Path: utzoo!attcan!uunet!lll-winken!ames!ncar!mailrus!ulowell!page From: page@swan.ulowell.edu (Bob Page) Newsgroups: comp.sources.amiga Subject: v89i001: exdoc - extract docs from C code Message-ID: <11171@swan.ulowell.edu> Date: 10 Jan 89 23:18:07 GMT Organization: University of Lowell, Computer Science Dept. Lines: 611 Approved: page@swan.ulowell.edu Submitted-by: oscvax!jan@uunet.UU.NET (Jan Sven Trabandt) Posting-number: Volume 89, Issue 1 Archive-name: langauges/exdoc.1 [uuencoded binary included. ..Bob] # This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # exdoc.c # exdoc.uu # This archive created: Tue Jan 10 18:15:17 1989 cat << \SHAR_EOF > exdoc.c /* * exdoc.c V1.0 (C)Copyright 1988, Jan Sven Trabandt. All Rights Reserved. * This software may not be distributed for profit; in other words, it is * freely redistributable except that it may not be incorporated as part of any * commercial software package without my express written consent. * Portions of this code are (C)Copyright 1988, Matthew Dillon. * * extract documentation that is in the canonical form from a [.c] file, * putting it to stdout. * it requires about 1K stack to run. * can someone tell me exactly why it isn't pure (1.3 pure bit/resident)??? * uucp: {utgpu,utzoo,lsuc}!oscvax!jan * * look at this comment as an example; * note that the start of the comment block has 2 characters followed by a '\n' * (the start-C-comment) * and the last line has 3 characters followed by a '\n' * (a space and the end-C-comment) * what comes inbetween these 2 lines can be in any form */ #include #include #ifdef MCH_AMIGA #include #include #include #endif MCH_AMIGA #ifndef MCH_AMIGA #ifndef NODATE #define NODATE #endif #endif !MCH_AMIGA #define VERSION "1.0" /* flags */ #define IN_COMMENT ((char)(1 << 0)) /* inside a "valid" comment */ #define REVERSE ((char)(1 << 1)) #define PRINTIT ((char)(1 << 7)) #define MAX_LINESIZE 514 /* flags for copystuff */ #define COPY_DATE ((char)(1 << 0)) #define COPY_COMM ((char)(1 << 1)) #define COPY_PROT ((char)(1 << 2)) #ifdef MCH_AMIGA typedef struct FileInfoBlock FIB; FIB *getFileInfo(); extern void *malloc(); #ifdef AZTEC_C #define strcpy _BUILTIN_strcpy #define strcmp _BUILTIN_strcmp #define strlen _BUILTIN_strlen #endif AZTEC_C #endif MCH_AMIGA help( argc, argv ) int argc; char **argv; { fprintf(stderr, "Usage: %s [infile] [-o outfile]" #ifndef NODATE " [-cdp]" #endif !NODATE " [-i] [-r] [-qh?]\n" " V%s ... file and flags can appear in any order:\n" " infile : input file (default: stdin)\n" " -o outfile : output file (default: stdout)\n" #ifndef NODATE " -c : copy file comment (must give in/out files)\n" " -d : copy datestamp (must give infile & outfile)\n" " -p : copy protection bits (must give in/out files)\n" #endif !NODATE " -i : ignore comment blocks\n" " -r : reverse (everything but comment blocks)\n" " in this case ignore# is how many to keep\n" " -q : quiet (suppress warning messages)\n" " -h, -? : help (this information)\n\n", argv[0], VERSION); exit( (int) 0 ); } /* help */ main( argc, argv ) int argc; char **argv; { FILE *fpin, *fpout; char *infname = NULL, *outfname = NULL; char *temp; register short i; short state = 0; char copystuff = 0, quiet = 0; char s[MAX_LINESIZE]; register char flags = 0; char dummy = '\0'; for( i = 1; i < argc; ++i ) { temp = argv[i]; if( *temp++ == '-' ) { /* parse flags */ while( *temp ) { switch( tolower(*temp++) ) { case 'i': /* this way allows while loop to stop properly */ if( !*temp ) { /* if "-i " */ state = atoi( argv[++i] ); /* use next arg */ } else { state = atoi( temp ); /* #comments to skip/keep */ temp = &dummy; } break; case 'r': flags |= REVERSE | PRINTIT; break; case 'o': /* this way allows while loop to stop properly */ if( !*temp ) { /* if "-o outfile" */ outfname = argv[++i]; /* use next arg */ } else { outfname = temp; /* outfile name */ temp = &dummy; } break; #ifndef NODATE case 'c': copystuff |= COPY_COMM; break; case 'd': copystuff |= COPY_DATE; break; case 'p': copystuff |= COPY_PROT; break; #endif !NODATE case 'q': quiet = 1; break; case 'h': case '?': help( argc, argv ); break; default: fprintf(stderr, "unknown flag '%c' ignored\n", *(temp - 1)); break; } /* switch */ } /* while */ } else { if( infname ) { /* error: too many filenames */ help( argc, argv ); } else { infname = argv[i]; } } } /* for */ #ifndef NODATE if( !infname || !outfname ) { /* need both i/o filenames to copy stuff */ copystuff = 0; } #endif !NODATE if( !infname ) { fpin = stdin; if( !outfname && !quiet ) { fprintf(stderr, "%s from stdin to stdout (c-\\ is EOF)\n", argv[0]); } } else { if( !(fpin = fopen(infname, "r")) ) { if( !quiet ) { fprintf(stderr, "Error, can't open file '%s' for input\n", infname); } exit( (int) 1000 ); } } if( !outfname ) { fpout = stdout; } else if( !(fpout = fopen(outfname, "w")) ) { if( !quiet ) { fprintf(stderr, "Error, can't open file '%s' for output\n", outfname); } exit( (int) 1000 ); } if( flags & REVERSE ) { state = -state; /* negative #ignore meanse #keep */ } /* print comment block if state is negative * state is initialized to the number of comment blocks to skip */ while( fgets(s, MAX_LINESIZE, fpin) ) { /* if start of valid comment (and not nested) */ if( !strcmp(s, "/*\n") && !(flags & IN_COMMENT) ) { flags |= IN_COMMENT; if( !(flags & REVERSE) ) { /* if not reverse, ie. state is #skip */ --state; /* one less to skip */ } if( state < 0 ) { flags |= PRINTIT; } else { flags &= ~PRINTIT; } /* if end of valid comment (and we had start of comment) */ } else if( !strcmp(s, " */\n") && (flags & IN_COMMENT) ) { if( state < 0 ) { ++state; } if( flags & PRINTIT ) { fprintf(fpout, "%s\n", s); } if( flags & REVERSE ) { flags |= PRINTIT; } else { flags &= ~PRINTIT; } flags &= ~IN_COMMENT; continue; } if( flags & PRINTIT ) { fprintf(fpout, "%s", s); } } /* while */ if( fpout != stdout ) { fclose( fpout ); } #ifndef NODATE if( copystuff ) { /* need to copy file datestamp/comm/prot */ FIB *fib; long lock; if( !(fib = getFileInfo(infname, &lock)) ) { if( !quiet ) { fprintf(stderr, "couldn't get file info for input file '%s'\n", infname); } } else { if( copystuff & COPY_DATE ) { setfiledate( outfname, &fib->fib_Date ); } if( copystuff & COPY_PROT ) { SetProtection( outfname, fib->fib_Protection ); } if( copystuff & COPY_COMM ) { SetComment( outfname, fib->fib_Comment ); } freeFileInfo( fib, lock ); } } #endif !NODATE if( fpin != stdin ) { fclose( fpin ); } } /* main */ #ifdef MCH_AMIGA #ifndef NODATE /* The following routines (C)Copyright 1988, Matt Dillon, * from his backup program and support library (sup32.lib). * Permission was granted to use them in this program. */ FIB * getFileInfo(path, plock) char *path; long *plock; { register long lock; register FIB *fib; *plock = NULL; if (lock = (long) Lock(path, SHARED_LOCK)) { if (fib = malloc(sizeof(FIB))) { /* longword align FIB */ if (Examine(lock, fib)) { *plock = lock; return(fib); } free(fib); } UnLock(lock); } return(NULL); } freeFileInfo(fib, lock) FIB *fib; long lock; { if (fib) free(fib); if (lock) UnLock(lock); } /* * SETFILEDATE.C * * BOOL = setfiledate(filename, date) */ #define BTOC(bptr) ((long)(bptr) << 2) #define CTOB(cptr) ((long)(cptr) >> 2) #ifndef ACTION_SET_DATE #define ACTION_SET_DATE 34 #endif typedef struct Task TASK; typedef struct Process PROC; typedef struct StandardPacket STDPKT; typedef struct MsgPort MSGPORT; typedef struct FileLock LOCK; typedef struct DateStamp DATESTAMP; extern TASK *FindTask(); extern void *AllocMem(); setfiledate(file, date) char *file; DATESTAMP *date; { register STDPKT *packet; register char *buf; register PROC *proc; long result; long lock; { register long flock = (long) Lock(file, SHARED_LOCK); register short i; register char *ptr = file; if (flock == NULL) return(NULL); lock = (long) ParentDir(flock); UnLock(flock); if (!lock) return(NULL); for (i = strlen(ptr) - 1; i >= 0; --i) { if (ptr[i] == '/' || ptr[i] == ':') break; } file += i + 1; } proc = (PROC *)FindTask(NULL); packet = (STDPKT *)AllocMem((long)sizeof(STDPKT), MEMF_CLEAR|MEMF_PUBLIC); buf = AllocMem((long)strlen(file)+2, MEMF_PUBLIC); strcpy(buf+1,file); buf[0] = strlen(file); packet->sp_Msg.mn_Node.ln_Name = (char *)&(packet->sp_Pkt); packet->sp_Pkt.dp_Link = &packet->sp_Msg; packet->sp_Pkt.dp_Port = &proc->pr_MsgPort; packet->sp_Pkt.dp_Type = ACTION_SET_DATE; packet->sp_Pkt.dp_Arg1 = NULL; packet->sp_Pkt.dp_Arg2 = (long)lock; /* lock on parent dir of file */ packet->sp_Pkt.dp_Arg3 = (long)CTOB(buf); /* BPTR to BSTR of file name */ packet->sp_Pkt.dp_Arg4 = (long)date; /* APTR to datestamp structure */ PutMsg(((LOCK *)BTOC(lock))->fl_Task, packet); WaitPort(&proc->pr_MsgPort); GetMsg(&proc->pr_MsgPort); result = packet->sp_Pkt.dp_Res1; FreeMem(packet, (long)sizeof(STDPKT)); FreeMem(buf, (long)strlen(file)+2); UnLock(lock); return(result); } #endif !NODATE #endif MCH_AMIGA SHAR_EOF cat << \SHAR_EOF > exdoc.uu begin 600 exdoc M```#\P`````````#``````````(```?2````N`````$```/I```'TD[Z#FI.@ M50``2'H"LR!M``HO$$AZ`!I(;(#X3KH,.$_O`!!"9TZZ&]I43TY=3G5571H:6YG(&)U="!C;VUM96YT(&)L;V-K@!"+?WE>`%@``%J,`1(P.6`(&T`"BMP"`#_["!M_^Q2K?_L. M#!``+68``2(@;?_L2A!G``$6(&W_[%*M_^P0$$B`/P!.N@;T5$](P&```,0@< M;?_L2A!F'%)$,`1(P.6`(&T`"B\P"`!.N@9&6$\[0/_J8!8O+?_L3KH&-EA/P M.T#_ZD'M_>4K2/_L8```NHH\`()@``"R(&W_[$H09A121#`$2,#E@"!M``HK+ M<`@`__!@#BMM_^S_\$'M_>4K2/_L8```A`CM``'_Z6!Z".T``/_I8'(([0`"W M_^E@:AM\``'_Z&!B+RT`"C\M``A.NOPX7$]@4B!M_^P0*/__2(`_`$AZ`M!(W M;(#X3KH(;$_O``I@-)"\````/V?*D+P````D9Z)3@&>F68!GNE.`9P#_(EV`# M9P#_8E.`9YI3@&>>4X!G`/],8*Y@`/[D8"9*K?_T9Q`O+0`*/RT`"$ZZ^\IR`S"M(__Q*K?_P9AQ*+?_H9A8@;0`*+Q!(>@(_2&R`^$ZZ!\!/( M[P`,8#)(>@)3+RW_]$ZZ!PQ03RM`__QF'B\M__1(>@(]2&R`^$ZZ!Y9/[P`," M/SP#Z$ZZ%S943TJM__!F"D'L@.(K2/_X8#)(>@(Z+RW_\$ZZ!LI03RM`__AF' M'B\M__!(>@(D2&R`^$ZZ!U1/[P`,/SP#Z$ZZ%O143P@%``%G!$1M_^HO+?_\O M/SP"`DAM_>9.N@4(3^\`"DJ`9P``O$'M_>9#^@(*$!BP&68$2@!F]I`A2(!F; M)@@%``!F(`C%```(!0`!9@13;?_J2FW_ZFP&BCP`@&`$RCP`?V!<0>W]YD/ZR M`=`0&+`99@1*`&;VD"%(@&9$"`4``&<^2FW_ZFP$4FW_ZA`%P#P`@&<42&W]= MYDAZ`:4O+?_X3KH&I$_O``P(!0`!9P:*/`"`8`3*/`!_"(4``&``_TX0!<`\2 M`(!G%$AM_>9(>@%U+RW_^$ZZ!G!/[P`,8`#_+D'L@.(B;?_XL\AG"B\M__A.5 MNA'>6$]*+?_I9P``B$AM_=PO+?_T3KH!:E!/*T#]X&86+RW_]$AZ`2Y(;(#X] M3KH&)D_O``Q@7`@M``#_Z6<2(&W]X$AH`(0O+?_P3KH!OE!/""T``O_I9Q(@7 M;?W@+R@`="\M__!.NA?04$\(+0`!_^EG$B!M_>!(:`"0+RW_\$ZZ%ZA03R\M\ M_=PO+?W@3KH!5%!/0>R`S")M__RSR&<*+RW__$ZZ$3I83TS?`#!.74YU=6YKE M;F]W;B!F;&%G("0`!``%(>`!$3KH5[%!/3 M)$!(>``!(&T`""`(2AAF_)'`4X@P"$C`5(`O`$ZZ%`!$' M+PI.NA5:4$\@;0`((`A*&&;\D@`,$@`MS M9@9Z`5**8`@,$@`K9@)2BG@`8!8@2E**$!!(@#($POP`"M!!.`"8?``P$!)() M@%)`0>R`2@@P``(``&;82D5G!C`$1$!@`C`$3-\$,$Y=3G5P`!`O``6P/`!@8 M8PJP/`!Z8@20/``@3G5P`!`O``6P/`!`8PJP/`!:8@30/``@3G5.50``2.<(J M("1M``A3;0`,2FT`#&\@+RT`#DZZ`#@X`+!\__]83V<.($I2BA"$N'P`"F<"` M8-9"$KA\__]F$+7M``AF"G``3-\$$$Y=3G4@+0`(8/).50``2.<(("1M``@O2 M"DZZ`#(X`+!\__]83VR"A+?(9=8_*@`0+RH`"!`J``U(@#\`Y M3KH"=C@`2D!03VX42D1F!'`(8`)P$($J``QP_V``_WHP!$C`)*H`"-"J``@EM M0``$(%)2DA`02(#`?`#_8`#_6DY5```O"DZZ#8HD0$J`9@AP`"1?3EU.=2\*G M+RT`#"\M``AA!D_O``Q@Z$Y5``!(YP@@+RT`$$ZZ"_1![(`")$A83TH29A`Y_ M?``%@I9P`$S?!!!.74YU($HB;0`,$!BP&68$2@!F]I`A2(!G!%R*8-(_*@`$E M+RT`"$ZZ`'@X`+!\__]<3V8$<`!@Q"!M`!`11``-(&T`$!%\``$`#"`M`!!@B MK$Y5```I;0`(@HY(;0`0+RT`#$AZ``Y.N@<(3^\`#$Y=3G5.50``+RR"CC\M# M``A.N@JT7$].74YU3E4``#\M``P_/`,!+RT`"&$&4$].74YU3E4``$CG#S`D. M;0`(3KH.]"9L@IAX`&`.,`3!_``&2K,(`&<.4D2X;(*$;>QZ!F```,0(+0`!U M``QG,$AX__\O"DZZ$/8L`%!/9R`O!DZZ$58O"DZZ$*9*@%!/9@Y.NA#".@"PV M?`#-9@``C$AX`^TO"DZZ$-0L`$J&4$]F8`@M````#&8$>@%@;$AX`^XO"DZZ5 M$+8L`%!/9@A.NA"&.@!@5$AX`"%(>@"23KH1BBX`4$]G"B\'3KH1)%A/8!Y(! M>``!2'H`@B\&3KH0Z$AX__]"IR\&3KH0HD_O`!A@)C`M``S`?`4`L'P%`&88] M+P9.N@_T>@183SE%@I9P_TS?#/!.74YU,`3!_``&)X8(`#`$P?P`!B!`TR"CK7)9@XR/``4:PAT`"+"4``$*4Z"H$CG@(`(+@`$1 M`2EG$$OZ``A.KO_B8`9"I_-?3G-#^@`@3J[^:"E`@J1F#"X\``.`!TZN_Y1@0 M!$ZZ`!I03TYU9&]S+FQI8G)A0`!```P+(*$S MP?P`!B\`3KH/D"E`@IA03V840J=(>0`!``!.N@]04$\N;(*<3G4@;(*80F@`Q M!"!L@I@Q?``!`!`@;(*8,7P``0`*(&R"G"`L@IR0J``$4(`I0(*H(&R"J""\+ M34%.6$*G3KH/2"1`2JH`K%A/9RXO+0`,+RT`""\*3KH`KCE\``&"K"!L@I@`! M:(````0@;(*8`&B````*3^\`#&!"2&H`7$ZZ#WQ(:@!<3KH/+"E`@JX@;(*NW M2J@`)%!/9Q`@;(*N(F@`)"\13KH-U%A/+RR"KB\*3KH":"EL@JZ"LE!/3KH-) MYB!L@I@@@$ZZ#A@@;(*8(4``!F<62'@#[4AZ`"I.N@WT(&R"F"%```Q03R\L6 M@K(_+(*V3KKRMD)G3KH+[E!/)%].74YU*@!.50``2.<,,"1M`!`@;0`(2J@`A MK&<8(&T`""`H`*SE@"@`($0@*``0Y8`F0&`$)FR"AA`32(!(P-"M``Q4@#E`/ M@KA"IS`L@KA(P"\`3KH.(BE`@KI03V8(3-\,,$Y=3G40$TB`.@`_!2!+4H@O, M""\L@KI.N@%^,`5(P"!`T>R"ND/Z`400V6;\/RT`#B\*+RR"NDZZ`3H@;(*Z> M0C!0`#E\``&"MC`%2,#0K(*Z)D!2BR1+3^\`%!`32(`Z`+!\`"!G&+I\``EG_ M$KI\``QG#+I\``UG!KI\``IF!%*+8-@,$P`@;7H,$P`B9BY2BR!+4HL0$$B`^ M.@!G'B!*4HH0A;I\`")F$`P3`")F!%*+8`9"*O__8`)@UF`X($M2BQ`02(`Z: M`&@".3KH,DBE`@KY0P M3V8(3-\,<$Y=3G4@;0`,(F@`)"\I``1.N@S4*`!83V=22'H`;2!$+R@`-DZZ- M#*8F0$J`4$]G-$AX`^TO"TZZ"UXL`%!/9R0@!N6`*@`@125H``@`I"5&`)Q(O M>`/M2'H`.$ZZ"SHE0`"@4$\O!$ZZ#')83R\L@KY.N@NT0JR"OEA/8(!I8V]NS M+FQI8G)A M9M2X?``N9EH@2U*+$!!(@#@`L'P`*F88(&W__%2M__P[4/_T($M2BQ`02(`X" M`&`R0FW_]&`<,"W_],'\``K01)!\`#`[0/_T($M2BQ`02(`X`#`$4D!![(!*J M"#```@``9M0[?``"__"X?`!L9A(@2U*+$!!(@#@`.WP`!/_P8!"X?`!H9@H@B M2U*+$!!(@#@`,`1(P&!Z.WP`"/_N8!8[?``*_^Y@#CM\`!#_[F`&.WS_]O_N/ M/RW_\$AM_S`_+?_N+RW__$ZZ_>0K0/_J,"W_\$C`T:W__$_O``Q@7"!M__Q8? MK?_\(E`K2?_J(`E*&6;\D\!3B3M)__!@2B!M__Q4K?_\.!!![?\O*TC_ZA"$) M8"B0O````&-GXE.`9Y*0O`````MG`/]R68!GLE6`9P#_<%>`9P#_W_@ M,)'M_^H[2/_P,"W_\+!M__1O!CMM__3_\$IM__AG:"!M_^H,$``M9PH@;?_J' M#!``*V8N#&T`,/_V9B93;?_R(&W_ZE*M_^H0$$B`/P!.DK!\__]43V8*``@G M"F8*H`"#@(/P0O*@`($"H`] M#4B`/P!.N@*`L$103V<0".H`!``,0I)"J@`$ M(&R"F"\P"`!.N@+82H!83V<$<`%@`G``8-A.50``+RT`"$ZZ`I!*@%A/9@Y.: MN@*L.4""EG#_3EU.=7``8/A.50``2.<,(#@M``A.N@!P,`3!_``&)$#5[(*8W M2D1M"KAL@H1L!$J29A`Y?``"@I9P_TS?!#!.74YU,"H`!,!\``-F"CE\``6"% MEG#_8.1P`#`M``XO`"\M``HO$DZZ`LXJ`+"\_____T_O``QF#$ZZ`BPY0(*6G M`!@"C\$3KH`_E1/4D2X;(*$;?`P+(*$P?P`!B\`! M+RR"F$ZZ`F!03TJL@L9G!B!L@L9.D$JL@HIG"B\L@HI.N@'06$]*K(+*9P@@& M;(+*(*R"SDJL@M)G"B\L@M).N@'L6$]*K(+69PHO+(+63KH!W%A/2JR"VF<*; M+RR"VDZZ```$""X`!`$I9Q0O#4OZ``I.! MKO_B*E]@!D*G\U].R"F$I$;0JX;(*$;`1*DF80^ M.7P``H*6