v17i008: mkptypes - Generate prototype declarations for C, Patch01

Eric R. Smith ersmith at uwovax.uwo.ca
Wed Feb 20 15:30:27 AEST 1991


Submitted-by: Eric R. Smith <ersmith at uwovax.uwo.ca>
Posting-number: Volume 17, Issue 8
Archive-name: mkptypes/patch01
Patch-To: mkptypes: Volume 16, Issue 90

Here is patch 1 for mkptypes. The biggest bug fixed is the bad default
choice of guard macro; "_P" is in the reserved namespace of both ANSI C
and POSIX, and conflicts with the ctypes.h header file in some versions of
Unix. The default is now "P_". I also took the opportunity to add some
suggested enhancements, e.g. making the parser a bit smarter, recognizing
C++ style comments, and providing some new flags to print version
information and to suppress the promotion of types (so C++ compilers that
accept "int foo(c) char c;" and expect it to have prototype "int foo(char c)"
will be happy).

Thanks to all the people who have reported bugs and suggested improvements.

Eric R. Smith                     email:
Dept. of Mathematics            ersmith at uwovax.uwo.ca
University of Western Ontario   ersmith at uwovax.bitnet
----
#	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:
#	patch1
# This archive created: 17 February 1991 12:31:28 AM EST
# By:	eric (at home)
echo shar: extracting patch1
sed 's/^X//' << \SHAR_EOF > patch1
X*** mkptypes/orig/Makefile	Mon Mar 26 12:12:20 1990
X--- mkptypes/Makefile	Sun Feb 17 00:19:32 1991
X***************
X*** 2,8 ****
X  # Makefile for mkptypes. Edit the lines below to suit your tastes; the default
X  # is for my computer (Atari ST running the gcc 1.37); a Unix configuration is
X  # also provided.
X! 
X  #CC = cc
X  #PROG = mkptypes
X  #CFLAGS = -O
X--- 2,8 ----
X  # Makefile for mkptypes. Edit the lines below to suit your tastes; the default
X  # is for my computer (Atari ST running the gcc 1.37); a Unix configuration is
X  # also provided.
X! #
X  #CC = cc
X  #PROG = mkptypes
X  #CFLAGS = -O
X***************
X*** 9,18 ****
X  
X  CC = gcc
X  PROG = mkptypes.ttp
X! CFLAGS = -mshort -O
X  
X! $(PROG) : mkptypes.c mkptypes.h
X  	$(CC) $(CFLAGS) -o $(PROG) mkptypes.c
X  
X  clean:
X  	rm -f mkptypes.o
X--- 9,28 ----
X  
X  CC = gcc
X  PROG = mkptypes.ttp
X! CFLAGS = -mshort -O -Wall
X  
X! $(PROG) : mkptypes.c mkptypes.h patchlev.h
X  	$(CC) $(CFLAGS) -o $(PROG) mkptypes.c
X+ 
X+ all: $(PROG)
X+ 
X+ #
X+ # edit the lines below if you want to be able to 'make install'
X+ #
X+ #DESTDIR = /usr/local/bin
X+ #install: $(PROG)
X+ #	install -c -o bin -g bin -m 755 $(PROG) $(DESTDIR)/$(PROG)
X+ #
X  
X  clean:
X  	rm -f mkptypes.o
X*** mkptypes/orig/mkptypes.1	Mon Jan 21 12:16:40 1991
X--- mkptypes/mkptypes.1	Sun Feb 17 00:05:58 1991
X***************
X*** 19,24 ****
X--- 19,28 ----
X  ] [
X  .B -A
X  ] [
X+ .B -V
X+ ] [
X+ .B -W
X+ ] [
X  .I file ...
X  ]
X  .SH DESCRIPTION
X***************
X*** 41,47 ****
X  to be prepended to the prototype declaration as a comment.
X  .PP
X  The -p option controls the name of the macro used to guard prototype
X! definitions. Normally this is ``_P'', but you can change it to any string
X  you like. To eliminate the guard macro entirely, use the -A option.
X  .PP
X  The -s option causes prototypes to be generated for functions declared
X--- 45,51 ----
X  to be prepended to the prototype declaration as a comment.
X  .PP
X  The -p option controls the name of the macro used to guard prototype
X! definitions. Normally this is ``P_'', but you can change it to any string
X  you like. To eliminate the guard macro entirely, use the -A option.
X  .PP
X  The -s option causes prototypes to be generated for functions declared
X***************
X*** 63,68 ****
X--- 67,79 ----
X  The -A option causes the prototypes emitted to be only readable by ANSI
X  compilers. Normally, the prototypes are "macro-ized" so that compilers
X  with __STDC__ not defined don't see them.
X+ .PP
X+ The -V option prints the version number and patchlevel of mkptypes on the
X+ standard error output.
X+ .PP
X+ The -W option supresses the default widening of types in old-style
X+ declarations (e.g. char -> int); use this for C++ compilers or
X+ for supposedly ANSI compilers that don't do type promotion.
X  .PP
X  If files are specified on the command line, then a comment specifying
X  the file of origin is emitted before the prototypes constructed from
X*** mkptypes/orig/mkptypes.c	Mon Mar 26 12:35:06 1990
X--- mkptypes/mkptypes.c	Sun Feb 17 00:21:50 1991
X***************
X*** 30,37 ****
X  #include <ctype.h>
X  #include <string.h>
X  
X! /*#define DEBUG(s) (fputs(s, stderr)) /* */
X! #define DEBUG(s) /* */
X  
X  #define ISCSYM(x) ((x) > 0 && (isalnum(x) || (x) == '_'))
X  #define ABORTED ( (Word *) -1 )
X--- 30,40 ----
X  #include <ctype.h>
X  #include <string.h>
X  
X! #if 0
X! #define DEBUG(s) (fputs(s, stderr))
X! #else
X! #define DEBUG(s)
X! #endif
X  
X  #define ISCSYM(x) ((x) > 0 && (isalnum(x) || (x) == '_'))
X  #define ABORTED ( (Word *) -1 )
X***************
X*** 42,53 ****
X  int donum    = 0;		/* print line numbers? */
X  int define_macro   = 1;		/* define macro for prototypes? */
X  int use_macro   = 1;		/* use a macro for prototypes? */
X! char *macro_name = "_P";	/*   macro to use for prototypes */
X  int no_parm_names = 0;		/* no parm names - only types */
X  int print_extern = 0;		/* use "extern" before function declarations */
X! #ifdef CPP
X! int call_cpp = 0;		/* preprocess files */
X! #endif
X  
X  char *ourname;			/* our name, from argv[] array */
X  int inquote = 0;		/* in a quote?? */
X--- 45,54 ----
X  int donum    = 0;		/* print line numbers? */
X  int define_macro   = 1;		/* define macro for prototypes? */
X  int use_macro   = 1;		/* use a macro for prototypes? */
X! char *macro_name = "P_";	/*   macro to use for prototypes */
X  int no_parm_names = 0;		/* no parm names - only types */
X  int print_extern = 0;		/* use "extern" before function declarations */
X! int dont_promote = 0;		/* don't promote prototypes */
X  
X  char *ourname;			/* our name, from argv[] array */
X  int inquote = 0;		/* in a quote?? */
X***************
X*** 164,169 ****
X--- 165,173 ----
X  {
X  	Word *oldw = 0;
X  
X+ 	if (dont_promote)
X+ 		return;
X+ 
X  	while (w) {
X  		if (*w->string) {
X  			if ( (!strcmp(w->string, "char") ||
X***************
X*** 190,196 ****
X  
X  /* read a character: if it's a newline, increment the line count */
X  
X! #ifdef __GNUC__	/* ++jrb */
X  inline
X  #endif
X  int ngetc(f)
X--- 194,200 ----
X  
X  /* read a character: if it's a newline, increment the line count */
X  
X! #if defined(__GNUC__) && !defined(__NO_INLINE__)	/* ++jrb */
X  inline
X  #endif
X  int ngetc(f)
X***************
X*** 236,241 ****
X--- 240,259 ----
X  			}
X  			return fnextch(f);
X  		}
X+ 		else if (c == '/') {	/* C++ style comment */
X+ 			incomment = 1;
X+ 			c = ' ';
X+ DEBUG("fnextch: C++ comment seen\n");
X+ 			while (incomment) {
X+ 				lastc = c;
X+ 				c = ngetc(f);
X+ 				if (lastc != '\\' && c == '\n')
X+ 					incomment = 0;
X+ 				else if (c < 0)
X+ 					return c;
X+ 			}
X+ 			return fnextch(f);
X+ 		}
X  		else {
X  /* if we pre-fetched a linefeed, remember to adjust the line number */
X  			if (c == '\n') linenum--;
X***************
X*** 557,566 ****
X  		else if (!strcmp(buf, "{}")) break;
X  /* otherwise, throw the word into the list (except for "register") */
X  		else if (strcmp(buf, "register")) {
X- 			sawsomething = 1;
X  			addword(plist, buf);
X  			if (*buf == '(') inparen++;
X! 			if (*buf == ')') inparen--;
X  		}
X  	}
X  
X--- 575,584 ----
X  		else if (!strcmp(buf, "{}")) break;
X  /* otherwise, throw the word into the list (except for "register") */
X  		else if (strcmp(buf, "register")) {
X  			addword(plist, buf);
X  			if (*buf == '(') inparen++;
X! 			else if (*buf == ')') inparen--;
X! 			else sawsomething = 1;
X  		}
X  	}
X  
X***************
X*** 682,688 ****
X  /* try to guess when a declaration is not an external function definition */
X  		if (!strcmp(buf, ",") || !strcmp(buf, "{}") ||
X  		    !strcmp(buf, "=") || !strcmp(buf, "typedef") ||
X! 		    !strcmp(buf, "extern")) {
X  			skipit(buf, f);
X  			goto again;
X  		}
X--- 700,706 ----
X  /* try to guess when a declaration is not an external function definition */
X  		if (!strcmp(buf, ",") || !strcmp(buf, "{}") ||
X  		    !strcmp(buf, "=") || !strcmp(buf, "typedef") ||
X! 		    !strcmp(buf, "[") || !strcmp(buf, "extern")) {
X  			skipit(buf, f);
X  			goto again;
X  		}
X***************
X*** 721,738 ****
X  {
X  	FILE *f;
X  	char *t, *iobuf;
X  	extern void Usage();
X  
X! 	if (argv[0] && argv[0][0])
X  		ourname = argv[0];
X  	else
X  		ourname = "mkptypes";
X  
X  	argv++; argc--;
X  
X- 	if (argc < 0)		/* strange -- no args at all */
X- 		Usage();
X- 
X  	iobuf = malloc(NEWBUFSIZ);
X  	while (*argv && **argv == '-') {
X  		t = *argv++; --argc; t++;
X--- 739,763 ----
X  {
X  	FILE *f;
X  	char *t, *iobuf;
X+ 	int exit_if_noargs = 0;
X  	extern void Usage();
X  
X! 	if (argv[0] && argv[0][0]) {
X! #ifdef unix
X! 		ourname = strrchr(argv[0], '/');
X! 		if (!ourname)
X! #endif
X! #ifdef atarist
X! 		ourname = strrchr(argv[0], '\\');
X! 		if (!ourname)
X! #endif
X  		ourname = argv[0];
X+ 	}
X  	else
X  		ourname = "mkptypes";
X  
X  	argv++; argc--;
X  
X  	iobuf = malloc(NEWBUFSIZ);
X  	while (*argv && **argv == '-') {
X  		t = *argv++; --argc; t++;
X***************
X*** 758,763 ****
X--- 783,794 ----
X  				define_macro = 0;
X  			else if (*t == 'A')
X  				use_macro = 0;
X+ 			else if (*t == 'V') {
X+ 				exit_if_noargs = 1;
X+ 				Version();
X+ 			}
X+ 			else if (*t == 'W')
X+ 				dont_promote = 1;
X  			else
X  				Usage();
X  			t++;
X***************
X*** 764,769 ****
X--- 795,803 ----
X  		}
X  	}
X  
X+ 	if (argc == 0 && exit_if_noargs)
X+ 		exit(EXIT_FAILURE);
X+ 
X  	if (use_macro && define_macro) {
X  		printf("#if defined(__STDC__) || defined(__cplusplus)\n");
X  		printf("# define %s(s) s\n", macro_name);
X***************
X*** 771,778 ****
X  		printf("# define %s(s) ()\n", macro_name);
X  		printf("#endif\n\n");
X  	}
X! 	if (argc == 0)
X  		getdecl(stdin);
X  	else
X  		while (argc > 0 && *argv) {
X  DEBUG("trying a new file\n");
X--- 805,814 ----
X  		printf("# define %s(s) ()\n", macro_name);
X  		printf("#endif\n\n");
X  	}
X! 
X! 	if (argc == 0) {
X  		getdecl(stdin);
X+ 	}
X  	else
X  		while (argc > 0 && *argv) {
X  DEBUG("trying a new file\n");
X***************
X*** 804,814 ****
X  void Usage()
X  {
X  	fprintf(stderr, 
X! 	   "Usage: %s [-e][-n][-p sym][-s][-x][-z][-A][files ...]\n", ourname);
X  	fputs("   -e: put an explicit \"extern\" keyword in declarations\n",
X  	   stderr);
X  	fputs("   -n: put line numbers of declarations as comments\n",stderr);
X! 	fputs("   -p nm: use \"nm\" as the prototype macro (default \"_P\")\n",
X  	   stderr);
X  	fputs("   -s: include declarations for static functions\n", stderr);
X  	fputs("   -x: omit parameter names in prototypes\n", stderr);
X--- 840,850 ----
X  void Usage()
X  {
X  	fprintf(stderr, 
X! 	   "Usage: %s [-e][-n][-p sym][-s][-x][-z][-A][-W][files ...]\n", ourname);
X  	fputs("   -e: put an explicit \"extern\" keyword in declarations\n",
X  	   stderr);
X  	fputs("   -n: put line numbers of declarations as comments\n",stderr);
X! 	fputs("   -p nm: use \"nm\" as the prototype macro (default \"P_\")\n",
X  	   stderr);
X  	fputs("   -s: include declarations for static functions\n", stderr);
X  	fputs("   -x: omit parameter names in prototypes\n", stderr);
X***************
X*** 815,819 ****
X--- 851,865 ----
X  	fputs("   -z: omit prototype macro definition\n", stderr);
X  	fputs("   -A: omit prototype macro; header files are strict ANSI\n",
X  	   stderr);
X+ 	fputs("   -V: print version number\n", stderr);
X+ 	fputs("   -W: don't promote types in old style declarations\n", stderr);
X  	exit(EXIT_FAILURE);
X+ }
X+ 
X+ #include "patchlev.h"
X+ 
X+ void
X+ Version()
X+ {
X+ 	fprintf(stderr, "%s 1.0 patchlevel %d\n", ourname, PATCHLEVEL);
X  }
X*** mkptypes/orig/mkptypes.h	Thu Mar 22 08:14:40 1990
X--- mkptypes/mkptypes.h	Sun Feb 17 00:08:30 1991
X***************
X*** 1,29 ****
X  #if defined(__STDC__) || defined(__cplusplus)
X! # define _P(s) s
X  #else
X! # define _P(s) ()
X  #endif
X  
X  
X  /* mkptypes.c */
X! Word *word_alloc _P((char *s));
X! void word_free _P((Word *w));
X! int List_len _P((Word *w));
X! Word *word_append _P((Word *w1, Word *w2));
X! int foundin _P((Word *w1, Word *w2));
X! void addword _P((Word *w, char *s));
X! void typefixhack _P((Word *w));
X! int ngetc _P((FILE *f));
X! int fnextch _P((FILE *f));
X! int nextch _P((FILE *f));
X! int getsym _P((char *buf, FILE *f));
X! int skipit _P((char *buf, FILE *f));
X! int is_type_word _P((char *s));
X! Word *typelist _P((Word *p));
X! Word *getparamlist _P((FILE *f));
X! void emit _P((Word *wlist, Word *plist, long startline));
X! void getdecl _P((FILE *f));
X! void main _P((int argc, char **argv));
X! void Usage _P((void));
X  
X! #undef _P
X--- 1,30 ----
X  #if defined(__STDC__) || defined(__cplusplus)
X! # define P_(s) s
X  #else
X! # define P_(s) ()
X  #endif
X  
X  
X  /* mkptypes.c */
X! Word *word_alloc P_((char *s));
X! void word_free P_((Word *w));
X! int List_len P_((Word *w));
X! Word *word_append P_((Word *w1, Word *w2));
X! int foundin P_((Word *w1, Word *w2));
X! void addword P_((Word *w, char *s));
X! void typefixhack P_((Word *w));
X! int ngetc P_((FILE *f));
X! int fnextch P_((FILE *f));
X! int nextch P_((FILE *f));
X! int getsym P_((char *buf, FILE *f));
X! int skipit P_((char *buf, FILE *f));
X! int is_type_word P_((char *s));
X! Word *typelist P_((Word *p));
X! Word *getparamlist P_((FILE *f));
X! void emit P_((Word *wlist, Word *plist, long startline));
X! void getdecl P_((FILE *f));
X! void main P_((int argc, char **argv));
X! void Usage P_((void));
X! void Version P_((void));
X  
X! #undef P_
X*** mkptypes/orig/mkptypes.man	Mon Jan 21 12:16:38 1991
X--- mkptypes/mkptypes.man	Sun Feb 17 00:05:40 1991
X***************
X*** 3,9 ****
X  
X  
X  SYNOPSIS
X!     mkptypes [ -e ][ -n ][ -p symbol ][ -s ][ -x ][ -z ][ -A ] [ file ... ]
X  
X  
X  DESCRIPTION
X--- 3,9 ----
X  
X  
X  SYNOPSIS
X!     mkptypes [-e][-n][-p symbol][-s][-x][-z][-A][-V][-W][ file ... ]
X  
X  
X  DESCRIPTION
X***************
X*** 22,28 ****
X      be prepended to the prototype declaration as a comment.
X  
X      The -p option controls the name of the macro used to guard prototype
X!     definitions. Normally this is "_P", but you can change it to any string you
X      like. To eliminate the guard macro entirely, use the -A option.
X  
X      The -s option causes prototypes to be generated for functions declared
X--- 22,28 ----
X      be prepended to the prototype declaration as a comment.
X  
X      The -p option controls the name of the macro used to guard prototype
X!     definitions. Normally this is "P_", but you can change it to any string you
X      like. To eliminate the guard macro entirely, use the -A option.
X  
X      The -s option causes prototypes to be generated for functions declared
X***************
X*** 42,47 ****
X--- 42,54 ----
X      The -A option causes the prototypes emitted to be only readable by ANSI
X      compilers.  Normally, the prototypes are "macro-ized" so that compilers
X      with __STDC__not defined don't see them.
X+ 
X+     The -V option prints the version number and patchlevel of mkptypes on
X+     the standard error output.
X+ 
X+     The -W option supresses the default widening of types in old-style
X+     declarations (e.g. char -> int); use this for C++ compilers or
X+     for supposedly ANSI compilers that don't do type promotion.
X  
X      If files are specified on the command line, then a comment specifying the
X      file of origin is emitted before the prototypes constructed from that file.
X*** mkptypes/orig/patchlev.h	Sat Feb 16 01:14:02 1991
X--- mkptypes/patchlev.h	Sun Feb 17 00:00:38 1991
X***************
X*** 0 ****
X--- 1,16 ----
X+ /*
X+  * Patchlevel 1: Feb. 16, 1991
X+  * changed "_P" in prototype header files to "P_" to avoid namespace conflicts
X+  * with POSIX, ANSI, and some Unix header files
X+  *
X+  * added support C++ style comments (// to end of line)
X+  * 
X+  * new option (-W) to suppress promotion of prototypes in old style declarations
X+  *
X+  * miscellaneous bugfixes to improve probablility of parsing complicated
X+  * declarations
X+  *
X+  * added "install" option to makefile (thanks to Blayne Puklich)
X+  */
X+ 
X+ #define PATCHLEVEL 1
SHAR_EOF
if test 14624 -ne "`wc -c patch1`"
then
echo shar: error transmitting patch1 '(should have been 14624 characters)'
fi
#	End of shell archive
exit 0
-- 
--
Eric R. Smith                     email:
Dept. of Mathematics            ersmith at uwovax.uwo.ca
University of Western Ontario   ersmith at uwovax.bitnet
London, Ont. Canada N6A 5B7
ph: (519) 661-3638

exit 0 # Just in case...
-- 
Kent Landfield                   INTERNET: kent at sparky.IMD.Sterling.COM
Sterling Software, IMD           UUCP:     uunet!sparky!kent
Phone:    (402) 291-8300         FAX:      (402) 291-4362
Please send comp.sources.misc-related mail to kent at uunet.uu.net.



More information about the Comp.sources.misc mailing list