jtkohl@MIT.EDU (John T Kohl) (02/13/90)
Attached are diffs to the mkproto.c program which I picked up on one of these source groups a while back. The patch adds a new argument, -f, which will cause mkproto to not print formal parameter names in the generated prototypes. The patch also fixes problems with BSD-style STDIO buffering, and some problems with a C compiler which claims to be ANSI but isn't, and provides a man page (cobbled from the previous documentation). *** /tmp/,RCSt1a00620 Mon Feb 12 15:48:31 1990 --- mkproto.c Mon Feb 12 15:19:57 1990 *************** *** 3,8 **** --- 3,11 ---- /* Thanks are due to Jwahar R. Bammi for fixing several bugs */ /* and providing the Unix makefiles. */ + #ifdef __HIGHC__ + #undef __STDC__ + #endif #if defined(__STDC__) && !defined(minix) #include <stddef.h> #include <stdlib.h> *************** *** 9,15 **** #else #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 ! extern char *malloc(); #endif #include <stdio.h> --- 12,18 ---- #else #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 ! extern char *malloc(), *realloc(); #endif #include <stdio.h> *************** *** 31,36 **** --- 34,40 ---- int donum = 0; /* print line numbers? */ int dohead = 1; /* do file headers? */ int docond = 1; /* conditionalize for non-ANSI compilers? */ + int doformals= 1; /* print formal parameter names? */ int glastc = ' '; /* last char. seen by getsym() */ typedef struct word { *************** *** 355,360 **** --- 359,365 ---- static Word *pname[MAXPARAM]; /* parameter names */ Word *tlist, /* type name */ *plist; /* temporary */ + Word *ptemp, *ptemp2; /* temporary */ int np = 0; /* number of parameters */ int typed[MAXPARAM]; /* parameter has been given a type */ int tlistdone; /* finished finding the type name */ *************** *** 472,477 **** --- 477,503 ---- (!(pname[i]->next->next)&&strcmp(pname[i]->next->string, "void"))) { addword(tlist, "int"); } + + if (!doformals) { + /* conjecture: the last element of pname[i] is the formal + parameter name--usually true, except for things + like function pointers as args */ + for (ptemp = pname[i]->next; ptemp->next; + ptemp = ptemp->next) + ptemp2 = ptemp; + /* ptemp is now the last formal */ + if (ISCSYM(ptemp->string[0])) + ptemp->string[0] = '\0'; + else { + /* flag with XXX */ + ptemp = (Word *) realloc(ptemp, sizeof(Word) + + strlen(ptemp->string) + + 8); /* 9 for comment */ + ptemp2->next = ptemp; + (void) strcat(ptemp->string, "/*XXX*/"); + } + } + while (tlist->next) tlist = tlist->next; tlist->next = pname[i]; if (i < np - 1) *************** *** 603,608 **** --- 629,636 ---- donum = 1; else if (*t == 'p') docond = 0; + else if (*t == 'f') + doformals = 0; else Usage(); t++; *************** *** 625,632 **** --- 653,665 ---- perror(*argv); exit(EXIT_FAILURE); } + #ifdef BSD if (iobuf) + setbuffer(f, iobuf, NEWBUFSIZ); + #else + if (iobuf) setvbuf(f, iobuf, _IOFBF, NEWBUFSIZ); + #endif if (dohead) printf("\n/* %s */\n", *argv); linenum = 1; *************** *** 648,657 **** void Usage() { ! fputs("Usage: mkproto [-n][-s][-p][files ...]\n",stderr); fputs(" -n: put line numbers of declarations as comments\n",stderr); fputs(" -s: include declarations for static functions\n", stderr); ! fputs(" -p: don't make header files readable by non-ANSI compilers\n", ! stderr); exit(EXIT_FAILURE); } --- 681,690 ---- void Usage() { ! fputs("Usage: mkproto [-n][-s][-p][-f][files ...]\n",stderr); fputs(" -n: put line numbers of declarations as comments\n",stderr); fputs(" -s: include declarations for static functions\n", stderr); ! fputs(" -p: don't make header files readable by non-ANSI compilers\n", stderr); ! fputs(" -f: don't print formal paramter names\n", stderr); exit(EXIT_FAILURE); } *** /dev/null Mon Feb 12 13:04:07 1990 --- mkproto.1 Mon Feb 12 15:33:21 1990 *************** *** 0 **** --- 1,127 ---- + .TH MKPROTO 1 WATCHMAKER + .FM quote "MIT Project Athena" + .SH NAME + mkproto \- make prototypes for functions + .SH SYNOPSIS + .B /mit/watchmaker/${MACHTYPE}bin/mkproto + [ + .B \-n + ] [ + .B \-s + ] [ + .B \-p + ] [ + .B \-f + ] [ + .I file + .I \.\.\. + ] + .SH DESCRIPTION + .PP + .I Mkproto + takes as input one or more C source code files, and + produces as output (on the standard output stream) a list of function + prototypes (a la ANSI) for the external functions defined in the + given source files. This output, redirected to a file, is suitable + for \fC#include\fR'ing in a C source file. + .PP + The function definitions in the original source + may be either "old-style" (in which case appropriate prototypes are + generated for the functions) or "new-style" (in which the definition + includes a prototype already). + .PP + A + .B \-n + option causes the line number where each function was defined + to be prepended to the prototype declaration as a comment. + .PP + A + .B \-s + option causes prototypes to be generated for functions declard + "static" as well as extern functions. + .PP + A + .B \-p + option causes the prototypes emitted to be only readable by ANSI + compilers. Normally, the prototypes are "macro-ized" so that compilers + with \fC__STDC__\fR not defined don't see them. + .PP + A + .B \-f + option causes the prototypes emitted to omit the formal parameter names. + .PP + If files are specified on the command line, then a comment specifying + the file of origin is emitted before the prototypes constructed from + that file. If no files are given, then no comments are emitted and + the C source code is taken from the standard input stream. + .SH BUGS + .I Mkproto + is easily confused by complicated declarations, such as + .nf + .in +5 + \fCint ((*signal)())() { ...\fR + .in -5 + or + .in +5 + \fCstruct foo { int x, y; } foofunc() { ...\fR + .in -5 + .fi + .PP + Float types are not properly promoted in old style definitions, + i.e. + .nf + .in +5 + \fCint test(f) float f; { ...\fR + .in -5 + .fi + should (because of the default type conversion rules) have prototype + .nf + .in +5 + \fCint test(double f);\fR + .in -5 + .fi + rather than the incorrect + .nf + .in +5 + \fCint test(float f);\fR + .in -5 + .fi + generated by + .IR mkproto . + .PP + Some programs may need to be run through the preprocessor before + being run through + .IR mkproto . + The + .B \-n + option is unlikely to work as desired + on the output of a preprocessor. + .PP + Typedef'd types aren't correctly promoted, e.g. for + .nf + .in +5 + \fCtypedef schar char; int foo(x) schar x;...\fR + .in -5 + .fi + .I mkproto + incorrectly generates the prototype \fCint foo(schar x)\fR rather than + the (correct) \fCint foo(int x)\fR. + .PP + Functions named "inline" with no explicit type qualifiers are not + recognized. + .PP + Formal parameter names for complex types (anything where the semicolon + trailing the declaration does not immediately follow the parameter name) + are not discarded with + .BR \-f, + but these instances in the output are flagged with "/*XXX*/". + .SH SEE ALSO + cc(1), + lint(1) + .SH AUTHOR + Eric R. Smith. + .SH NOTE + There is no warranty for this program (as noted above, it's guaranteed + to break sometimes anyways!). + .I Mkproto + is in the public domain. -- John Kohl <jtkohl@ATHENA.MIT.EDU> or <jtkohl@Kolvir.Brookline.MA.US> Digital Equipment Corporation/Project Athena (The above opinions are MINE. Don't put my words in somebody else's mouth!)