home *** CD-ROM | disk | FTP | other *** search
- /*
- * Prototype Pre-Processor, by Mike Gleason, NCEMRSoft.
- * Version 1.0 / February 8, 1993.
- */
-
- #define VERSION "1.0"
-
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
- #include <stdlib.h>
-
- /* Definitions. */
- #define CPP_LINE '#'
- #define SEMICOLON ';'
- #define LEFTBRACKET '{'
- #define RIGHTBRACKET '}'
- #define LEFTPAREN '('
- #define RIGHTPAREN ')'
- #define SLASH '/'
- #define BACKSLASH '\\'
- #define ASTERISK '*'
- #define COMMA ','
- #define CIDENTCHAR(c) (isalnum(c) || ((c) == '_'))
- #define CIDENTCHAR1(c) (isalpha(c) || ((c) == '_'))
- #define NEXTC (cbp->chr)
- #define SKIPCHAR cbp->chr = getc(fp); cbp = (cbp->next)
- #define EQ(a,b) (strcmp((a), (b)) == 0)
- #define Strncpy(a,b) strncpy((a), (b), sizeof(a) - 1)
- #define Strncat(a,b) strncat((a), (b), sizeof(a) - 1)
- #define wt_unknown 0
- #define wt_extern 1
- #define wt_static 2
- #define wt_volatile 3
- #define wt_const 4
- #define wt_unsigned 5
- #define wt_signed 6
- #define wt_enum 7
- #define wt_union 8
- #define wt_struct 9
- #define wt_typedef 10
- #ifndef HEADERDIR
- # define HEADERDIR "/usr/include"
- #endif
-
- /* Types. */
- struct ch {
- int chr;
- struct ch *next;
- };
-
- /* Globals. */
- FILE *fp;
- char word[128];
-
- /* For now, pgrepoutput isn't very helpful. I was going to support this
- * weird format which prints the function name first so you could alphabetize
- * the list (for fast searches), but fgrep is plenty fast for me.
- */
-
- int pgrepoutput = 0;
- int is_sue;
- int is_ptr;
- int is_volatile;
- int is_signed;
- int curline;
- int curchar;
- int startline;
- char typename[64];
- char funcname[64];
- char funcargs[256];
- char filename[256];
-
- /* Keep a 4-byte look ahead buffer. */
- struct ch cbuf[4] = {
- { EOF, &cbuf[1] },
- { EOF, &cbuf[2] },
- { EOF, &cbuf[3] },
- { EOF, &cbuf[0] }
- }, *cbp;
-
-
-
-
- static void InitGetc(void)
- {
- int i;
-
- cbp = cbuf;
- curline = 1;
- curchar = 0;
- for (i=0; i<4; i++)
- cbuf[i].chr = getc(fp);
- } /* InitGetc */
-
-
-
-
- static int Getc(void)
- {
- int c;
- c = cbp->chr;
- if (c == '\n') {
- curchar = 0;
- curline++;
- } else
- curchar++;
- SKIPCHAR;
- return c;
- } /* Getc */
-
-
-
-
- static int Skipline(void)
- {
- int c;
-
- while(1) {
- c = Getc();
- if (c == EOF) return (EOF);
- if (c == BACKSLASH)
- (void) Getc();
- if (c == '\n') return ('\n');
- }
- } /* Skipline */
-
-
-
-
- static int Wordcmp(void)
- {
- char *cp = word;
- int wt = wt_unknown;
-
- switch(*cp++) {
- case 'e': /* extern? */
- if (EQ(cp, "xtern"))
- wt = wt_extern;
- else if (EQ(cp, "num"))
- wt = wt_enum;
- break;
- case 't':
- if (EQ(cp, "ypedef"))
- wt = wt_typedef;
- break;
- case 'v':
- if (EQ(cp, "olatile"))
- wt = wt_volatile;
- break;
- case 'u':
- if (EQ(cp, "nsigned"))
- wt = wt_unsigned;
- else if (EQ(cp, "nion"))
- wt = wt_union;
- break;
- case 's':
- if (*cp++ == 't') {
- if (EQ(cp, "ruct"))
- wt = wt_struct;
- else if (EQ(cp, "atic"))
- wt = wt_static;
- } else if (EQ(cp, "igned"))
- wt = wt_signed;
- break;
- }
- return wt;
- } /* Wordcmp */
-
-
-
-
- static int SkipUntilSemi(void)
- {
- int brackets = 0, c;
-
- while (1) {
- c = Getc();
- if (c == EOF)
- break;
- else if (c == SEMICOLON && brackets <= 0)
- break;
- else if (c == LEFTBRACKET)
- brackets++;
- else if (c == RIGHTBRACKET)
- --brackets;
- }
- return c;
- } /* SkipUntilSemi */
-
-
-
- static int SkipBrackets(void)
- {
- int brackets = 1, c;
-
- while (brackets > 0) {
- c = Getc();
- if (c == EOF)
- break;
- else if (c == LEFTBRACKET)
- brackets++;
- else if (c == RIGHTBRACKET)
- --brackets;
- }
- return c;
- } /* SkipUntilSemi */
-
-
-
-
- static void PutProto(void)
- {
- char *sue_str, *vol_str, *signed_str;
- char *ptr_str = "***********";
-
- if (is_sue == wt_struct)
- sue_str = "struct ";
- else if (is_sue == wt_union)
- sue_str = "union ";
- else if (is_sue == wt_enum)
- sue_str = "enum ";
- else sue_str = "";
-
- if (is_volatile)
- vol_str = "volatile ";
- else vol_str = "";
-
- if (is_ptr > 0)
- ptr_str[is_ptr] = 0;
- else ptr_str = "";
-
- if (is_signed == wt_unsigned)
- signed_str = "unsigned ";
- else if (is_signed == wt_signed)
- signed_str = "signed ";
- else signed_str = "";
-
- if (pgrepoutput > 0) {
- (void) printf("%s [%s%s%s%s %s]%s;%s %d\n",
- funcname,
- vol_str,
- signed_str,
- sue_str,
- typename,
- ptr_str,
- funcargs,
- filename,
- startline
- );
- } else {
- if (!EQ("-", filename))
- (void) printf("%s %d: ",
- filename,
- startline
- );
- (void) printf("%s%s%s%s %s%s%s;\n",
- vol_str,
- signed_str,
- sue_str,
- typename,
- ptr_str,
- funcname,
- funcargs
- );
- }
-
- if (is_ptr > 0)
- ptr_str[is_ptr] = ASTERISK;
- } /* PutProto */
-
-
-
-
- static void NewType(void)
- {
- is_sue = 0;
- is_volatile = 0;
- is_signed = 0;
- is_ptr = 0;
- typename[0] = funcname[0] = funcargs[0] = 0;
- startline = -1;
- } /* NewType */
-
-
-
-
- static int ParenCollect(char *dst, size_t siz)
- {
- char *wordp = dst;
- int parens = 1, c;
- size_t len;
-
- siz -= 2; /* leave room for last ) and null. */
- *wordp++ = LEFTPAREN;
- len = 1;
-
- while (1) {
- c = Getc();
- if (c == EOF)
- break;
- if (c == LEFTPAREN)
- parens++;
- else if (c == RIGHTPAREN) {
- if (--parens == 0) {
- *wordp++ = c;
- break;
- }
- }
- if (isspace(c)) {
- /* Don't bother with consecutive whitespace. */
- if (!isspace(wordp[-1]) && len < siz) {
- *wordp++ = ' ';
- ++len;
- }
- } else if (len < siz) {
- *wordp++ = c;
- ++len;
- }
- }
- *wordp = 0;
- return c;
- } /* ParenCollect */
-
-
-
-
- static void Parse(void)
- {
- int c = '\n', c2;
- int inword = 0;
- char *wordp;
- int wt;
-
- InitGetc();
- NewType();
-
- while(1) {
- if (inword) {
- if (CIDENTCHAR(c)) {
- *wordp++ = c;
- } else {
- /* End token. */
- *wordp = 0;
- inword = 0;
- switch (wt = Wordcmp()) {
- case wt_typedef:
- (void) SkipUntilSemi();
- break;
- case wt_struct:
- case wt_enum:
- case wt_union:
- is_sue = wt;
- break;
- case wt_volatile:
- is_volatile = wt_volatile;
- break;
- case wt_unsigned:
- case wt_signed:
- is_signed = wt;
- break;
- case wt_static:
- case wt_extern:
- break;
- case wt_unknown:
- if (typename[0] == 0) {
- (void) Strncpy(typename, word);
- } else {
- if (startline == -1)
- startline = curline;
- (void) Strncpy(funcname, word);
- }
- }
- }
- } else {
- if (CIDENTCHAR1(c)) {
- wordp = word;
- inword = 1;
- *wordp++ = c;
- }
- }
-
- if (c == '\n') {
- while (NEXTC == CPP_LINE) {
- if (Skipline() == EOF)
- goto done;
- }
- } else if (c == SLASH) {
- /* C++ style comment. */
- if (((c2 = NEXTC) == SLASH)) {
- if (Skipline() == EOF)
- goto done;
- } else if (c2 == ASTERISK) {
- /* C comment block. */
- SKIPCHAR;
- while (1) {
- if ((c = Getc()) == EOF) goto done;
- if (c == ASTERISK && NEXTC == SLASH) {
- /* End of comment. */
- SKIPCHAR;
- break;
- }
- } /* end getting comment block. */
- } /* end if the char was '*' */
- } else if (c == SEMICOLON) {
- if (funcargs[0])
- PutProto();
- NewType();
- } else if (c == COMMA) {
- if (funcargs[0])
- PutProto();
- funcname[0] = funcargs[0] = 0;
- is_ptr = 0;
- startline = -1;
- } else if (c == LEFTBRACKET) {
- if (is_sue && (SkipBrackets() == EOF))
- goto done;
- else if (EQ(typename, "C")) /* No 'extern "C" {' lines, please. */
- typename[0] = 0;
- } else if (c == LEFTPAREN) {
- if (is_signed && typename[0] && funcname[0] == 0) {
- (void) Strncpy(funcname, typename);
- (void) Strncpy(typename, "int");
- startline = curline;
- }
- if (funcname[0]) {
- /* We have an argument list. */
- if (ParenCollect(funcargs, sizeof(funcargs)) == EOF)
- goto done;
- } else {
- /* Typename, could be something like: (void (*)(int)) */
- if (ParenCollect(typename, sizeof(typename)) == EOF)
- goto done;
- }
- } else if (c == ASTERISK) {
- if (typename[0])
- is_ptr++;
- }
-
- c = Getc();
- if (c == EOF) break;
- }
- done:
- return;
- } /* parse */
-
-
-
- void main(int argc, char **argv)
- {
- int i, c, files;
-
- for (i=1, files=0; i<argc; i++) {
- if (argv[i][0] == '-') {
- c = argv[i][1];
- if (c == 'g')
- pgrepoutput++;
- else if (c == 'c')
- --pgrepoutput;
- else {
- (void) fprintf(stderr, "\
- %s version %s by Mike Gleason, NCEMRSoft.\n\
- Function: Parses C header files and prints the function prototypes from them.\n\
- Usage: %s [-g | -c] headers...\n", argv[0], VERSION, argv[0]);
- exit(1);
- }
- } else {
- if ((fp = fopen(argv[i], "r")) == NULL)
- perror(argv[i]);
- else {
- files++;
- if (strncmp(argv[i], HEADERDIR, sizeof(HEADERDIR) - 1) == 0) {
- filename[0] = '<';
- (void) strncpy(filename + 1, argv[i] + sizeof(HEADERDIR), sizeof(filename) - 2);
- (void) Strncat(filename, ">");
- } else
- (void) Strncpy(filename, argv[i]);
- Parse();
- (void) fclose(fp);
- }
- }
- }
- if (files == 0) {
- fp = stdin;
- (void) Strncpy(filename, "-");
- Parse();
- }
- } /* main */
-
- /* prpp.c */
-