[comp.sources.misc] v17i071: cproto - Generate C function prototypes from C source, Part02/02

cthuang@contact.UUCP (Chin Huang) (03/26/91)

Submitted-by: Chin Huang <cthuang@contact.UUCP>
Posting-number: Volume 17, Issue 71
Archive-name: cproto/part02

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  lex.l grammar.y config.h cproto.h patchlev.h semantic.h
#   symbol.h cproto.c semantic.c string.c symbol.c
# Wrapped by ibmpc@laphroig.UUCP on Mon Mar 25 11:41:06 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f lex.l -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"lex.l\"
else
echo shar: Extracting \"lex.l\" \(4859 characters\)
sed "s/^X//" >lex.l <<'END_OF_lex.l'
X%{
X/* $Id: lex.l 2.1 91/03/25 11:40:27 cthuang Exp $
X *
X * C function prototype generator
X * Lexical analyzer specification
X */
X%}
X
XWS		[ \t]
XWLF		[ \t\n\f]*
XLETTER		[A-Za-z_]
XDIGIT		[0-9]
XID		{LETTER}({LETTER}|{DIGIT})*
XQUOTED		(\"(\\\"|[^"\n])*\"|\'.\'|\\.)
X
X%{
Xchar cur_file[MAX_TEXT_LENGTH];	/* current file name */
Xint line_num = 1;		/* current line number in file */
Xstatic int curly = 0;		/* number of curly brace nesting levels */
X
Xtypedef struct {
X    FILE *fp;
X    char *file;
X    int line_num;
X} IncludeStack;
X
Xstatic int inc_depth = 0;			/* include nesting level */
Xstatic IncludeStack inc_stack[MAX_INC_DEPTH];	/* stack of included files */
Xstatic void do_include();
X%}
X
X%s CPP1 CPP2 INIT1 INIT2 CURLY COMMENT
X%%
X
X\n			++line_num;
X
X<INITIAL>^#{WS}*	BEGIN CPP1;
X<CPP1>define{WS}+{ID}.*\\$	{
X			    sscanf(yytext, "define %s", buf);
X			    new_symbol(typedef_names, buf);
X			    BEGIN CPP2;
X			}
X<CPP1>define{WS}+{ID}.*$	{
X			    sscanf(yytext, "define %s", buf);
X			    new_symbol(typedef_names, buf);
X			    BEGIN INITIAL;
X			}
X<CPP2>.*\\$		;
X<CPP2>.*$		BEGIN INITIAL;
X
X<CPP1>include{WS}+\"[^"]+\".*$	{
X			    sscanf(yytext, "include \"%[^\"]\"", buf);
X			    do_include(buf, 0);
X			    BEGIN INITIAL;
X			}
X<CPP1>include{WS}+\<[^>]+\>.*$	{
X			    sscanf(yytext, "include <%[^>]>", buf);
X			    do_include(buf, 1);
X			    BEGIN INITIAL;
X			}
X
X<CPP1>[0-9]+{WS}+\".*$	{
X			    sscanf(yytext, "%d \"%[^\"]\"", &line_num,
X			     cur_file);
X			    --line_num;
X			    BEGIN INITIAL;
X			}
X<CPP1>[0-9]+.*$		{
X			    sscanf(yytext, "%d ", &line_num);
X			    --line_num;
X			    BEGIN INITIAL;
X			}
X
X<CPP1>.*$		BEGIN INITIAL;
X
X<INITIAL>"("		return '(';
X<INITIAL>")"		return ')';
X<INITIAL>"*"		return '*';
X<INITIAL>","		return ',';
X<INITIAL>";"		return ';';
X<INITIAL>"..."		return T_ELLIPSIS;
X
X<INITIAL>auto		return T_AUTO;
X<INITIAL>extern		return T_EXTERN;
X<INITIAL>register	return T_REGISTER;
X<INITIAL>static		return T_STATIC;
X<INITIAL>typedef	return T_TYPEDEF;
X<INITIAL>char		return T_CHAR;
X<INITIAL>double		return T_DOUBLE;
X<INITIAL>float		return T_FLOAT;
X<INITIAL>int		return T_INT;
X<INITIAL>void		return T_VOID;
X<INITIAL>long		return T_LONG;
X<INITIAL>short		return T_SHORT;
X<INITIAL>signed		return T_SIGNED;
X<INITIAL>unsigned	return T_UNSIGNED;
X<INITIAL>enum		return T_ENUM;
X<INITIAL>struct		return T_STRUCT;
X<INITIAL>union		return T_UNION;
X<INITIAL>const		return T_CONST;
X<INITIAL>volatile	return T_VOLATILE;
X<INITIAL>inline		return T_INLINE;
X<INITIAL>\"C\"		return T_QUOTEC;
X<INITIAL>cdecl		return T_CDECL;
X<INITIAL>far		return T_FAR;
X<INITIAL>huge		return T_HUGE;
X<INITIAL>interrupt	return T_INTERRUPT;
X<INITIAL>near		return T_NEAR;
X<INITIAL>pascal		return T_PASCAL;
X
X<INITIAL>\[[^\]]*\]	{
X			    strcpy(yylval.text, yytext);
X			    return T_BRACKETS;
X			}
X
X<INITIAL>{ID}		{
X			    strcpy(yylval.text, yytext);
X			    if (is_typedef_name(yytext))
X				return T_TYPEDEF_NAME;
X			    else
X				return T_IDENTIFIER;
X			}
X
X<INITIAL>"="{WLF}"{"	{
X			    int i;
X
X			    curly = 1;
X			    BEGIN INIT1;
X			    for (i = 0; i < yyleng; ++i)
X				if (yytext[i] == '\n') ++line_num;
X			}
X<INIT1>"{"		++curly;
X<INIT1>"}"		{
X			    if (--curly == 0) {
X				BEGIN INITIAL;
X				return T_INITIALIZER;
X			    }
X			}
X<INIT1>{QUOTED}|.	;
X
X<INITIAL>"="		BEGIN INIT2;
X<INIT2>[,;]		{
X			    unput(yytext[yyleng-1]);
X			    BEGIN INITIAL;
X			    return T_INITIALIZER;
X			}
X<INIT2>{QUOTED}|.	;
X
X<INITIAL>"{"		{ curly = 1; BEGIN CURLY; }
X<CURLY>"{"		++curly;
X<CURLY>"}"		{
X			    if (--curly == 0) {
X				BEGIN INITIAL;
X				return T_BRACES;
X			    }
X			}
X<CURLY>{QUOTED}|.	;
X
X<INITIAL>"/*"		BEGIN COMMENT;
X<COMMENT>"*/"		BEGIN INITIAL;
X<COMMENT>.		;
X
X<INITIAL>"//".*$	;
X
X[ \t\f]+		;
X.			{
X			    output_error();
X			    fprintf(stderr, "bad character '%c'\n", yytext[0]);
X			}
X%%
X
X/* Process include directive.
X */
Xstatic void
Xdo_include (filename, sysinc)
Xchar *filename;		/* file name */
Xint sysinc;		/* 1 = do not search current directory */
X{
X    char path[MAX_TEXT_LENGTH];
X    int i;
X    FILE *fp;
X    IncludeStack *sp;
X
X    if (inc_depth >= MAX_INC_DEPTH) {
X	output_error();
X	fprintf(stderr, "includes too deeply nested\n");
X	return;
X    }
X
X    for (i = sysinc != 0; i < num_inc_dir; ++i) {
X	 strcpy(path, inc_dir[i]);
X	 strcat(path, filename);
X	 if ((fp = fopen(path, "r")) != NULL) {
X	     sp = inc_stack + inc_depth;
X	     sp->fp = yyin;
X	     sp->file = strdup(cur_file);
X	     sp->line_num = line_num;
X	     ++inc_depth;
X	     yyin = fp;
X	     strcpy(cur_file, filename);
X	     line_num = 0;
X	     return;
X	 }
X    }
X}
X
X/* When the end of the current input file is reached, pop any
X * nested includes.
X */
Xstatic int
Xyywrap ()
X{
X    IncludeStack *sp;
X
X    if (inc_depth > 0) {
X	--inc_depth;
X	sp = inc_stack + inc_depth;
X	fclose(yyin);
X	yyin = sp->fp;
X	strcpy(cur_file, sp->file);
X	free(sp->file);
X	line_num = sp->line_num + 1;
X	return 0;
X    } else {
X	return 1;
X    }
X}
END_OF_lex.l
if test 4859 -ne `wc -c <lex.l`; then
    echo shar: \"lex.l\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f grammar.y -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"grammar.y\"
else
echo shar: Extracting \"grammar.y\" \(10073 characters\)
sed "s/^X//" >grammar.y <<'END_OF_grammar.y'
X/* $Id: grammar.y 2.1 91/02/28 11:16:07 cthuang Exp $
X *
X * yacc grammar for C prototype generator
X * This was derived from the grammar given in Appendix A of
X * "The C Programming Language" by Kernighan and Ritchie.
X */
X
X/* identifiers that are not reserved words */
X%token T_IDENTIFIER T_TYPEDEF_NAME
X
X/* storage class */
X%token T_AUTO T_EXTERN T_REGISTER T_STATIC T_TYPEDEF
X/* This keyword included for compatibility with C++. */
X%token T_INLINE
X
X/* type specifiers */
X%token T_CHAR T_DOUBLE T_FLOAT T_INT T_VOID
X%token T_LONG T_SHORT T_SIGNED T_UNSIGNED
X%token T_ENUM T_STRUCT T_UNION
X
X/* type qualifiers */
X%token T_CONST T_VOLATILE
X/* These keywords included for compatibility with MSDOS C compilers. */
X%token T_CDECL T_FAR T_HUGE T_INTERRUPT T_NEAR T_PASCAL
X
X/* paired braces and everything between them: { ... } */
X%token T_BRACES
X
X/* paired square brackets and everything between them: [ ... ] */
X%token T_BRACKETS
X
X/* three periods */
X%token T_ELLIPSIS
X
X/* equal sign followed by constant expression or stuff between braces */
X%token T_INITIALIZER
X
X/* "C" */
X%token T_QUOTEC
X
X%type <decl_spec> declaration_specifiers declaration_specifier
X%type <decl_spec> storage_class type_specifier type_qualifier
X%type <decl_spec> struct_or_union_specifier enum_specifier
X%type <decl_list> init_declarator_list
X%type <declarator> init_declarator declarator direct_declarator
X%type <declarator> abs_declarator direct_abs_declarator
X%type <param_list> parameter_type_list parameter_list
X%type <parameter> parameter_declaration
X%type <param_list> opt_identifier_list identifier_list
X%type <text> struct_or_union
X%type <text> pointer type_qualifiers
X%type <text> any_id T_IDENTIFIER T_TYPEDEF_NAME
X%type <text> T_BRACKETS
X
X%{
X#include <stdio.h>
X#include "cproto.h"
X#include "semantic.h"
X
X#define YYMAXDEPTH 150
X
X/* This variable is set TRUE when we are scanning the parameter declarations
X * part of a function definition.
X */
Xstatic boolean func_params = FALSE;
X
X/* This points to the list of parameters for the current function definition. */
Xstatic ParameterList *cur_params;
X
X/* temporary string buffer */
Xstatic char buf[MAX_TEXT_LENGTH];
X
X/* Table of typedef names */
XSymbolTable *typedef_names;
X%}
X%%
X
Xprogram
X	: /* empty */
X	| translation_unit
X	;
X
Xtranslation_unit
X	: external_declaration
X	| translation_unit external_declaration
X	;
X
Xexternal_declaration
X	: declaration
X	| function_definition
X	| T_EXTERN T_QUOTEC T_BRACES
X	| error
X	;
X
Xdeclaration
X	: declaration_specifiers ';'
X	{
X	    free_decl_spec(&$1);
X	}
X	| declaration_specifiers init_declarator_list ';'
X	{
X	    if (func_params) {
X		set_param_types(cur_params, &$1, &$2);
X	    } else {
X		output_declarations(&$1, &$2);
X	    }
X	    free_decl_spec(&$1);
X	    free_decl_list(&$2);
X	}
X	| T_TYPEDEF declaration_specifiers declarator_list ';'
X	{
X	    free_decl_spec(&$2);
X	}
X	;
X
Xdeclarator_list
X	: declarator
X	{
X	    new_symbol(typedef_names, $1.name);
X	    free_declarator(&$1);
X	}
X	| declarator_list ',' declarator
X	{
X	    new_symbol(typedef_names, $3.name);
X	    free_declarator(&$3);
X	}
X	;
X
Xfunction_definition
X	: declaration_specifiers declarator
X	{
X	    if ($2.func_def == FUNC_NONE) {
X		yyerror("syntax error");
X		YYERROR;
X	    }
X	    cur_params = &($2.params);
X	    func_params = TRUE;
X	}
X	  opt_declaration_list T_BRACES
X	{
X	    func_params = FALSE;
X
X	    output_prototype(&$1, &$2);
X	    free_decl_spec(&$1);
X	    free_declarator(&$2);
X	}
X	| declarator
X	{
X	    if ($1.func_def == FUNC_NONE) {
X		yyerror("syntax error");
X		YYERROR;
X	    }
X	    cur_params = &($1.params);
X	    func_params = TRUE;
X	}
X	  opt_declaration_list T_BRACES
X	{
X	    DeclSpec	decl_spec;
X
X	    func_params = FALSE;
X
X	    new_decl_spec(&decl_spec, "int", DE_EXTERN);
X	    output_prototype(&decl_spec, &$1);
X	    free_decl_spec(&decl_spec);
X	    free_declarator(&$1);
X	}
X	;
X
Xopt_declaration_list
X	: /* empty */
X	| declaration_list
X	;
X
Xdeclaration_list
X	: declaration
X	| declaration_list declaration
X	;
X
Xdeclaration_specifiers
X	: declaration_specifier
X	| declaration_specifiers declaration_specifier
X	{
X	    join_decl_specs(&$$, &$1, &$2);
X	}
X	;
X
Xdeclaration_specifier
X	: storage_class
X	| type_specifier
X	| type_qualifier
X	;
X
Xstorage_class
X	: T_AUTO
X	{
X	    new_decl_spec(&$$, "auto", DE_JUNK);
X	}
X	| T_EXTERN
X	{
X	    new_decl_spec(&$$, "extern", DE_JUNK);
X	}
X	| T_REGISTER
X	{
X	    new_decl_spec(&$$, "register", DE_JUNK);
X	}
X	| T_STATIC
X	{
X	    new_decl_spec(&$$, "static", DE_STATIC);
X	}
X	| T_INLINE
X	{
X	    new_decl_spec(&$$, "inline", DE_JUNK);
X	}
X	;
X
Xtype_specifier
X	: T_CHAR
X	{
X	    new_decl_spec(&$$, "char", DE_EXTERN);
X	}
X	| T_DOUBLE
X	{
X	    new_decl_spec(&$$, "double", DE_EXTERN);
X	}
X	| T_FLOAT
X	{
X	    new_decl_spec(&$$, "float", DE_EXTERN);
X	}
X	| T_INT
X	{
X	    new_decl_spec(&$$, "int", DE_EXTERN);
X	}
X	| T_LONG
X	{
X	    new_decl_spec(&$$, "long", DE_EXTERN);
X	}
X	| T_SHORT
X	{
X	    new_decl_spec(&$$, "short", DE_EXTERN);
X	}
X	| T_SIGNED
X	{
X	    new_decl_spec(&$$, "signed", DE_EXTERN);
X	}
X	| T_UNSIGNED
X	{
X	    new_decl_spec(&$$, "unsigned", DE_EXTERN);
X	}
X	| T_VOID
X	{
X	    new_decl_spec(&$$, "void", DE_EXTERN);
X	}
X	| struct_or_union_specifier
X	| enum_specifier
X	| T_TYPEDEF_NAME
X	{
X	    new_decl_spec(&$$, $1, DE_EXTERN);
X	}
X	;
X
Xtype_qualifier
X	: T_CONST
X	{
X	    new_decl_spec(&$$, "const", DE_EXTERN);
X	}
X	| T_VOLATILE
X	{
X	    new_decl_spec(&$$, "volatile", DE_EXTERN);
X	}
X	| T_CDECL
X	{
X	    new_decl_spec(&$$, "cdecl", DE_EXTERN);
X	}
X	| T_INTERRUPT
X	{
X	    new_decl_spec(&$$, "interrupt", DE_EXTERN);
X	}
X	| T_FAR
X	{
X	    new_decl_spec(&$$, "far", DE_EXTERN);
X	}
X	| T_HUGE
X	{
X	    new_decl_spec(&$$, "huge", DE_EXTERN);
X	}
X	| T_NEAR
X	{
X	    new_decl_spec(&$$, "near", DE_EXTERN);
X	}
X	| T_PASCAL
X	{
X	    new_decl_spec(&$$, "pascal", DE_EXTERN);
X	}
X	;
X
Xstruct_or_union_specifier
X	: struct_or_union any_id T_BRACES
X	{
X	    sprintf(buf, "%s %s {}", $1, $2);
X	    new_decl_spec(&$$, buf, DE_EXTERN);
X	}
X	| struct_or_union T_BRACES
X	{
X	    sprintf(buf, "%s {}", $1);
X	    new_decl_spec(&$$, buf, DE_EXTERN);
X	}
X	| struct_or_union any_id
X	{
X	    sprintf(buf, "%s %s", $1, $2);
X	    new_decl_spec(&$$, buf, DE_EXTERN);
X	}
X	;
X
Xstruct_or_union
X	: T_STRUCT
X	{
X	    strcpy($$, "struct");
X	}
X	| T_UNION
X	{
X	    strcpy($$, "union");
X	}
X	;
X
Xinit_declarator_list
X	: init_declarator
X	{
X	    new_decl_list(&$$, &$1);
X	}
X	| init_declarator_list ',' init_declarator
X	{
X	    add_decl_list(&$$, &$1, &$3);
X	}
X	;
X
Xinit_declarator
X	: declarator
X	| declarator T_INITIALIZER
X	;
X
Xenum_specifier
X	: T_ENUM any_id T_BRACES
X	{
X	    sprintf(buf, "enum %s {}", $2);
X	    new_decl_spec(&$$, buf, DE_EXTERN);
X	}
X	| T_ENUM T_BRACES
X	{
X	    new_decl_spec(&$$, "enum {}", DE_EXTERN);
X	}
X	| T_ENUM any_id
X	{
X	    sprintf(buf, "enum %s", $2);
X	    new_decl_spec(&$$, buf, DE_EXTERN);
X	}
X	;
X
Xany_id
X	: T_IDENTIFIER
X	| T_TYPEDEF_NAME
X	;
X
Xdeclarator
X	: pointer direct_declarator
X	{
X	    sprintf(buf, "%s%s", $1, $2.text);
X	    $$ = $2;
X	    $$.text = strdup(buf);
X	    free($2.text);
X	}
X	| direct_declarator
X	;
X
Xdirect_declarator
X	: T_IDENTIFIER
X	{
X	    new_declarator(&$$, $1, $1);
X	}
X	| '(' declarator ')'
X	{
X	    sprintf(buf, "(%s)", $2.text);
X	    $$ = $2;
X	    $$.text = strdup(buf);
X	    free($2.text);
X	}
X	| direct_declarator T_BRACKETS
X	{
X	    sprintf(buf, "%s%s", $1.text, $2);
X	    $$ = $1;
X	    $$.text = strdup(buf);
X	    free($1.text);
X	}
X	| direct_declarator '(' parameter_type_list ')'
X	{
X	    sprintf(buf, "%s()", $1.text);
X	    $$ = $1;
X	    $$.text = strdup(buf);
X	    $$.func_def = FUNC_ANSI;
X	    $$.params = $3;
X	    free($1.text);
X	}
X	| direct_declarator '(' opt_identifier_list ')'
X	{
X	    sprintf(buf, "%s()", $1.text);
X	    $$ = $1;
X	    $$.text = strdup(buf);
X	    $$.func_def = FUNC_TRADITIONAL;
X	    if ($3.first != NULL) {
X		$$.params = $3;
X	    }
X	    free($1.text);
X	}
X	;
X
Xpointer
X	: '*' type_qualifiers
X	{
X	    sprintf($$, "*%s", $2);
X	}
X	| '*' type_qualifiers pointer
X	{
X	    sprintf($$, "*%s%s", $2, $3);
X	}
X	;
X
Xtype_qualifiers
X	: /* empty */
X	{
X	    strcpy($$, "");
X	}
X	| type_qualifiers type_qualifier
X	{
X	    sprintf($$, "%s %s ", $1, $2.text);
X	    free($2.text);
X	}
X	;
X
Xparameter_type_list
X	: parameter_list
X	| parameter_list ',' T_ELLIPSIS
X	{
X	    add_ident_list(&$$, &$1, "...");
X	}
X	;
X
Xparameter_list
X	: parameter_declaration
X	{
X	    new_param_list(&$$, &$1);
X	}
X	| parameter_list ',' parameter_declaration
X	{
X	    add_param_list(&$$, &$1, &$3);
X	}
X	;
X
Xparameter_declaration
X	: declaration_specifiers declarator
X	{
X	    new_parameter(&$$, &$1, &$2);
X	}
X	| declaration_specifiers abs_declarator
X	{
X	    new_parameter(&$$, &$1, &$2);
X	}
X	| declaration_specifiers
X	{
X	    new_parameter(&$$, &$1, NULL);
X	}
X	;
X
Xopt_identifier_list
X	: /* empty */
X	{
X	    new_ident_list(&$$);
X	}
X	| identifier_list
X	;
X
Xidentifier_list
X	: T_IDENTIFIER
X	{
X	    new_ident_list(&$$);
X	    add_ident_list(&$$, &$$, $1);
X	}
X	| identifier_list ',' T_IDENTIFIER
X	{
X	    add_ident_list(&$$, &$1, $3);
X	}
X	;
X
Xabs_declarator
X	: pointer
X	{
X	    new_declarator(&$$, $1, "");
X	}
X	| pointer direct_abs_declarator
X	{
X	    sprintf(buf, "%s%s", $1, $2.text);
X	    $$ = $2;
X	    $$.text = strdup(buf);
X	    free($2.text);
X	}
X	| direct_abs_declarator
X	;
X
Xdirect_abs_declarator
X	: '(' abs_declarator ')'
X	{
X	    sprintf(buf, "(%s)", $2.text);
X	    $$ = $2;
X	    $$.text = strdup(buf);
X	    free($2.text);
X	}
X	| direct_abs_declarator T_BRACKETS
X	{
X	    sprintf(buf, "%s%s", $1.text, $2);
X	    $$ = $1;
X	    $$.text = strdup(buf);
X	    free($1.text);
X	}
X	| T_BRACKETS
X	{
X	    new_declarator(&$$, $1, "");
X	}
X	| direct_abs_declarator '(' parameter_type_list ')'
X	{
X	    sprintf(buf, "%s(%%s)", $1.text);
X	    $$ = $1;
X	    $$.text = strdup(buf);
X	    free($1.text);
X	}
X	| direct_abs_declarator '(' ')'
X	{
X	    sprintf(buf, "%s()", $1.text);
X	    $$ = $1;
X	    $$.text = strdup(buf);
X	    free($1.text);
X	}
X	| '(' parameter_type_list ')'
X	{
X	    new_declarator(&$$, "()", "");
X	}
X	| '(' ')'
X	{
X	    new_declarator(&$$, "()", "");
X	}
X	;
X
X%%
X#ifdef MSDOS
X#include "lex_yy.c"
X#else
X#include "lex.yy.c"
X#endif
X
Xyyerror (msg)
Xchar *msg;
X{
X    output_error();
X    fprintf(stderr, "%s\n", msg);
X}
X
Xvoid
Xparse_file ()
X{
X    typedef_names = create_symbol_table();
X    yyparse();
X}
END_OF_grammar.y
if test 10073 -ne `wc -c <grammar.y`; then
    echo shar: \"grammar.y\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f config.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"config.h\"
else
echo shar: Extracting \"config.h\" \(640 characters\)
sed "s/^X//" >config.h <<'END_OF_config.h'
X/* $Id: config.h 2.1 91/02/28 11:16:12 cthuang Exp $
X *
X * cproto configuration and system dependencies
X */
X
X/* maximum include file nesting */
X#define MAX_INC_DEPTH 15
X
X/* maximum number of include directories */
X#define MAX_INC_DIR 15
X
X/* maximum number of characters in a text buffer */
X#define MAX_TEXT_LENGTH	256
X
X#ifdef __TURBOC__
X#include <alloc.h>
X#endif
X
X#ifdef M_I86
X#include <malloc.h>
X#endif
X
X#ifndef MSDOS
Xextern char *malloc();
X#endif
X
X#if defined(SYSV) || defined(MSDOS)
X#include <string.h>
X#define index strchr
X#define rindex strrchr
X#else
X#include <strings.h>
X#endif
X
X#ifndef MSDOS
Xextern char *strdup(), *strstr();
X#endif
END_OF_config.h
if test 640 -ne `wc -c <config.h`; then
    echo shar: \"config.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f cproto.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"cproto.h\"
else
echo shar: Extracting \"cproto.h\" \(2851 characters\)
sed "s/^X//" >cproto.h <<'END_OF_cproto.h'
X/* $Id: cproto.h 2.1 91/02/28 11:16:14 cthuang Exp $
X *
X * Definitions for C language prototype generator
X */
X#include "config.h"
X#include "symbol.h"
X
X/* Boolean type */
Xtypedef char boolean;
X#define FALSE	0
X#define TRUE	1
X
X/* This is a list of function parameters. */
Xtypedef struct _parameter_list {
X    struct _parameter	*first;	/* pointer to first parameter in list */
X    struct _parameter	*last;  /* pointer to last parameter in list */  
X} ParameterList;
X
X/* Declaration specifier flags */
X#define DE_EXTERN	0	/* default: external declaration */
X#define DE_STATIC	1	/* visible only in current file */
X#define DE_JUNK		2	/* we're not interested in this declaration */
X
X/* This structure stores information about a declaration specifier. */
Xtypedef struct _decl_spec {
X    unsigned short	flags;	/* flags defined above */
X    char		*text;	/* source text */
X} DeclSpec;
X
X/* Styles of function definitions */
Xtypedef enum {
X    FUNC_NONE,		/* not a function definition */
X    FUNC_TRADITIONAL,	/* traditional style */
X    FUNC_ANSI		/* ANSI style */
X} FuncDefType;
X
X/* This structure stores information about a declarator. */
Xtypedef struct _declarator {
X    char		*name;		/* name of variable or function */
X    char		*text;		/* source text */
X    FuncDefType		func_def;	/* style of function definition */
X    ParameterList	params;		/* function parameters */
X    struct _declarator	*next;		/* next declarator in list */
X} Declarator;
X
X/* This is a list of declarators. */
Xtypedef struct _declarator_list {
X    Declarator		*first;	/* pointer to first declarator in list */
X    Declarator		*last;  /* pointer to last declarator in list */  
X} DeclaratorList;
X
X/* This structure stores information about a function parameter. */
Xtypedef struct _parameter {
X    DeclSpec		decl_spec;
X    Declarator		declarator;
X    struct _parameter	*next;		/* next parameter in list */
X} Parameter;
X
X/* parser stack entry type */
Xtypedef union {
X    char		text[MAX_TEXT_LENGTH];
X    DeclSpec		decl_spec;
X    Parameter		parameter;
X    ParameterList	param_list;
X    Declarator		declarator;
X    DeclaratorList	decl_list;
X} yystype;
X
X#define YYSTYPE yystype
X
X/* Prototype styles */
X#define PROTO_NONE		0
X#define PROTO_TRADITIONAL	1
X#define PROTO_ABSTRACT		2
X#define PROTO_ANSI		3
X#define PROTO_MACRO		4
X
X/* Program options */
Xextern boolean extern_out;
Xextern boolean static_out;
Xextern boolean variables_out;
Xextern boolean promote_param;
Xextern int proto_style;
Xextern boolean define_macro;
Xextern char *macro_name;
Xextern char *decl_spec_prefix, *declarator_prefix, *declarator_suffix;
Xextern char *first_param_prefix, *middle_param_prefix, *last_param_suffix;
Xextern int num_inc_dir;
Xextern char *inc_dir[];
X
X/* Global declarations */
Xextern int line_num;
Xextern char cur_file[];
Xextern SymbolTable *typedef_names;
Xextern void output_error();
Xextern void parse_file();
END_OF_cproto.h
if test 2851 -ne `wc -c <cproto.h`; then
    echo shar: \"cproto.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f patchlev.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"patchlev.h\"
else
echo shar: Extracting \"patchlev.h\" \(21 characters\)
sed "s/^X//" >patchlev.h <<'END_OF_patchlev.h'
X#define PATCHLEVEL 0
END_OF_patchlev.h
if test 21 -ne `wc -c <patchlev.h`; then
    echo shar: \"patchlev.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f semantic.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"semantic.h\"
else
echo shar: Extracting \"semantic.h\" \(1610 characters\)
sed "s/^X//" >semantic.h <<'END_OF_semantic.h'
X/* $Id: semantic.h 2.1 91/02/28 11:16:19 cthuang Exp $
X *
X * Declarations for semantics action routines
X */
X
Xextern boolean is_typedef_name(/*
X	char *name
X	*/);
Xextern void new_decl_spec(/*
X	DeclSpec *decl_spec,
X	char *text,
X	unsigned short flags
X	*/);
Xextern void join_decl_specs(/*
X	DeclSpec *result,
X	DeclSpec *a,
X	DeclSpec *b
X	*/);
Xextern void free_decl_spec(/*
X	DeclSpec *decl_spec
X	*/);
Xextern void new_parameter(/*
X	Parameter *param,
X	DeclSpec *decl_spec,
X	Declarator *declarator
X	*/);
Xextern void free_parameter(/*
X	Parameter *param
X	*/);
Xextern void new_param_list(/*
X	ParameterList *param_list,
X	Parameter *param
X	*/);
Xextern void add_param_list(/*
X	ParameterList *to,
X	ParameterList *from,
X	Parameter *param
X	*/);
Xextern void free_param_list(/*
X	ParameterList *param_list
X	*/);
Xextern void new_ident_list(/*
X	ParameterList *param_list
X	*/);
Xextern void add_ident_list(/*
X	ParameterList *to,
X	ParameterList *from,
X	char *name
X	*/);
Xextern void new_declarator(/*
X	Declarator *d,
X	char *name,
X	char *text
X	*/);
Xextern void free_declarator(/*
X	Declarator *d
X	*/);
Xextern void new_decl_list(/*
X	DeclaratorList *decl_list,
X	Declarator *declarator
X	*/);
Xextern void add_decl_list(/*
X	DeclaratorList *to,
X	DeclaratorList *from,
X	Declarator *declarator
X	*/);
Xextern void free_decl_list(/*
X	DeclaratorList *decl_list
X	*/);
Xextern void set_param_types(/*
X	ParameterList *params,
X	DeclSpec *decl_spec,
X	DeclaratorList *declarators
X	*/);
Xextern void output_declarations(/*
X	DeclSpec *decl_spec,
X	DeclaratorList *decl_list
X	*/);
Xextern void output_prototype(/*
X	DeclSpec *decl_spec,
X	Declarator *declarator
X	*/);
END_OF_semantic.h
if test 1610 -ne `wc -c <semantic.h`; then
    echo shar: \"semantic.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f symbol.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"symbol.h\"
else
echo shar: Extracting \"symbol.h\" \(587 characters\)
sed "s/^X//" >symbol.h <<'END_OF_symbol.h'
X/* $Id: symbol.h 2.1 91/02/28 11:16:22 cthuang Exp $
X *
X * Definitions for a symbol table
X */
X#ifndef _SYMBOL_H
X#define _SYMBOL_H
X
Xtypedef struct _symbol {
X	struct _symbol *next;	/* next symbol in list */
X	char *name;		/* name of symbol */
X} Symbol;
X
X/* hash table length */
X#define SYM_MAX_HASH 256
X
Xtypedef struct _symbol_table {
X	Symbol *bucket[SYM_MAX_HASH];	/* hash buckets */
X} SymbolTable;
X
Xextern SymbolTable *create_symbol_table();	/* Create symbol table */
Xextern Symbol *find_symbol();			/* Lookup symbol name */
Xextern Symbol *new_symbol();			/* Define new symbol */
X
X#endif
END_OF_symbol.h
if test 587 -ne `wc -c <symbol.h`; then
    echo shar: \"symbol.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f cproto.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"cproto.c\"
else
echo shar: Extracting \"cproto.c\" \(7676 characters\)
sed "s/^X//" >cproto.c <<'END_OF_cproto.c'
X/* $Id: cproto.c 2.1 91/03/25 11:40:34 cthuang Exp $
X *
X * C prototype generator
X * Reads C source code and outputs ANSI C function prototypes.
X */
X#ifndef lint
Xstatic char *rcsid = "$Id: cproto.c 2.1 91/03/25 11:40:34 cthuang Exp $";
X#endif
X#include <stdio.h>
X#include <ctype.h>
X#include "cproto.h"
X#include "patchlev.h"
X
X/* C preprocessor */
X#ifndef CPP
X#define CPP "/lib/cpp"
X#endif
X
X/* getopt declarations */
Xextern int getopt();
Xextern char *optarg;
Xextern int optind;
X
X/* lex declarations */
Xextern FILE *yyin;	/* lex input stream */
X
X/* Name of the program */
Xstatic char *progname = "cproto";
X
X/* Program options */
X
X/* TRUE if "extern" should appear on external declarations. */
Xboolean extern_out = FALSE;
X
X/* TRUE if static declarations are also output. */
Xboolean static_out = FALSE;
X
X/* TRUE if variable declarations are output. */
Xboolean variables_out = FALSE;
X
X/* TRUE if formal parameter promotion is enabled. */
Xboolean promote_param = TRUE;
X
X/* Style of function prototype generated */
Xint proto_style = PROTO_ANSI;
X
X/* Name of macro to guard prototypes */
Xchar *macro_name = "P_";
X
X/* TRUE if prototype macro definition is output. */
Xboolean define_macro = TRUE;
X
X/* String output before prototype declaration specifiers */
Xchar *decl_spec_prefix = "";
X
X/* String output before prototype declarator */
Xchar *declarator_prefix = " ";
X
X/* String output after prototype declarator */
Xchar *declarator_suffix = "";
X
X/* String output before the first parameter in a function prototype */
Xchar *first_param_prefix = "";
X
X/* String output before each subsequent parameter in a function prototype */
Xchar *middle_param_prefix = " ";
X
X/* String output after the last parameter in a function prototype */
Xchar *last_param_suffix = "";
X
X/* Include file directories */
X#ifdef MSDOS
Xint num_inc_dir = 1;
Xchar *inc_dir[MAX_INC_DIR] = { ".\\" };
X#else
Xint num_inc_dir = 2;
Xchar *inc_dir[MAX_INC_DIR] = { "./", "/usr/include/" };
X#endif
X
X/* Output an error message along with the current line number in the
X * source file.
X */
Xvoid
Xoutput_error ()
X{
X    fprintf(stderr, "\"%s\", line %d: ", cur_file, line_num);
X}
X
X/* Replace any character escape sequences in a string with the actual
X * characters.  Return a pointer to malloc'ed memory containing the result.
X * This function knows only a few escape sequences.
X */
Xstatic char *
Xescape_string (src)
Xchar *src;
X{
X    char *result, *get, *put;
X
X    result = strdup(src);
X    put = result;
X    get = src;
X    while (*get != '\0') {
X	if (*get == '\\') {
X	    switch (*(++get)) {
X	    case 'n':
X		*put++ = '\n';
X		++get;
X		break;
X	    case 't':
X		*put++ = '\t';
X		++get;
X		break;
X	    default:
X		if (*get != '\0')
X		    *put++ = *get++;
X	    }
X	} else {
X	    *put++ = *get++;
X	}
X    }
X    *put = *get;
X    return result;
X}
X
X/* Append a path name separator to the end of the string if it doesn't
X * end with one already.  Allocate storage for the result and return
X * a pointer to it.
X */
Xstatic char *
Xadd_path_sep (s)
Xchar *s;
X{
X    char *result, ch;
X    int n;
X
X    n = strlen(s);
X    result = malloc(n+2);
X    strcpy(result, s);
X    ch = result[n-1];
X    if (ch != '/' && ch != '\\') {
X	result[n] = '/';
X	result[n+1] = '\0';
X    }
X    return result;
X}
X
X/* Output usage message and exit.
X */
Xstatic void
Xusage ()
X{
X    fprintf(stderr,
X	"usage: %s [ option ... ] [ file ... ]\n", progname);
X    fputs("  -e      output \"extern\" keyword before global declarations\n",
X	stderr);
X    fputs("  -f n    select function prototype style (0 to 4)\n", stderr);
X    fputs("  -p      disable prototype promotion\n", stderr);
X    fputs("  -s      output static declarations\n", stderr);
X    fputs("  -v      output variable declarations\n", stderr);
X    fputs("  -m nam  set name of macro guarding prototypes\n", stderr);
X    fputs("  -d      omit prototype macro definition\n", stderr);
X    fputs("  -D name[=value]\n", stderr);
X    fputs("  -U name\n", stderr);
X    fputs("  -I directory\n", stderr);
X    fputs("          C preprocessor options\n", stderr);
X    fputs(
X    "  -F fmt  set prototype template in the form \"int main (a, b)\"\n",
X	stderr);
X    fputs("  -V      print version information\n", stderr);
X    exit(1);
X}
X
Xmain (argc, argv)
Xint argc;
Xchar **argv;
X{
X    int i, c, n;
X    char *s, *cpp_cmd, tmp[MAX_TEXT_LENGTH];
X#ifndef MSDOS
X    char *cmd;
X#endif
X
X    /* Allocate buffer for C preprocessor command line. */
X    n = strlen(CPP) + 1;
X    for (i = 0; i < argc; ++i) {
X	n += strlen(argv[i]) + 1;
X    }
X    cpp_cmd = malloc(n);
X    strcpy(cpp_cmd, CPP);
X#ifndef MSDOS
X    cmd = malloc(n);
X#endif
X
X    /* Scan command line options. */
X    while ((c = getopt(argc, argv, "D:deF:f:I:m:psU:Vv")) != EOF) {
X	switch (c) {
X	case 'I':
X	    if (num_inc_dir < MAX_INC_DIR) {
X		inc_dir[num_inc_dir++] = add_path_sep(optarg);
X	    } else {
X		fprintf(stderr, "%s: too many include directories\n",
X		    progname);
X	    }
X	case 'D':
X	case 'U':
X	    sprintf(tmp, " -%c%s", c, optarg);
X	    strcat(cpp_cmd, tmp);
X	    break;
X	case 'd':
X	    define_macro = FALSE;
X	    break;
X	case 'e':
X	    extern_out = TRUE;
X	    break;
X	case 'F':
X	    s = escape_string(optarg);
X
X	    decl_spec_prefix = s;
X	    while (*s != '\0' && isascii(*s) && !isalnum(*s)) ++s;
X	    if (*s == '\0') usage();
X	    *s++ = '\0';
X	    while (*s != '\0' && isascii(*s) && isalnum(*s)) ++s;
X	    if (*s == '\0') usage();
X
X	    declarator_prefix = s;
X	    while (*s != '\0' && isascii(*s) && !isalnum(*s)) ++s;
X	    if (*s == '\0') usage();
X	    *s++ = '\0';
X	    while (*s != '\0' && isascii(*s) && isalnum(*s)) ++s;
X	    if (*s == '\0') usage();
X
X	    declarator_suffix = s;
X	    while (*s != '\0' && *s != '(') ++s;
X	    if (*s == '\0') usage();
X	    *s++ = '\0';
X
X	    first_param_prefix = s;
X	    while (*s != '\0' && isascii(*s) && !isalnum(*s)) ++s;
X	    if (*s == '\0') usage();
X	    *s++ = '\0';
X	    while (*s != '\0' && *s != ',') ++s;
X	    if (*s == '\0') usage();
X
X	    middle_param_prefix = ++s;
X	    while (*s != '\0' && isascii(*s) && !isalnum(*s)) ++s;
X	    if (*s == '\0') usage();
X	    *s++ = '\0';
X	    while (*s != '\0' && isascii(*s) && isalnum(*s)) ++s;
X	    if (*s == '\0') usage();
X
X	    last_param_suffix = s;
X	    while (*s != '\0' && *s != ')') ++s;
X	    *s = '\0';
X
X	    break;
X	case 'f':
X	    proto_style = atoi(optarg);
X	    if (proto_style < 0 || proto_style > PROTO_MACRO)
X		proto_style = PROTO_ANSI;
X	    break;
X	case 'm':
X	    macro_name = optarg;
X	    break;
X	case 'p':
X	    promote_param = FALSE;
X	    break;
X	case 's':
X	    static_out = TRUE;
X	    break;
X	case 'V':
X	    fprintf(stderr, "%s patchlevel %d\n", rcsid, PATCHLEVEL);
X	    break;
X	case 'v':
X	    variables_out = TRUE;
X	    break;
X	case '?':
X	default:
X	    usage();
X	}
X    }
X
X    if (proto_style == PROTO_MACRO && define_macro) {
X	printf("#if defined(__STDC__) || defined(__cplusplus)\n");
X	printf("# define %s(s) s\n", macro_name);
X	printf("#else\n");
X	printf("# define %s(s) ()\n", macro_name);
X	printf("#endif\n\n");
X    }
X
X    if (optind == argc) {
X	printf("/* stdin */\n");
X	parse_file();
X    } else {
X	for (i = optind; i < argc; ++i) {
X#ifdef MSDOS
X	    if (freopen(argv[i], "r", yyin) == NULL) {
X		fprintf(stderr, "%s: cannot open file %s\n", progname, argv[i]);
X		continue;
X	    }
X#else
X	    sprintf(cmd, "%s %s", cpp_cmd, argv[i]);
X	    if ((yyin = popen(cmd, "r")) == NULL) {
X		fprintf(stderr, "%s: error running cpp\n", progname);
X		continue;
X	    }
X#endif
X	    strcpy(cur_file, argv[i]);
X	    line_num = 1;
X	    printf("/* %s */\n", cur_file);
X	    parse_file();
X#ifdef MSDOS
X	    fclose(yyin);
X#else
X	    pclose(yyin);
X#endif
X	}
X    }
X
X    if (proto_style == PROTO_MACRO && define_macro) {
X	printf("\n#undef %s\n", macro_name);
X    }
X
X    return 0;
X}
END_OF_cproto.c
if test 7676 -ne `wc -c <cproto.c`; then
    echo shar: \"cproto.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f semantic.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"semantic.c\"
else
echo shar: Extracting \"semantic.c\" \(10639 characters\)
sed "s/^X//" >semantic.c <<'END_OF_semantic.c'
X/* $Id: semantic.c 2.1 91/03/25 11:40:31 cthuang Exp $
X *
X * C prototype generator
X * These routines implement the semantic actions executed by the yacc parser.
X */
X#include <stdio.h>
X#include "cproto.h"
X#include "semantic.h"
X
X/* Output a string to standard output. */
X#define put_string(s) fputs(s, stdout)
X
X/* Create a new string by joining two strings with a space between them.
X * Return a pointer to the resultant string or NULL if an error occurred.
X */
Xstatic char *
Xconcat_string (a, b)
Xchar *a, *b;
X{
X    char *result;
X
X    if ((result = malloc((unsigned)(strlen(a) + strlen(b) + 2))) != NULL) {
X	strcpy(result, a);
X	strcat(result, " ");
X	strcat(result, b);
X    }
X    return result;
X}
X
X/* Return TRUE if the given identifier is really a typedef name.
X * Search the symbol table for the identifier.
X */
Xboolean
Xis_typedef_name (name)
Xchar *name;
X{
X    return (boolean)(find_symbol(typedef_names, name) != NULL);
X}
X
X/* Initialize a new declaration specifier part.
X */
Xvoid
Xnew_decl_spec (decl_spec, text, flags)
XDeclSpec *decl_spec;
Xchar *text;
Xunsigned short flags;
X{
X    decl_spec->text = strdup(text);
X    decl_spec->flags = flags;
X}
X
X/* Append two declaration specifier parts together.
X */
Xvoid
Xjoin_decl_specs (result, a, b)
XDeclSpec *result, *a, *b;
X{
X    result->text = concat_string(a->text, b->text);
X    result->flags = a->flags | b->flags;
X    free(a->text);
X    free(b->text);
X}
X
X/* Free storage used by a declaration specifier part.
X */
Xvoid
Xfree_decl_spec (decl_spec)
XDeclSpec *decl_spec;
X{
X    free(decl_spec->text);
X}
X
X/* Initialize the parameter structure.
X */
Xvoid
Xnew_parameter (param, decl_spec, declarator)
XParameter *param;		/* pointer to structure to be initialized */
XDeclSpec *decl_spec;		/* declaration specifier structure */
XDeclarator *declarator;		/* declarator structure */
X{
X    if (decl_spec == NULL) {
X	new_decl_spec(&(param->decl_spec), "", DE_JUNK);
X    } else {
X	param->decl_spec = *decl_spec;
X    }
X
X    if (declarator == NULL) {
X	new_declarator(&(param->declarator), "", "");
X    } else {
X	param->declarator = *declarator;
X    }
X}
X
X/* Free the storage used by the parameter.
X */
Xvoid
Xfree_parameter (param)
XParameter *param;
X{
X    free_decl_spec(&(param->decl_spec));
X    free_declarator(&(param->declarator));
X}
X
X/* Initialize a list of function parameters.
X */
Xvoid
Xnew_param_list (param_list, param)
XParameterList *param_list;
XParameter *param;
X{
X    Parameter *p;
X
X    p = (Parameter *)malloc((unsigned)sizeof(Parameter));
X    *p = *param;
X    
X    param_list->first = param_list->last = p;
X    p->next = NULL;
X}
X
X/* Add the function parameter declaration to the list.
X */
Xvoid
Xadd_param_list (to, from, param)
XParameterList *to, *from;
XParameter *param;
X{
X    Parameter *p;
X
X    p = (Parameter *)malloc((unsigned)sizeof(Parameter));
X    *p = *param;
X
X    to->first = from->first;
X    from->last->next = p;
X    to->last = p;
X    p->next = NULL;
X}
X
X/* Free storage used by the elements in the function parameter list.
X */
Xvoid
Xfree_param_list (param_list)
XParameterList *param_list;
X{
X    Parameter *p, *next;
X
X    p = param_list->first;
X    while (p != NULL) {
X	next = p->next;
X	free_parameter(p);
X	free(p);
X	p = next;
X    }
X}
X
X/* Initialize an empty list of function parameter names.
X */
Xvoid
Xnew_ident_list (param_list)
XParameterList *param_list;
X{
X    param_list->first = param_list->last = NULL;
X}
X
X/* Add an item to the list of function parameter declarations but set only
X * the parameter name field.
X */
Xvoid
Xadd_ident_list (to, from, name)
XParameterList *to, *from;
Xchar *name;
X{
X    Parameter *p;
X    Declarator declarator;
X
X    p = (Parameter *)malloc((unsigned)sizeof(Parameter));
X    new_declarator(&declarator, name, name);
X    new_parameter(p, NULL, &declarator);
X
X    to->first = from->first;
X    if (to->first == NULL) {
X	to->first = p;
X    } else {
X	from->last->next = p;
X    }
X    to->last = p;
X    p->next = NULL;
X}
X
X/* Initialize a declarator.
X */
Xvoid
Xnew_declarator (d, name, text)
XDeclarator *d;
Xchar *name, *text;
X{
X    d->name = strdup(name);
X    d->text = strdup(text);
X    d->func_def = FUNC_NONE;
X    d->params.first = d->params.last = NULL;
X}
X
X/* Free storage used by a declarator.
X */
Xvoid
Xfree_declarator (d)
XDeclarator *d;
X{
X    free(d->name);
X    free(d->text);
X    free_param_list(&(d->params));
X}
X
X/* Initialize a declarator list and add the given declarator to it.
X */
Xvoid
Xnew_decl_list (decl_list, declarator)
XDeclaratorList *decl_list;
XDeclarator *declarator;
X{
X    Declarator *d;
X
X    d = (Declarator *)malloc((unsigned)sizeof(Declarator));
X    *d = *declarator;
X
X    decl_list->first = decl_list->last = d;
X    d->next = NULL;
X}
X
X/* Add the declarator to the declarator list.
X */
Xvoid
Xadd_decl_list (to, from, declarator)
XDeclaratorList *to, *from;
XDeclarator *declarator;
X{
X    Declarator *d;
X
X    d = (Declarator *)malloc((unsigned)sizeof(Declarator));
X    *d = *declarator;
X
X    to->first = from->first;
X    from->last->next = d;
X    to->last = d;
X    to->last->next = NULL;
X}
X
X/* Free storage used by the declarators in the declarator list.
X */
Xvoid
Xfree_decl_list (decl_list)
XDeclaratorList *decl_list;
X{
X    Declarator *d, *next;
X
X    d = decl_list->first;
X    while (d != NULL) {
X	next = d->next;
X	free_declarator(d);
X	free((char *)d);
X	d = next;
X    }
X}
X
X/* Search the list of parameters for a matching parameter name.
X * Return a pointer to the matching parameter or NULL if not found.
X */
Xstatic Parameter *
Xsearch_parameter_list (params, name)
XParameterList *params;
Xchar *name;
X{
X    Parameter *p;
X
X    for (p = params->first; p != NULL; p = p->next) {
X	if (strcmp(p->declarator.name, name) == 0)
X	    return p;
X    }
X    return (Parameter *)NULL;
X}
X
X/* This routine is called to generate function prototypes from traditional
X * style function definitions.  For each parameter name in the declarator
X * list, find the matching parameter name in the parameter list and set
X * that parameter's declaration specifier.
X * This is also where we promote formal parameters.  Parameters of type
X * "char", "unsigned char", "short", or "unsigned short" get promoted to
X * "int".  Parameters of type "float" are promoted to "double".
X */
Xvoid
Xset_param_types (params, decl_spec, declarators)
XParameterList *params;
XDeclSpec *decl_spec;
XDeclaratorList *declarators;
X{
X    Declarator *d;
X    Parameter *p;
X    char *decl_spec_text, *s;
X
X    for (d = declarators->first; d != NULL; d = d->next) {
X	/* Search the parameter list for a matching name. */
X	p = search_parameter_list(params, d->name);
X	if (p == NULL) {
X	    output_error();
X	    fprintf(stderr, "declared argument \"%s\" is missing\n", d->name);
X	} else {
X	    p->declarator.text = strdup(d->text);
X	    decl_spec_text = decl_spec->text;
X	    if (promote_param && strcmp(d->text, d->name) == 0) {
X	        s = rindex(decl_spec_text, ' ');
X		s = (s != NULL) ? s+1 : decl_spec_text;
X		if (strcmp(s, "char") == 0 || strcmp(s, "short") == 0)
X		    decl_spec_text = "int";
X		else if (strcmp(s, "float") == 0)
X		    decl_spec_text = "double";
X	    }
X	    p->decl_spec.text = strdup(decl_spec_text);
X	}
X    }
X}
X
X/* Output a declaration specifier for an external declaration.
X */
Xstatic void
Xoutput_decl_spec (decl_spec)
XDeclSpec *decl_spec;
X{
X    if (extern_out && (decl_spec->flags & DE_STATIC) == 0) {
X	if (strstr(decl_spec->text, "extern") == NULL) {
X	    put_string("extern ");
X	}
X    }
X    put_string(decl_spec->text);
X}
X
Xstatic void output_parameters();
X
X/* Output a declarator.
X */
Xstatic void
Xoutput_declarator (d)
XDeclarator *d;
X{
X    char *s;
X
X    if (d->func_def == FUNC_NONE) {
X	put_string(d->text);
X    } else {
X	if ((s = strstr(d->text, "()")) != NULL) {
X	    *s = '\0';
X	    put_string(d->text);
X	    put_string(declarator_suffix);
X	    if (proto_style == PROTO_MACRO)
X		printf(" %s(", macro_name);
X	    fputc(*s++ = '(', stdout);
X	    output_parameters(&(d->params));
X	    fputc(*s++, stdout);
X	    if (proto_style == PROTO_MACRO)
X		putchar(')');
X	    put_string(s);
X	}
X    }
X}
X
X/* Output a function parameter.
X */
Xstatic void
Xoutput_parameter (p)
XParameter *p;
X{
X    char *s;
X
X    put_string(p->decl_spec.text);
X    if (proto_style == PROTO_ABSTRACT && strlen(p->declarator.name) > 0) {
X	s = strstr(p->declarator.text, p->declarator.name);
X	*s = '\0';
X	printf(" %s/*%s*/%s", p->declarator.text, p->declarator.name,
X		s + strlen(p->declarator.name));
X	*s = *(p->declarator.name);
X    } else {
X	if (strlen(p->declarator.text) > 0) {
X	    putchar(' ');
X	    output_declarator(&(p->declarator));
X	}
X    }
X}
X
X/* Output the list of function parameters.
X */
Xstatic void
Xoutput_parameters (params)
XParameterList *params;
X{
X    Parameter *p;
X
X    if (proto_style == PROTO_TRADITIONAL)
X	put_string("/*");
X
X    p = params->first;
X    if (p == NULL ||
X        (strcmp(p->decl_spec.text, "void") == 0 &&
X	 strlen(p->declarator.text) == 0)) {
X	put_string("void");
X    } else {
X	put_string(first_param_prefix);
X	output_parameter(p);
X	p = p->next;
X	while (p != NULL) {
X	    putchar(',');
X	    put_string(middle_param_prefix);
X	    output_parameter(p);
X	    p = p->next;
X	}
X	put_string(last_param_suffix);
X    }
X
X    if (proto_style == PROTO_TRADITIONAL)
X	put_string("*/");
X}
X
X/* Output variable declarations.
X */
Xvoid
Xoutput_declarations (decl_spec, decl_list)
XDeclSpec *decl_spec;		/* declaration specifier */
XDeclaratorList *decl_list;	/* list of declared variables */
X{
X    Declarator *d;
X
X    if (!variables_out || (decl_spec->flags & DE_JUNK))
X	return;
X    if (!static_out && (decl_spec->flags & DE_STATIC))
X	return;
X
X    for (d = decl_list->first; d != NULL; d = d->next) {
X	if (d->func_def == FUNC_NONE) {
X	    put_string(decl_spec_prefix);
X	    output_decl_spec(decl_spec);
X	    putchar(' ');
X	    output_declarator(d);
X	    put_string(";\n");
X	}
X    }
X}
X
X/* Output a function prototype.
X */
Xvoid
Xoutput_prototype (decl_spec, declarator)
XDeclSpec *decl_spec;
XDeclarator *declarator;
X{
X    Parameter *p;
X
X    if (proto_style == PROTO_NONE)
X	return;
X    if (decl_spec->flags & DE_JUNK)
X	return;
X    if (!static_out && (decl_spec->flags & DE_STATIC))
X	return;
X
X    /* Check for parameter names with no declaration specifiers.  This
X     * happens when a parameter name appears in the identifier list of a
X     * function definition but does not appear in the parameter declaration
X     * part.  The default type in this cause is "int".
X     */
X    for (p = declarator->params.first; p != NULL; p = p->next) {
X	if (strlen(p->decl_spec.text) == 0) {
X	    free(p->decl_spec.text);
X	    p->decl_spec.text = strdup("int");
X	}
X    }
X
X    put_string(decl_spec_prefix);
X    output_decl_spec(decl_spec);
X    put_string(declarator_prefix);
X    output_declarator(declarator);
X    put_string(";\n");
X}
END_OF_semantic.c
if test 10639 -ne `wc -c <semantic.c`; then
    echo shar: \"semantic.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f string.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"string.c\"
else
echo shar: Extracting \"string.c\" \(795 characters\)
sed "s/^X//" >string.c <<'END_OF_string.c'
X/* $Id: string.c 2.1 91/02/28 11:16:33 cthuang Exp $
X *
X * Some string handling routines
X */
X#include <stdio.h>
X#include "config.h"
X
X/* Copy the string into an allocated memory block.
X * Return a pointer to the copy.
X */
Xchar *
Xstrdup (s)
Xchar *s;
X{
X    char *dest;
X
X    if ((dest = malloc((unsigned)(strlen(s)+1))) == NULL) {
X	fprintf(stderr, "No memory to duplicate string.\n");
X	exit(1);
X    }
X    strcpy(dest, s);
X    return dest;
X}
X
X/* Return a pointer to the first occurence of the substring 
X * within the string, or NULL if not found.
X */
Xchar *
Xstrstr (src, key)
Xchar *src, *key;
X{
X    char *s;
X    int keylen;
X
X    keylen = strlen(key);
X    s = index(src, *key);
X    while (s != NULL) {
X	if (strncmp(s, key, keylen) == 0)
X	    return s;
X	s = index(s+1, *key);
X    }
X    return NULL;
X}
END_OF_string.c
if test 795 -ne `wc -c <string.c`; then
    echo shar: \"string.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f symbol.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"symbol.c\"
else
echo shar: Extracting \"symbol.c\" \(1900 characters\)
sed "s/^X//" >symbol.c <<'END_OF_symbol.c'
X/* $Id: symbol.c 2.1 91/02/28 11:16:35 cthuang Exp $
X *
X * Symbol table maintenance. Implements an abstract data type called
X * the symbol table.
X */
X#include <stdio.h>
X#include "config.h"
X#include "symbol.h"
X
X/* Create a symbol table.
X * Return a pointer to the symbol table or NULL if an error occurs.
X */
XSymbolTable *
Xcreate_symbol_table ()
X{
X    SymbolTable *symtab;
X    int i;
X
X    if ((symtab = (SymbolTable *)malloc(sizeof(SymbolTable))) != NULL) {
X	for (i = 0; i < SYM_MAX_HASH; ++i)
X	    symtab->bucket[i] = NULL;
X    }
X    return symtab;
X}
X
X
X/* This is a simple hash function mapping a symbol name to a hash bucket. */
X
Xstatic int
Xhash (name)
Xchar *name;
X{
X    return (name[0] + name[1] + strlen(name)) % SYM_MAX_HASH;
X}
X
X
X/* Search the list of symbols <list> for the symbol <name>.
X * Return a pointer to the symbol or NULL if not found.
X */
Xstatic Symbol *
Xsearch_symbol_list (list, name)
XSymbol *list;
Xchar *name;
X{
X    Symbol *sym;
X
X    for (sym = list; sym != NULL; sym = sym->next) {
X	if (strcmp(sym->name, name) == 0)
X	    return sym;
X    }
X    return NULL;
X}
X
X
X/* Look for symbol <name> in symbol table <symtab>.
X * Return a pointer to the symbol or NULL if not found.
X */
XSymbol *
Xfind_symbol (symtab, name)
XSymbolTable *symtab;
Xchar *name;
X{
X    return search_symbol_list(symtab->bucket[hash(name)], name);
X}
X
X
X/* If the symbol <name> does not already exist in symbol table <symtab>,
X * then add the symbol to the symbol table.
X * Return a pointer to the symbol or NULL on an error.
X */
XSymbol *
Xnew_symbol (symtab, name)
XSymbolTable *symtab;	/* symbol table */
Xchar *name;		/* symbol name */
X{
X    Symbol *sym;
X    int i;
X
X    if ((sym = find_symbol(symtab, name)) == NULL) {
X	if ((sym = (Symbol *)malloc(sizeof(Symbol))) != NULL) {
X	    sym->name = strdup(name);
X	    i = hash(name);
X	    sym->next = symtab->bucket[i];
X	    symtab->bucket[i] = sym;
X	}
X    }
X    return sym;
X}
END_OF_symbol.c
if test 1900 -ne `wc -c <symbol.c`; then
    echo shar: \"symbol.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0
-- 
Chin Huang  cthuang@contact.uucp  chin.huang@canrem.uucp

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.