home *** CD-ROM | disk | FTP | other *** search
Text File | 1989-10-19 | 35.3 KB | 1,692 lines |
- Path: wuarchive!brutus.cs.uiuc.edu!uakari.primate.wisc.edu!xanth!bbn.com!rsalz
- From: rsalz@uunet.uu.net (Rich Salz)
- Newsgroups: comp.sources.unix
- Subject: v20i039: Generate C function prototypes from C source
- Message-ID: <2037@prune.bbn.com>
- Date: 19 Oct 89 17:21:41 GMT
- Lines: 1682
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Chin Huang <cthuang@watdragon.waterloo.edu>
- Posting-number: Volume 20, Issue 39
- Archive-name: cproto
-
- [ Not to be confused with Ron Guilmette's protoize, which will also
- appear here. This takes a neat way out in that it avoids doing any
- parsing of function bodies, which I think is really clever. As Chin
- says, you will need FLEX which is available from your nearest archive
- site and is also distributed on most GNU sites. /r$ ]
-
- This is program automatically generates C function prototypes and
- variable declarations from C language source code.
-
- You don't need the source to 4.2BSD lint to compile this program but
- you do need flex since the lexical analyzer specified in lex.l makes use
- of mutually exclusive start conditions.
-
- Chin Huang
- cthuang@watdragon.waterloo.edu
-
- #
- # This is a shell archive. Remove anything before this line,
- # then unpack it by saving it in a file and typing "sh file".
- #
- # Contents: README Makefile cproto.1 cproto.sh grammar.y lex.l cproto.h
- # patchlevel.h semantics.h symbol.h cproto1.c semantics.c string.c
- # symbol.c
-
- echo x - README
- sed 's/^@//' > "README" <<'@//E*O*F README//'
- This is program automatically generates C function prototypes and
- variable declarations from C language source code.
-
- You don't need the source to 4.2BSD lint to compile this program but
- you do need flex since the lexical analyzer specified in lex.l makes use
- of mutually exclusive start conditions.
-
- Chin Huang
- cthuang@watdragon.waterloo.edu
- @//E*O*F README//
- chmod u=rw,g=r,o=r README
-
- echo x - Makefile
- sed 's/^@//' > "Makefile" <<'@//E*O*F Makefile//'
- #
- # $Header: Makefile,v 1.1 89/03/14 20:58:56 cthuang Exp $
- #
- # Makefile for C prototype generator
-
- LEX = flex
- YACC = yacc
- CFLAGS = -O
-
- SOURCES = README Makefile cproto.1 cproto.sh \
- grammar.y lex.l \
- cproto.h patchlevel.h semantics.h symbol.h \
- cproto1.c semantics.c string.c symbol.c
- CSOURCES = cproto1.c semantics.c string.c symbol.c y.tab.c
- OBJECTS = cproto1.o semantics.o string.o symbol.o y.tab.o
-
- all: cproto1
-
- cproto1: $(OBJECTS)
- $(CC) $(CFLAGS) -o $@ $(OBJECTS)
-
- y.tab.o: y.tab.c lex.yy.c
- $(CC) $(CFLAGS) -c $*.c
-
- y.tab.c: grammar.y
- $(YACC) grammar.y
-
- lex.yy.c: lex.l grammar.y
- $(LEX) lex.l
-
- lint:
- lint -B $(CSOURCES)
-
- shar:
- shar -c $(SOURCES) >shar.out
-
- ci:
- ci -u $(SOURCES)
-
- main.o: symbol.h cproto.h
- semantics.o: symbol.h cproto.h semantics.h
- symbol.o: symbol.h
- y.tab.o: symbol.h cproto.h semantics.h
- @//E*O*F Makefile//
- chmod u=rw,g=r,o=r Makefile
-
- echo x - cproto.1
- sed 's/^@//' > "cproto.1" <<'@//E*O*F cproto.1//'
- @.\" $Header: cproto.1,v 1.1 89/03/14 21:30:01 cthuang Exp $
- @.\"
- @.de EX \"Begin example
- @.ne 5
- @.if n .sp 1
- @.if t .sp .5
- @.nf
- @.in +.5i
- @..
- @.de EE \"End example
- @.fi
- @.in -.5i
- @.if n .sp 1
- @.if t .sp .5
- @..
- @.TH CPROTO 1 "March 14, 1989"
- @.SH NAME
- cproto \- generate C function prototypes from C source code
- @.SH SYNOPSIS
- @.B cproto
- [
- @.I option \fP...\fI
- ] [
- @.I file
- ]
- @.SH DESCRIPTION
- @.B Cproto
- generates C function prototypes from a C language source file.
- For each function defined in the file,
- @.B cproto
- outputs to the standard output a line consisting of the prototype
- for that function.
- Optionally,
- @.B cproto
- also outputs declarations for any variables defined in the file.
- If no
- @.I file
- argument is given,
- @.B cproto
- takes its input from the standard input.
- @.SH OPTIONS
- @.TP
- @.B \-e
- On the output, prepend the keyword
- @.B extern
- to declarations that have global scope.
- @.TP
- @.B \-g
- Output only "global" declarations.
- Only declarations of functions and variables that can be accessed outside
- of the source file will be printed.
- @.TP
- @.BI \-p n
- Set the style of function prototype where
- @.I n
- is a number from 0 to 2.
- For example, consider the function definition
- @.EX
- main (argc, argv)
- int argc;
- char *argv[];
- {
- ...
- }
- @.EE
- A value of 2 produces the full function prototype:
- @.EX
- int main(int argc, char *argv[]);
- @.EE
- For a value of 1, the output has the form:
- @.EX
- int main(int /*argc*/, char */*argv*/[]);
- @.EE
- When set to 0, the output is:
- @.EX
- int main(/*int argc, char *argv[]*/);
- @.EE
- The default value is 2.
- @.TP
- @.B \-v
- Also output declarations of variables defined in the file.
- @.TP
- @.BI \-D name\[=value\]
- This option is passed through to the preprocessor and is used to define
- symbols for use with conditionals such as
- @.I #ifdef.
- @.TP
- @.BI \-U name
- This option is passed through to the preprocessor and is used to remove
- any definitions of this symbol.
- @.TP
- @.BI \-I directory
- This option is passed through to the preprocessor and is used to specify
- a directory to search for files that are referenced with
- @.I #include.
- @.SH AUTHOR
- Chin Huang (cthuang@watdragon.waterloo.edu)
- @.SH CAVEATS
- Any error messages produced are minimal.
- If the C source code is accepted by the C compiler, then
- @.B cproto
- will probably accept it as well.
- @.SH "SEE ALSO"
- cc(1),
- cpp(1)
- @//E*O*F cproto.1//
- chmod u=r,g=r,o=r cproto.1
-
- echo x - cproto.sh
- sed 's/^@//' > "cproto.sh" <<'@//E*O*F cproto.sh//'
- #!/bin/sh
- # $Header$
- #
- cpp_opt="-I."
- cproto_opt=""
- source=""
- for opt do
- case $opt in
- -D*|-U*|-I*)
- cpp_opt="$cpp_opt $opt"
- ;;
- -*)
- cproto_opt="$cproto_opt $opt"
- ;;
- *)
- source=$opt
- ;;
- esac
- done
- /lib/cpp $cpp_opt $source | cproto1 $cproto_opt
- @//E*O*F cproto.sh//
- chmod u=rwx,g=r,o=r cproto.sh
-
- echo x - grammar.y
- sed 's/^@//' > "grammar.y" <<'@//E*O*F grammar.y//'
- /*
- * $Header: grammar.y,v 1.1 89/03/14 20:59:01 cthuang Exp $
- *
- * yacc grammar for C prototype generator
- * This was derived from the grammar given in Appendix A of
- * "The C Programming Language" by the Kernighan and Ritchie.
- */
-
- /* identifiers that are not reserved words */
- %token IDENTIFIER TYPEDEF_NAME
-
- /* storage class */
- %token AUTO EXTERN REGISTER STATIC TYPEDEF
-
- /* type specifiers */
- %token CHAR DOUBLE FLOAT INT VOID
- %token LONG SHORT SIGNED UNSIGNED
- %token ENUM STRUCT UNION
-
- /* type qualifiers */
- %token CONST VOLATILE
-
- /* paired braces and everything between them: { ... } */
- %token BRACES
-
- /* paired square brackets and everything between them: [ ... ]*/
- %token BRACKETS
-
- /* three periods */
- %token ELLIPSIS
-
- /* equal sign followed by constant expression or stuff between braces */
- %token INITIALIZER
-
- %type <decl_spec> decl_specs decl_spec_item
- %type <decl_spec> storage_class type_spec type_qualifier
- %type <decl_spec> struct_union_spec enum_spec
- %type <decl_list> init_decl_list
- %type <declarator> init_declarator declarator direct_decl
- %type <param_list> param_type_list param_list
- %type <parameter> param_decl
- %type <param_list> identifier_list ident_list
- %type <text> struct_or_union
- %type <text> pointer type_qual_list
- %type <text> IDENTIFIER TYPEDEF_NAME
- %type <text> BRACKETS
-
- %{
- #include <stdio.h>
- #include "cproto.h"
- #include "semantics.h"
-
- /* This variable is TRUE when the parameter declaration part of a function
- * definition is currently being parsed.
- * For example:
- * int
- * main (argc, argv)
- * int argc; | TRUE when these lines
- * char **argv; | are being scanned.
- * {
- * ...
- * }
- */
- static boolean func_decl = FALSE;
-
- /* This points to the list of parameters for the current function definition. */
- static ParameterList *cur_params;
-
- /* temporary string buffer */
- static char buf[MAX_TEXT_LENGTH];
-
- /* Table of typedef names */
- SymbolTable *typedef_names;
- %}
- %%
-
- program : /* empty */
- | translation_unit
- ;
-
- translation_unit : external_decl
- | translation_unit external_decl
- ;
-
- external_decl : declaration
- | function_def
- | error
- ;
-
- declaration : decl_specs ';'
- | decl_specs init_decl_list ';'
- {
- if (func_decl) {
- set_param_types(cur_params, &$1, &$2);
- } else {
- output_declarations(&$1, &$2);
- }
- free_decl_spec(&$1);
- free_decl_list(&$2);
- }
- | TYPEDEF decl_specs declarator ';'
- {
- (void)new_symbol(typedef_names, $3.name);
- free_decl_spec(&$2);
- free_declarator(&$3);
- }
- ;
-
- function_def : decl_specs
- declarator
- {
- if ($2.func_def == FUNC_DEF_NONE) {
- yyerror("syntax error");
- YYERROR;
- }
- func_decl = TRUE;
- cur_params = &($2.params);
- }
- opt_decl_list BRACES
- {
- func_decl = FALSE;
-
- output_prototype(&$1, &$2);
- free_decl_spec(&$1);
- free_declarator(&$2);
- }
- | declarator
- {
- if ($1.func_def == FUNC_DEF_NONE) {
- yyerror("syntax error");
- YYERROR;
- }
- func_decl = TRUE;
- cur_params = &($1.params);
- }
- opt_decl_list BRACES
- {
- DeclSpec decl_spec;
-
- func_decl = FALSE;
-
- new_decl_spec(&decl_spec, "int", DE_EXTERN);
- output_prototype(&decl_spec, &$1);
- free_decl_spec(&decl_spec);
- free_declarator(&$1);
- }
- ;
-
- decl_list : declaration
- | decl_list declaration
- ;
-
- decl_specs : decl_spec_item
- | decl_specs decl_spec_item
- {
- join_decl_specs(&$$, &$1, &$2);
- }
- ;
-
- decl_spec_item : storage_class
- | type_spec
- | type_qualifier
- ;
-
- opt_decl_list : decl_list
- | /* empty */
- ;
-
- storage_class : AUTO
- {
- new_decl_spec(&$$, "auto", DE_JUNK);
- }
- | EXTERN
- {
- new_decl_spec(&$$, "extern", DE_EXTERN);
- }
- | REGISTER
- {
- new_decl_spec(&$$, "register", DE_JUNK);
- }
- | STATIC
- {
- new_decl_spec(&$$, "static", DE_STATIC);
- }
- ;
-
- type_spec : CHAR
- {
- new_decl_spec(&$$, "char", DE_EXTERN);
- }
- | DOUBLE
- {
- new_decl_spec(&$$, "double", DE_EXTERN);
- }
- | FLOAT
- {
- new_decl_spec(&$$, "float", DE_EXTERN);
- }
- | INT
- {
- new_decl_spec(&$$, "int", DE_EXTERN);
- }
- | LONG
- {
- new_decl_spec(&$$, "long", DE_EXTERN);
- }
- | SHORT
- {
- new_decl_spec(&$$, "short", DE_EXTERN);
- }
- | SIGNED
- {
- new_decl_spec(&$$, "signed", DE_EXTERN);
- }
- | UNSIGNED
- {
- new_decl_spec(&$$, "unsigned", DE_EXTERN);
- }
- | VOID
- {
- new_decl_spec(&$$, "void", DE_EXTERN);
- }
- | struct_union_spec
- | enum_spec
- | TYPEDEF_NAME
- {
- new_decl_spec(&$$, $1, DE_EXTERN);
- }
- ;
-
- type_qualifier : CONST
- {
- new_decl_spec(&$$, "const", DE_EXTERN);
- }
- | VOLATILE
- {
- new_decl_spec(&$$, "volatile", DE_EXTERN);
- }
- ;
-
- struct_union_spec : struct_or_union IDENTIFIER BRACES
- {
- sprintf(buf, "%s %s {}", $1, $2);
- new_decl_spec(&$$, buf, DE_EXTERN);
- }
- | struct_or_union BRACES
- {
- sprintf(buf, "%s {}", $1);
- new_decl_spec(&$$, buf, DE_EXTERN);
- }
- | struct_or_union IDENTIFIER
- {
- sprintf(buf, "%s %s", $1, $2);
- new_decl_spec(&$$, buf, DE_EXTERN);
- }
- ;
-
- struct_or_union : STRUCT
- {
- strcpy($$, "struct");
- }
- | UNION
- {
- strcpy($$, "union");
- }
- ;
-
- init_decl_list : init_declarator
- {
- new_decl_list(&$$, &$1);
- }
- | init_decl_list ',' init_declarator
- {
- add_decl_list(&$$, &$1, &$3);
- }
- ;
-
- init_declarator : declarator
- | declarator INITIALIZER
- ;
-
- enum_spec : ENUM IDENTIFIER BRACES
- {
- sprintf(buf, "enum %s {}", $2);
- new_decl_spec(&$$, buf, DE_EXTERN);
- }
- | ENUM BRACES
- {
- new_decl_spec(&$$, "enum {}", DE_EXTERN);
- }
- | ENUM IDENTIFIER
- {
- sprintf(buf, "enum %s", $2);
- new_decl_spec(&$$, buf, DE_EXTERN);
- }
- ;
-
- declarator : pointer direct_decl
- {
- sprintf(buf, "%s%s", $1, $2.text);
- $$ = $2;
- $$.text = strdup(buf);
- free($2.text);
- }
- | direct_decl
- ;
-
- direct_decl : IDENTIFIER
- {
- new_declarator(&$$, $1, $1);
- }
- | '(' declarator ')'
- {
- sprintf(buf, "(%s)", $2.text);
- $$ = $2;
- $$.text = strdup(buf);
- free($2.text);
- }
- | direct_decl BRACKETS
- {
- sprintf(buf, "%s%s", $1.text, $2);
- $$ = $1;
- $$.text = strdup(buf);
- free($1.text);
- }
- | direct_decl '(' param_type_list ')'
- {
- sprintf(buf, "%s(%%s)", $1.text);
- $$ = $1;
- $$.func_def = FUNC_DEF_NEW;
- $$.params = $3;
- $$.text = strdup(buf);
- free($1.text);
- }
- | direct_decl '(' identifier_list ')'
- {
- sprintf(buf, "%s(%%s)", $1.text);
- $$ = $1;
- $$.func_def = FUNC_DEF_OLD;
- $$.params = $3;
- $$.text = strdup(buf);
- free($1.text);
- }
- ;
-
- pointer : '*' type_qual_list
- {
- sprintf($$, "*%s", $2);
- }
- | '*' type_qual_list pointer
- {
- sprintf($$, "*%s%s", $2, $3);
- }
- ;
-
- type_qual_list : /* empty */
- {
- strcpy($$, "");
- }
- | type_qual_list type_qualifier
- {
- sprintf($$, "%s %s ", $1, $2.text);
- free($2.text);
- }
- ;
-
- param_type_list : VOID
- {
- Parameter p;
-
- new_parameter(&p, "void", " ", " ");
- new_param_list(&$$, &p);
- }
- | param_list
- | param_list ',' ELLIPSIS
- {
- Parameter p;
-
- new_parameter(&p, "...", " ", " ");
- add_param_list(&$$, &$1, &p);
- }
- ;
-
- param_list : param_decl
- {
- new_param_list(&$$, &$1);
- }
- | param_list ',' param_decl
- {
- add_param_list(&$$, &$1, &$3);
- }
- ;
-
- param_decl : decl_specs declarator
- {
- new_parameter(&$$, $1.text, $2.text, $2.name);
- }
- ;
-
- identifier_list : /* empty */
- {
- new_ident_list(&$$);
- }
- | ident_list
- ;
-
- ident_list : IDENTIFIER
- {
- new_ident_list(&$$);
- add_ident_list(&$$, &$$, $1);
- }
- | ident_list ',' IDENTIFIER
- {
- add_ident_list(&$$, &$1, $3);
- }
- ;
-
- %%
- #include "lex.yy.c"
-
- yyerror (msg)
- char *msg;
- {
- print_error(msg);
- }
-
- void
- parse_file ()
- {
- typedef_names = create_symbol_table();
- (void)yyparse();
- }
- @//E*O*F grammar.y//
- chmod u=rw,g=r,o=r grammar.y
-
- echo x - lex.l
- sed 's/^@//' > "lex.l" <<'@//E*O*F lex.l//'
- /*
- * $Header: lex.l,v 1.1 89/03/14 20:59:10 cthuang Exp $
- *
- * C function prototype generator
- * Lexical analyzer specification for flex
- */
-
- WLF ([ \t\n\f]*)
- LETTER [a-zA-Z_]
- DIGIT [0-9]
- ID {LETTER}({LETTER}|{DIGIT})*
- SKIPQUOTED (\"([^"\n]|\\\")*\"|\'.\'|\\.)
-
- %{
- static int curly = 0; /* number of curly brace nesting levels */
- int line_num = 1;
- %}
-
- %x INIT1 INIT2 CURLY COMMENT
- %%
- \n { ++line_num; }
-
- #[ \t]*[0-9]+.*$ { sscanf(yytext, "# %d ", &line_num); --line_num; }
- #.*$ ;
-
- "(" return '(';
- ")" return ')';
- "*" return '*';
- "," return ',';
- ";" return ';';
- "..." return ELLIPSIS;
-
- auto return AUTO;
- extern return EXTERN;
- register return REGISTER;
- static return STATIC;
- typedef return TYPEDEF;
- char return CHAR;
- double return DOUBLE;
- float return FLOAT;
- int return INT;
- void return VOID;
- long return LONG;
- short return SHORT;
- signed return SIGNED;
- unsigned return UNSIGNED;
- enum return ENUM;
- struct return STRUCT;
- union return UNION;
- const return CONST;
- volatile return VOLATILE;
-
- \[[^\]]*\] {
- strcpy(yylval.text, yytext);
- return BRACKETS;
- }
-
- {ID} {
- strcpy(yylval.text, yytext);
- if (is_typedef_name(yytext))
- return TYPEDEF_NAME;
- else
- return IDENTIFIER;
- }
-
- "="{WLF}"{" { curly = 1; BEGIN INIT1; }
- <INIT1>\n { ++line_num; }
- <INIT1>"{" ++curly;
- <INIT1>"}" {
- if (--curly == 0) {
- BEGIN 0;
- return INITIALIZER;
- }
- }
- <INIT1>{SKIPQUOTED}|. ;
-
- "=" { BEGIN INIT2; }
- <INIT2>\n { ++line_num; }
- <INIT2>({SKIPQUOTED}|[^,;])+[,;] {
- yyless(yyleng-1);
- BEGIN 0;
- return INITIALIZER;
- }
-
- "{" { curly=1; BEGIN CURLY; }
- <CURLY>\n { ++line_num; }
- <CURLY>"{" { ++curly; }
- <CURLY>"}" {
- --curly;
- if (curly == 0) {
- BEGIN 0;
- return BRACES;
- }
- }
- <CURLY>{SKIPQUOTED}|. ;
-
- "/*" BEGIN COMMENT;
- <COMMENT>\n { ++line_num; }
- <COMMENT>"*/" BEGIN 0;
- <COMMENT>. ;
-
- [ \t]+ ;
- @. print_error("syntax error");
- @//E*O*F lex.l//
- chmod u=rw,g=r,o=r lex.l
-
- echo x - cproto.h
- sed 's/^@//' > "cproto.h" <<'@//E*O*F cproto.h//'
- /*
- * $Header: cproto.h,v 1.1 89/03/14 20:59:12 cthuang Exp $
- *
- * Definitions for C language prototype generator
- */
- #include "symbol.h"
-
- /* Boolean type */
- typedef char boolean;
- #define FALSE 0
- #define TRUE 1
-
- /* maximum number of characters in a text buffer */
- #define MAX_TEXT_LENGTH 512
-
- /* Declaration specifier flags */
- #define DE_EXTERN 0 /* default: declaration has global scope */
- #define DE_STATIC 1 /* visible only in current file */
- #define DE_JUNK 2 /* we're not interested in this declaration */
-
- /* This structure stores information about a declaration specifier. */
- typedef struct _decl_spec {
- unsigned short flags; /* flags defined above */
- char *text; /* source text */
- } DeclSpec;
-
- /* Types of function definitions
- *
- * FUNC_DEF_OLD traditional style function definition
- * FUNC_DEF_NEW ANSI style
- */
- typedef enum { FUNC_DEF_NONE, FUNC_DEF_OLD, FUNC_DEF_NEW } FuncDefType;
-
- /* This structure stores information about a function parameter. */
- typedef struct _parameter {
- char *decl_spec; /* declaration specifier text */
- char *declarator; /* declarator text */
- char *name; /* parameter name */
- struct _parameter *next; /* next parameter in list */
- } Parameter;
-
- /* This is a list of function parameters. */
- typedef struct _parameter_list {
- Parameter *first; /* pointer to first parameter in list */
- Parameter *last; /* pointer to last parameter in list */
- } ParameterList;
-
- /* This structure stores information about a declarator. */
- typedef struct _declarator {
- char *name; /* name of declared variable or function */
- char *text; /* source text */
- FuncDefType func_def; /* style of function definition */
- ParameterList params; /* list of parameters if this is a function */
- struct _declarator *next; /* next declarator in list */
- } Declarator;
-
- /* This is a list of declarators. */
- typedef struct _declarator_list {
- Declarator *first; /* pointer to first declarator in list */
- Declarator *last; /* pointer to last declarator in list */
- } DeclaratorList;
-
- /* parser stack entry type */
- typedef union {
- char text[MAX_TEXT_LENGTH];
- DeclSpec decl_spec;
- Parameter parameter;
- ParameterList param_list;
- Declarator declarator;
- DeclaratorList decl_list;
- } YYSTYPE;
-
- /* Program options */
- extern boolean extern_out;
- extern boolean globals_only;
- extern int proto_style;
- extern boolean variables_out;
-
- /* Global declarations */
- extern int line_num;
- extern SymbolTable *typedef_names;
- extern void print_error();
- extern void parse_file();
-
- extern char *strdup(), *strstr();
- extern char *malloc();
- @//E*O*F cproto.h//
- chmod u=rw,g=r,o=r cproto.h
-
- echo x - patchlevel.h
- sed 's/^@//' > "patchlevel.h" <<'@//E*O*F patchlevel.h//'
- #define PATCHLEVEL 0
- @//E*O*F patchlevel.h//
- chmod u=rw,g=r,o=r patchlevel.h
-
- echo x - semantics.h
- sed 's/^@//' > "semantics.h" <<'@//E*O*F semantics.h//'
- /*
- * $Header: semantics.h,v 1.1 89/03/14 20:59:16 cthuang Exp $
- *
- * Declarations for semantics action routines
- */
-
- extern boolean is_typedef_name();
-
- extern void new_decl_spec();
- extern void join_decl_specs();
- extern void free_decl_spec();
-
- extern void new_parameter();
- extern void free_parameter();
-
- extern void new_param_list();
- extern void add_param_list();
- extern void free_param_list();
-
- extern void new_ident_list();
- extern void add_ident_list();
-
- extern void new_declarator();
- extern void free_declarator();
-
- extern void new_decl_list();
- extern void add_decl_list();
- extern void free_decl_list();
-
- extern void set_param_types();
- extern void output_declarations();
- extern void output_prototype();
- @//E*O*F semantics.h//
- chmod u=rw,g=r,o=r semantics.h
-
- echo x - symbol.h
- sed 's/^@//' > "symbol.h" <<'@//E*O*F symbol.h//'
- /*
- * $Header: symbol.h,v 1.1 89/03/14 20:59:18 cthuang Exp $
- *
- * Definitions for a symbol table
- */
- #ifndef _SYMBOL_H
- #define _SYMBOL_H
-
- /* maximum length of symbols */
- #define SYM_MAX_LENGTH 64
-
- typedef struct _symbol {
- struct _symbol *next; /* next symbol in list */
- char name[SYM_MAX_LENGTH]; /* name of symbol */
- } Symbol;
-
- /* hash table length */
- #define SYM_MAX_HASH 256
-
- typedef struct _symbol_table {
- Symbol *bucket[SYM_MAX_HASH]; /* hash buckets */
- } SymbolTable;
-
- extern SymbolTable *create_symbol_table(); /* Create symbol table */
- extern Symbol *find_symbol(); /* Lookup symbol name */
- extern Symbol *new_symbol(); /* Define new symbol */
-
- #endif
- @//E*O*F symbol.h//
- chmod u=rw,g=r,o=r symbol.h
-
- echo x - cproto1.c
- sed 's/^@//' > "cproto1.c" <<'@//E*O*F cproto1.c//'
- /*
- * $Header: cproto1.c,v 1.1 89/03/14 20:59:21 cthuang Exp $
- *
- * C prototype generator
- * This filter reads C source code and outputs ANSI C function prototypes.
- */
- #ifndef lint
- static char *rcsid = "$Header: cproto1.c,v 1.1 89/03/14 20:59:21 cthuang Exp $";
- #endif
- #include <stdio.h>
- #include "cproto.h"
-
- /* getopt declarations */
- extern int getopt();
- extern char *optarg;
- extern int optind;
-
- /* Name of the program */
- static char *progname = "cproto";
-
- /* Program options */
-
- /* TRUE when "extern" should appear to external declarations. */
- boolean extern_out = FALSE;
-
- /* TRUE when only external declarations will be generated. */
- boolean globals_only = FALSE;
-
- /* This variable controls the style of function prototype. */
- int proto_style = 2;
-
- /* TRUE when variable declarations are printed also. */
- boolean variables_out = FALSE;
-
- /* Output an error message along with the line number where it was found.
- */
- void
- print_error (msg)
- char *msg;
- {
- fprintf(stderr, "%s: line %d: %s\n", progname, line_num, msg);
- }
-
- main (argc, argv)
- int argc;
- char **argv;
- {
- int c;
- boolean error_flag;
-
- error_flag = FALSE;
- while ((c = getopt(argc, argv, "egp:v")) != EOF) {
- switch (c) {
- case 'e':
- extern_out = TRUE;
- break;
- case 'g':
- globals_only = TRUE;
- break;
- case 'p':
- proto_style = atoi(optarg);
- break;
- case 'v':
- variables_out = TRUE;
- break;
- case '?':
- default:
- error_flag = TRUE;
- }
- }
-
- if (optind == argc-1) {
- if (freopen(argv[optind], "r", stdin) == NULL) {
- fprintf(stderr, "%s: cannot open file %s\n", progname,
- argv[optind]);
- exit(1);
- }
- } else {
- error_flag = (boolean)(optind < argc-1);
- }
-
- if (error_flag) {
- fprintf(stderr, "usage: %s [ -egv ] [ -p n ] [ file ]\n", progname);
- exit(1);
- }
-
- parse_file();
- }
- @//E*O*F cproto1.c//
- chmod u=rw,g=r,o=r cproto1.c
-
- echo x - semantics.c
- sed 's/^@//' > "semantics.c" <<'@//E*O*F semantics.c//'
- /*
- * $Header: semantics.c,v 1.1 89/03/14 20:59:22 cthuang Exp $
- *
- * C prototype generator
- * These routines implement the semantic actions executed by the yacc parser.
- *
- */
- #include <stdio.h>
- #include <strings.h>
- #include "cproto.h"
- #include "semantics.h"
-
- /* Create a new string by joining two strings with a space between them.
- * Return a pointer to the resultant string or NULL if an error occurred.
- */
- static char *
- concat_string (a, b)
- char *a, *b;
- {
- char *result;
-
- if ((result = malloc((unsigned)(strlen(a) + strlen(b) + 2))) != NULL) {
- strcpy(result, a);
- strcat(result, " ");
- strcat(result, b);
- }
- return result;
- }
-
- /* Delete the first occurence of a substring from a string.
- * Return a pointer to a static buffer containing the result.
- * If the substring is not found, then return the entire string.
- */
- static char *
- delete_string (src, key)
- char *src, *key;
- {
- static char buf[MAX_TEXT_LENGTH];
- char *s;
- int n;
-
- if ((s = strstr(src, key)) == NULL) {
- strcpy(buf, src);
- } else {
- strcpy(buf, "");
- n = s - src;
- if (n > 0) strncat(buf, src, n);
- n = strlen(src) - n - strlen(key);
- if (n > 0) strncat(buf, s+strlen(key), n);
- }
- return buf;
- }
-
- /* Check if the given identifier is really a typedef name by searching the
- * symbol table.
- * Return TRUE if it is a typedef name.
- */
- boolean
- is_typedef_name (name)
- char *name;
- {
- return (boolean)(find_symbol(typedef_names, name) != NULL);
- }
-
- /* Initialize a new declaration specifier part.
- */
- void
- new_decl_spec (decl_spec, text, flags)
- DeclSpec *decl_spec;
- char *text;
- unsigned short flags;
- {
- decl_spec->text = strdup(text);
- decl_spec->flags = flags;
- }
-
- /* Append two declaration specifier parts together.
- */
- void
- join_decl_specs (result, a, b)
- DeclSpec *result, *a, *b;
- {
- result->text = concat_string(a->text, b->text);
- result->flags = a->flags | b->flags;
- free(a->text);
- free(b->text);
- }
-
- /* Free storage used by a declaration specifier part.
- */
- void
- free_decl_spec (decl_spec)
- DeclSpec *decl_spec;
- {
- if (decl_spec->text != NULL)
- free(decl_spec->text);
- }
-
- /* Initialize the parameter structure.
- */
- void
- new_parameter (param, decl_spec, declarator, name)
- Parameter *param;
- char *decl_spec, *declarator, *name;
- {
- param->decl_spec = strdup(decl_spec);
- param->declarator = strdup(delete_string(declarator, "%s"));
- param->name = strdup(name);
- }
-
- /* Free the storage used by the parameter.
- */
- void
- free_parameter (param)
- Parameter *param;
- {
- if (param->decl_spec != NULL)
- free(param->decl_spec);
- if (param->declarator != NULL)
- free(param->declarator);
- free(param->name);
- }
-
- /* Initialize an empty list of function parameters.
- */
- void
- new_param_list (param_list, param)
- ParameterList *param_list;
- Parameter *param;
- {
- Parameter *p;
-
- p = (Parameter *)malloc(sizeof(Parameter));
- *p = *param;
-
- param_list->first = param_list->last = p;
- p->next = NULL;
- }
-
- /* Add the function parameter declaration to the list.
- */
- void
- add_param_list (to, from, param)
- ParameterList *to, *from;
- Parameter *param;
- {
- Parameter *p;
-
- p = (Parameter *)malloc(sizeof(Parameter));
- *p = *param;
-
- to->first = from->first;
- from->last->next = p;
- to->last = p;
- p->next = NULL;
- }
-
- /* Free storage used by the elements in the function parameter list.
- */
- void
- free_param_list (param_list)
- ParameterList *param_list;
- {
- Parameter *p, *next;
-
- p = param_list->first;
- while (p != NULL) {
- next = p->next;
- free_parameter(p);
- free((char *)p);
- p = next;
- }
- }
-
- /* Initialize an empty list of function parameter names.
- * This is just a list of function parameter declarations with
- * only the name field set.
- */
- void
- new_ident_list (param_list)
- ParameterList *param_list;
- {
- param_list->first = param_list->last = NULL;
- }
-
- /* Add an item to the list of function parameter declarations but set only
- * the parameter name field.
- */
- void
- add_ident_list (to, from, name)
- ParameterList *to, *from;
- char *name;
- {
- Parameter *p;
-
- p = (Parameter *)malloc(sizeof(Parameter));
- p->decl_spec = NULL;
- p->declarator = NULL;
- p->name = strdup(name);
-
- to->first = from->first;
- if (to->first == NULL) {
- to->first = p;
- } else {
- from->last->next = p;
- }
- to->last = p;
- p->next = NULL;
- }
-
- /* Initialize a declarator.
- */
- void
- new_declarator (d, name, text)
- Declarator *d;
- char *name, *text;
- {
- d->name = strdup(name);
- d->text = strdup(text);
- d->func_def = FUNC_DEF_NONE;
- d->params.first = d->params.last = NULL;
- }
-
- /* Free storage used by a declarator.
- */
- void
- free_declarator (d)
- Declarator *d;
- {
- if (d->name != NULL)
- free(d->name);
- if (d->text != NULL)
- free(d->text);
- free_param_list(&(d->params));
- }
-
- /* Initialize a declarator list and add the given declarator to it.
- */
- void
- new_decl_list (decl_list, declarator)
- DeclaratorList *decl_list;
- Declarator *declarator;
- {
- Declarator *d;
-
- d = (Declarator *)malloc(sizeof(Declarator));
- *d = *declarator;
-
- decl_list->first = decl_list->last = d;
- d->next = NULL;
- }
-
- /* Add the declarator to the declarator list.
- */
- void
- add_decl_list (to, from, declarator)
- DeclaratorList *to, *from;
- Declarator *declarator;
- {
- Declarator *d;
-
- d = (Declarator *)malloc(sizeof(Declarator));
- *d = *declarator;
-
- to->first = from->first;
- from->last->next = d;
- to->last = d;
- to->last->next = NULL;
- }
-
- /* Free storage used by the declarators in the declarator list.
- */
- void
- free_decl_list (decl_list)
- DeclaratorList *decl_list;
- {
- Declarator *d, *next;
-
- d = decl_list->first;
- while (d != NULL) {
- next = d->next;
- free_declarator(d);
- free((char *)d);
- d = next;
- }
- }
-
- /* Search the list of parameters for a matching parameter name.
- * Return a pointer to the matching parameter or NULL if not found.
- */
- static Parameter *
- search_parameter_list (params, name)
- ParameterList *params;
- char *name;
- {
- Parameter *p;
-
- for (p = params->first; p != NULL; p = p->next) {
- if (strcmp(p->name, name) == 0)
- return p;
- }
- return (Parameter *)NULL;
- }
-
- /* For each declared variable name in the declarator list,
- * set the declaration specifier and declarator for the parameter
- * with the same name.
- */
- void
- set_param_types (params, decl_spec, declarators)
- ParameterList *params;
- DeclSpec *decl_spec;
- DeclaratorList *declarators;
- {
- Declarator *d;
- Parameter *p;
- char buf[MAX_TEXT_LENGTH];
-
- for (d = declarators->first; d != NULL; d = d->next) {
- /* Search the parameter list for a matching name. */
- p = search_parameter_list(params, d->name);
- if (p == NULL) {
- sprintf(buf, "declared argument \"%s\" is missing", d->name);
- print_error(buf);
- } else {
- p->decl_spec = strdup(decl_spec->text);
- p->declarator = strdup(delete_string(d->text, "%s"));
- }
- }
- }
-
- /* Output a declaration specifier for an external declaration.
- */
- static void
- output_decl_spec (decl_spec)
- DeclSpec *decl_spec;
- {
- if (extern_out && (decl_spec->flags & DE_STATIC) == 0) {
- if (strstr(decl_spec->text, "extern") == NULL) {
- printf("extern ");
- }
- }
- printf("%s ", decl_spec->text);
- }
-
- /* Output a function parameter type and variable declaration.
- */
- static void
- output_parameter (p)
- Parameter *p;
- {
- char *s;
-
- if (proto_style == 1) {
- s = strstr(p->declarator, p->name);
- *s = '\0';
- printf("%s %s/*%s*/%s", p->decl_spec, p->declarator, p->name,
- s+strlen(p->name));
- *s = *(p->name);
- } else {
- printf("%s %s", p->decl_spec, p->declarator);
- }
- }
-
- /* Output the list of function parameters.
- */
- static void
- output_parameters (params)
- ParameterList *params;
- {
- Parameter *p;
-
- if (proto_style == 0)
- printf("/*");
-
- p = params->first;
- if (p == NULL) {
- printf("void");
- } else {
- output_parameter(p);
- p = p->next;
- while (p != NULL) {
- printf(", ");
- output_parameter(p);
- p = p->next;
- }
- }
-
- if (proto_style == 0)
- printf("*/");
- }
-
- /* Output a declarator.
- */
- static void
- output_declarator (d)
- Declarator *d;
- {
- char *s;
-
- if (d->func_def == FUNC_DEF_NONE) {
- printf("%s", d->text);
- } else {
- if ((s = strstr(d->text, "%s")) != NULL) {
- *s = '\0';
- printf("%s", d->text);
- output_parameters(&(d->params));
- printf("%s", s+2);
- *s = '%';
- }
- }
- }
-
- /* Output variable declarations.
- */
- void
- output_declarations (decl_spec, decl_list)
- DeclSpec *decl_spec; /* declaration specifier */
- DeclaratorList *decl_list; /* list of declared variables */
- {
- Declarator *d;
-
- if (variables_out == FALSE)
- return;
- if (globals_only && (decl_spec->flags & DE_STATIC))
- return;
-
- for (d = decl_list->first; d != NULL; d = d->next) {
- if (d->func_def == FUNC_DEF_NONE) {
- if (strstr(decl_spec->text, "extern") == NULL) {
- output_decl_spec(decl_spec);
- output_declarator(d);
- printf(";\n");
- }
- }
- }
- }
-
- /* Output the prototype for the function definition.
- */
- void
- output_prototype (decl_spec, declarator)
- DeclSpec *decl_spec;
- Declarator *declarator;
- {
- Parameter *p;
-
- if (globals_only && (decl_spec->flags & DE_STATIC))
- return;
-
- /* Check for function parameters for which no type has been specified.
- * This happens when a parameter name appears in the function
- * declaration but does not appear in the parameter declaration part.
- * The default type in this cause is "int".
- */
- for (p = declarator->params.first; p != NULL; p = p->next) {
- if (p->decl_spec == NULL) {
- p->decl_spec = strdup("int");
- p->declarator = strdup(p->name);
- }
- }
-
- output_decl_spec(decl_spec);
- output_declarator(declarator);
- printf(";\n");
- }
- @//E*O*F semantics.c//
- chmod u=rw,g=r,o=r semantics.c
-
- echo x - string.c
- sed 's/^@//' > "string.c" <<'@//E*O*F string.c//'
- /*
- * $Header: string.c,v 1.1 89/03/14 20:59:24 cthuang Exp $
- *
- * Some are string handling routines
- */
- #include <stdio.h>
- #include <strings.h>
-
- extern char *malloc();
-
- /* Copy the string into an allocated memory block.
- * Return a pointer to the copy.
- */
- char *
- strdup (s)
- char *s;
- {
- char *dest;
-
- if ((dest = malloc((unsigned)(strlen(s)+1))) != NULL)
- strcpy(dest, s);
- return dest;
- }
-
- /* Return a pointer to the first occurence of the substring
- * within the string, or NULL if not found.
- */
- char *
- strstr (src, key)
- char *src, *key;
- {
- char *s;
- int keylen;
-
- keylen = strlen(key);
- s = index(src, *key);
- while (s != NULL) {
- if (strncmp(s, key, keylen) == 0)
- return s;
- s = index(s+1, *key);
- }
- return NULL;
- }
- @//E*O*F string.c//
- chmod u=rw,g=r,o=r string.c
-
- echo x - symbol.c
- sed 's/^@//' > "symbol.c" <<'@//E*O*F symbol.c//'
- /*
- * $Header: symbol.c,v 1.1 89/03/14 20:59:26 cthuang Exp $
- *
- * Symbol table maintenance. Implements an abstract data type called
- * the symbol table.
- */
- #include <stdio.h>
- #include <strings.h>
- #include "symbol.h"
-
- extern char *malloc();
-
- /* Create a symbol table.
- * Return a pointer to the symbol table or NULL if an error occurs.
- */
- SymbolTable *
- create_symbol_table ()
- {
- SymbolTable *symtab;
- int i;
-
- if ((symtab = (SymbolTable *)malloc(sizeof(SymbolTable))) != NULL) {
- for (i = 0; i < SYM_MAX_HASH; ++i)
- symtab->bucket[i] = NULL;
- }
- return symtab;
- }
-
-
- /* This is a simple hash function mapping a symbol name to a hash bucket. */
-
- static int
- hash (name)
- char *name;
- {
- return (name[0] + name[1] + strlen(name)) % SYM_MAX_HASH;
- }
-
-
- /* Search the list of symbols <list> for the symbol <name>.
- * Return a pointer to the symbol or NULL if not found.
- */
- static Symbol *
- search_symbol_list (list, name)
- Symbol *list;
- char *name;
- {
- Symbol *sym;
-
- for (sym = list; sym != NULL; sym = sym->next) {
- if (strncmp(sym->name, name, SYM_MAX_LENGTH-1) == 0)
- return sym;
- }
- return NULL;
- }
-
-
- /* Look for symbol <name> in symbol table <symtab>.
- * Return a pointer to the symbol or NULL if not found.
- */
- Symbol *
- find_symbol (symtab, name)
- SymbolTable *symtab;
- char *name;
- {
- return search_symbol_list(symtab->bucket[hash(name)], name);
- }
-
-
- /* If the symbol <name> does not already exist in symbol table <symtab>,
- * then add the symbol to the symbol table.
- * Return a pointer to the symbol or NULL on an error.
- */
- Symbol *
- new_symbol (symtab, name)
- SymbolTable *symtab; /* symbol table */
- char *name; /* symbol name */
- {
- Symbol *sym;
- int i;
-
- if ((sym = find_symbol(symtab, name)) == NULL) {
- if ((sym = (Symbol *)malloc(sizeof(Symbol))) != NULL) {
- strncpy(sym->name, name, SYM_MAX_LENGTH-1);
- sym->name[SYM_MAX_LENGTH-1] = '\0';
-
- i = hash(name);
- sym->next = symtab->bucket[i];
- symtab->bucket[i] = sym;
- }
- }
- return sym;
- }
- @//E*O*F symbol.c//
- chmod u=rw,g=r,o= symbol.c
-
- echo Inspecting for damage in transit...
- temp=/tmp/shar$$; dtemp=/tmp/.shar$$
- trap "rm -f $temp $dtemp; exit" 0 1 2 3 15
- cat > $temp <<\!!!
- 9 50 344 README
- 43 110 826 Makefile
- 105 402 2247 cproto.1
- 20 32 264 cproto.sh
- 432 939 7877 grammar.y
- 103 263 1946 lex.l
- 86 373 2616 cproto.h
- 1 3 21 patchlevel.h
- 32 75 707 semantics.h
- 28 98 673 symbol.h
- 88 272 1827 cproto1.c
- 466 1296 9642 semantics.c
- 43 124 759 string.c
- 93 308 2014 symbol.c
- 1549 4345 31763 total
- !!!
- wc README Makefile cproto.1 cproto.sh grammar.y lex.l cproto.h patchlevel.h semantics.h symbol.h cproto1.c semantics.c string.c symbol.c | sed 's=[^ ]*/==' | diff -b $temp - >$dtemp
- if [ -s $dtemp ]
- then echo "Ouch [diff of wc output]:" ; cat $dtemp
- else echo "No problems found."
- fi
- exit 0
- --
- cthuang@watdragon.uwaterloo.ca
- cthuang@watdragon.waterloo.edu
- cthuang@watdragon.waterloo.cdn
- {uunet,utzoo}!watmath!watdragon!cthuang
-
- --
- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
- Use a domain-based address or give alternate paths, or you may lose out.
-