ersmith@uwovax.uwo.ca (Eric R. Smith) (02/20/91)
Submitted-by: Eric R. Smith <ersmith@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@uwovax.uwo.ca University of Western Ontario ersmith@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@uwovax.uwo.ca University of Western Ontario ersmith@uwovax.bitnet London, Ont. Canada N6A 5B7 ph: (519) 661-3638 exit 0 # Just in case... -- Kent Landfield INTERNET: kent@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@uunet.uu.net.