[alt.sources] mkproto.c: patches for omitting formal parameter names

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!)