home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume28 / cproto / part02 < prev    next >
Encoding:
Text File  |  1992-03-14  |  46.8 KB  |  1,846 lines

  1. Newsgroups: comp.sources.misc
  2. From: cthuang@zerosan.UUCP (Chin Huang)
  3. Subject:  v28i101:  cproto - generate C function prototypes v3, Part02/02
  4. Message-ID: <1992Mar14.222622.4016@sparky.imd.sterling.com>
  5. X-Md4-Signature: c224692232069c890be7cfc198de8596
  6. Date: Sat, 14 Mar 1992 22:26:22 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: cthuang@zerosan.UUCP (Chin Huang)
  10. Posting-number: Volume 28, Issue 101
  11. Archive-name: cproto/part02
  12. Environment: UNIX, MS-DOS, getopt, lex, yacc
  13. Supersedes: cproto: Volume 17, Issue 70-71
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then unpack
  17. # it by saving it into a file and typing "sh file".  To overwrite existing
  18. # files, type "sh file -c".  You can also feed this as standard input via
  19. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  20. # will see the following message at the end:
  21. #        "End of shell archive."
  22. # Contents:  config.h cproto.h patchlev.h semantic.h symbol.h cproto.c
  23. #   popen.c semantic.c strstr.c symbol.c
  24. # Wrapped by cthuang@zerosan.UUCP on Sat Mar 14 12:14:56 1992
  25. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  26. if test -f config.h -a "${1}" != "-c" ; then 
  27.   echo shar: Will not over-write existing file \"config.h\"
  28. else
  29. echo shar: Extracting \"config.h\" \(773 characters\)
  30. sed "s/^X//" >config.h <<'END_OF_config.h'
  31. X/* $Id: config.h 3.2 92/03/14 11:57:03 cthuang Exp $
  32. X *
  33. X * cproto configuration and system dependencies
  34. X */
  35. X
  36. X/* maximum include file nesting */
  37. X#define MAX_INC_DEPTH 15
  38. X
  39. X/* maximum number of include directories */
  40. X#define MAX_INC_DIR 15
  41. X
  42. X/* maximum text buffer size */
  43. X#define MAX_TEXT_SIZE 256
  44. X
  45. X/* Borland C predefines __MSDOS__ */
  46. X#ifdef __MSDOS__
  47. X#ifndef MSDOS
  48. X#define MSDOS
  49. X#endif
  50. X#endif
  51. X
  52. X#ifdef MSDOS
  53. X#include <malloc.h>
  54. X#include <stdlib.h>
  55. X#else
  56. Xextern char *malloc();
  57. Xextern char *getenv();
  58. X#endif
  59. X
  60. X#ifdef BSD
  61. X#include <strings.h>
  62. X#define strchr index
  63. X#define strrchr rindex
  64. X#else
  65. X#include <string.h>
  66. X#endif
  67. X
  68. X#ifndef MSDOS
  69. Xextern char *strstr();
  70. X#endif
  71. X
  72. X/* C preprocessor */
  73. X#ifdef TURBO_CPP
  74. X#define CPP "cpp -P-"
  75. X#endif
  76. X
  77. X#ifndef MSDOS
  78. X#define CPP "/lib/cpp"
  79. X#endif
  80. END_OF_config.h
  81. if test 773 -ne `wc -c <config.h`; then
  82.     echo shar: \"config.h\" unpacked with wrong size!
  83. fi
  84. # end of overwriting check
  85. fi
  86. if test -f cproto.h -a "${1}" != "-c" ; then 
  87.   echo shar: Will not over-write existing file \"cproto.h\"
  88. else
  89. echo shar: Extracting \"cproto.h\" \(5008 characters\)
  90. sed "s/^X//" >cproto.h <<'END_OF_cproto.h'
  91. X/* $Id: cproto.h 3.3 92/03/14 11:57:14 cthuang Exp $
  92. X *
  93. X * Declarations for C function prototype generator
  94. X */
  95. X#include "config.h"
  96. X
  97. X/* Boolean type */
  98. Xtypedef char boolean;
  99. X#define FALSE    0
  100. X#define TRUE    1
  101. X
  102. X/* Source file text */
  103. Xtypedef struct text {
  104. X    char text[MAX_TEXT_SIZE];    /* source text */
  105. X    long begin;         /* offset in temporary output file */
  106. X} Text;
  107. X
  108. X/* This is a list of function parameters. */
  109. Xtypedef struct parameter_list {
  110. X    struct parameter *first;    /* pointer to first parameter in list */
  111. X    struct parameter *last;    /* pointer to last parameter in list */  
  112. X    long begin_comment;     /* begin offset of comment */
  113. X    long end_comment;        /* end offset of comment */
  114. X    char *comment;        /* comment at start of parameter list */
  115. X} ParameterList;
  116. X
  117. X/* Declaration specifier flags */
  118. X#define DS_EXTERN    0    /* default: external declaration */
  119. X#define DS_STATIC    1    /* visible only in current file */
  120. X#define DS_CHAR     2    /* "char" type specifier in declaration */
  121. X#define DS_SHORT    4    /* "short" type specifier in declaration */
  122. X#define DS_FLOAT    8    /* "float" type specifier in declaration */
  123. X#define DS_JUNK     16    /* we're not interested in this declaration */
  124. X
  125. X/* This structure stores information about a declaration specifier. */
  126. Xtypedef struct decl_spec {
  127. X    unsigned short flags;    /* flags defined above */
  128. X    char *text;         /* source text */
  129. X    long begin;         /* offset in output file */
  130. X} DeclSpec;
  131. X
  132. X/* Styles of function definitions */
  133. Xtypedef enum {
  134. X    FUNC_NONE,            /* not a function definition */
  135. X    FUNC_TRADITIONAL,        /* traditional style */
  136. X    FUNC_ANSI            /* ANSI style */
  137. X} FuncDefStyle;
  138. X
  139. X/* This structure stores information about a declarator. */
  140. Xtypedef struct declarator {
  141. X    char *name;             /* name of variable or function */
  142. X    char *text;             /* source text */
  143. X    long begin;             /* offset in temporary file */
  144. X    long begin_comment;         /* begin offset of comment */
  145. X    long end_comment;            /* end offset of comment */
  146. X    FuncDefStyle func_def;        /* style of function definition */
  147. X    ParameterList params;        /* function parameters */
  148. X    struct declarator *head;        /* head function declarator */
  149. X    struct declarator *func_stack;    /* stack of function declarators */
  150. X    struct declarator *next;        /* next declarator in list */
  151. X} Declarator;
  152. X
  153. X/* This is a list of declarators. */
  154. Xtypedef struct declarator_list {
  155. X    Declarator *first;        /* pointer to first declarator in list */
  156. X    Declarator *last;        /* pointer to last declarator in list */  
  157. X} DeclaratorList;
  158. X
  159. X/* This structure stores information about a function parameter. */
  160. Xtypedef struct parameter {
  161. X    struct parameter *next;    /* next parameter in list */
  162. X    DeclSpec decl_spec;
  163. X    Declarator *declarator;
  164. X    char *comment;        /* comment following the parameter */
  165. X} Parameter;
  166. X
  167. X/* parser stack entry type */
  168. Xtypedef union {
  169. X    Text text;
  170. X    DeclSpec decl_spec;
  171. X    Parameter parameter;
  172. X    ParameterList param_list;
  173. X    Declarator *declarator;
  174. X    DeclaratorList decl_list;
  175. X} YYSTYPE;
  176. X
  177. X/* Prototype styles */
  178. Xtypedef enum {
  179. X    PROTO_NONE,     /* do not output any prototypes */
  180. X    PROTO_TRADITIONAL,    /* comment out parameters */
  181. X    PROTO_ABSTRACT,    /* comment out parameter names */
  182. X    PROTO_ANSI,     /* ANSI C prototype */
  183. X    PROTO_MACRO,    /* preprocessor macro around parameters */
  184. X} PrototypeStyle;
  185. X
  186. X/* The role of a function declarator */
  187. Xtypedef enum {
  188. X    FUNC_OTHER,     /* declarator for a miscellaneous declaration */
  189. X    FUNC_PROTO,     /* declarator for a prototype */
  190. X    FUNC_DEF        /* declarator for a function definition */
  191. X} FuncDeclRole;
  192. X
  193. X/* Prototype/function definition output formats */
  194. Xtypedef enum {
  195. X    FMT_OTHER,        /* miscellaneous */
  196. X    FMT_PROTO,        /* prototype */
  197. X    FMT_FUNC,        /* function definition */
  198. X    FMT_FUNC_COMMENT    /* function definition with parameter comments */
  199. X} FuncFormatType;
  200. X
  201. X/* Prototype/function definition output format */
  202. Xtypedef struct {
  203. X    char *decl_spec_prefix;    /* output before declaration specifier */
  204. X    char *declarator_prefix;    /* output before declarator name */
  205. X    char *declarator_suffix;    /* output before '(' of parameter list */
  206. X    char *first_param_prefix;    /* output before first parameter */
  207. X    char *middle_param_prefix;    /* output before each subsequent parameter */
  208. X    char *last_param_suffix;    /* output after last parameter */
  209. X} FuncFormat;
  210. X
  211. X/* Program options */
  212. Xextern boolean extern_out;
  213. Xextern boolean static_out;
  214. Xextern boolean variables_out;
  215. Xextern boolean promote_param;
  216. Xextern PrototypeStyle proto_style;
  217. Xextern FuncDefStyle func_style;
  218. Xextern boolean define_macro;
  219. Xextern char *macro_name;
  220. Xextern boolean file_comment_out;
  221. Xextern int num_inc_dir;
  222. Xextern char *inc_dir[];
  223. Xextern FuncFormat fmt[4];
  224. X
  225. X/* Global declarations */
  226. Xextern char progname[];
  227. Xextern long begin_comment, end_comment;
  228. X
  229. Xextern char *xmalloc(), *xstrdup(), *trim_path_sep();
  230. Xextern void put_error();
  231. Xextern void init_parser(), process_file(), pop_file();
  232. Xextern char *cur_file_name();
  233. Xextern unsigned cur_line_num();
  234. Xextern FILE *cur_tmp_file();
  235. Xextern void cur_file_changed();
  236. END_OF_cproto.h
  237. if test 5008 -ne `wc -c <cproto.h`; then
  238.     echo shar: \"cproto.h\" unpacked with wrong size!
  239. fi
  240. # end of overwriting check
  241. fi
  242. if test -f patchlev.h -a "${1}" != "-c" ; then 
  243.   echo shar: Will not over-write existing file \"patchlev.h\"
  244. else
  245. echo shar: Extracting \"patchlev.h\" \(21 characters\)
  246. sed "s/^X//" >patchlev.h <<'END_OF_patchlev.h'
  247. X#define PATCHLEVEL 0
  248. END_OF_patchlev.h
  249. if test 21 -ne `wc -c <patchlev.h`; then
  250.     echo shar: \"patchlev.h\" unpacked with wrong size!
  251. fi
  252. # end of overwriting check
  253. fi
  254. if test -f semantic.h -a "${1}" != "-c" ; then 
  255.   echo shar: Will not over-write existing file \"semantic.h\"
  256. else
  257. echo shar: Extracting \"semantic.h\" \(1823 characters\)
  258. sed "s/^X//" >semantic.h <<'END_OF_semantic.h'
  259. X/* $Id: semantic.h 3.2 92/03/06 00:54:38 cthuang Exp $
  260. X *
  261. X * Declarations of semantic action routines
  262. X */
  263. X
  264. Xextern void new_decl_spec(/*
  265. X    DeclSpec *decl_spec, char *text, long offset, int flags*/);
  266. Xextern void free_decl_spec(/*
  267. X    DeclSpec *decl_spec*/);
  268. Xextern void join_decl_specs(/*
  269. X    DeclSpec *result, DeclSpec *a, DeclSpec *b*/);
  270. Xextern void check_untagged(/*
  271. X    DeclSpec *decl_spec*/);
  272. Xextern Declarator *new_declarator(/*
  273. X    char *text, char *name, long offset*/);
  274. Xextern void free_declarator(/*
  275. X    Declarator *d*/);
  276. Xextern void new_decl_list(/*
  277. X    DeclaratorList *decl_list, Declarator *declarator*/);
  278. Xextern void free_decl_list(/*
  279. X    DeclaratorList *decl_list*/);
  280. Xextern void add_decl_list(/*
  281. X    DeclaratorList *to, DeclaratorList *from, Declarator *declarator*/);
  282. Xextern void new_parameter(/*
  283. X    Parameter *param, DeclSpec *decl_spec, Declarator *declarator*/);
  284. Xextern void free_parameter(/*
  285. X    Parameter *param*/);
  286. Xextern boolean is_void_parameter(/*
  287. X    Parameter *p*/);
  288. Xextern void new_param_list(/*
  289. X    ParameterList *param_list, Parameter *param*/);
  290. Xextern void free_param_list(/*
  291. X    ParameterList *param_list*/);
  292. Xextern void add_param_list(/*
  293. X    ParameterList *to, ParameterList *from, Parameter *param*/);
  294. Xextern void new_ident_list(/*
  295. X    ParameterList *param_list*/);
  296. Xextern void add_ident_list(/*
  297. X    ParameterList *to, ParameterList *from, char *name*/);
  298. Xextern void set_param_types(/*
  299. X    ParameterList *params, DeclSpec *decl_spec, DeclaratorList *declarators*/);
  300. Xextern void gen_declarations(/*
  301. X    DeclSpec *decl_spec, DeclaratorList *decl_list*/);
  302. Xextern void gen_prototype(/*
  303. X    DeclSpec *decl_spec, Declarator *declarator*/);
  304. Xextern void gen_func_declarator(/*
  305. X    Declarator *declarator*/);
  306. Xextern void gen_func_definition(/*
  307. X    DeclSpec *decl_spec, Declarator *declarator*/);
  308. END_OF_semantic.h
  309. if test 1823 -ne `wc -c <semantic.h`; then
  310.     echo shar: \"semantic.h\" unpacked with wrong size!
  311. fi
  312. # end of overwriting check
  313. fi
  314. if test -f symbol.h -a "${1}" != "-c" ; then 
  315.   echo shar: Will not over-write existing file \"symbol.h\"
  316. else
  317. echo shar: Extracting \"symbol.h\" \(776 characters\)
  318. sed "s/^X//" >symbol.h <<'END_OF_symbol.h'
  319. X/* $Id: symbol.h 3.3 92/03/14 11:57:48 cthuang Exp $
  320. X *
  321. X * A symbol table is a collection of string identifiers stored in a
  322. X * hash table.
  323. X */
  324. X#ifndef SYMBOL_H
  325. X#define SYMBOL_H
  326. X
  327. Xtypedef struct symbol {
  328. X    struct symbol *next;    /* next symbol in list */
  329. X    char *name;         /* name of symbol */
  330. X    unsigned short flags;    /* symbol attributes */
  331. X} Symbol;
  332. X
  333. X/* The hash table length should be a prime number. */
  334. X#define SYM_MAX_HASH 251
  335. X
  336. Xtypedef struct symbol_table {
  337. X    Symbol *bucket[SYM_MAX_HASH];    /* hash buckets */
  338. X} SymbolTable;
  339. X
  340. Xextern SymbolTable *new_symbol_table(); /* Create symbol table */
  341. Xextern void free_symbol_table();    /* Destroy symbol table */
  342. Xextern Symbol *find_symbol();        /* Lookup symbol name */
  343. Xextern Symbol *new_symbol();        /* Define new symbol */
  344. X
  345. X#endif
  346. END_OF_symbol.h
  347. if test 776 -ne `wc -c <symbol.h`; then
  348.     echo shar: \"symbol.h\" unpacked with wrong size!
  349. fi
  350. # end of overwriting check
  351. fi
  352. if test -f cproto.c -a "${1}" != "-c" ; then 
  353.   echo shar: Will not over-write existing file \"cproto.c\"
  354. else
  355. echo shar: Extracting \"cproto.c\" \(10336 characters\)
  356. sed "s/^X//" >cproto.c <<'END_OF_cproto.c'
  357. X/* $Id: cproto.c 3.3 92/03/14 11:58:01 cthuang Exp $
  358. X *
  359. X * C function prototype generator and function definition converter
  360. X */
  361. X#ifndef lint
  362. Xstatic char rcsid[] = "$Id: cproto.c 3.3 92/03/14 11:58:01 cthuang Exp $";
  363. X#endif
  364. X#include <stdio.h>
  365. X#include <ctype.h>
  366. X#include "cproto.h"
  367. X#include "patchlev.h"
  368. X
  369. X/* getopt declarations */
  370. Xextern int getopt();
  371. Xextern char *optarg;
  372. Xextern int optind;
  373. X
  374. X/* Name of the program */
  375. Xchar progname[] = "cproto";
  376. X
  377. X/* Program options */
  378. X
  379. X/* If TRUE, output "extern" before global declarations */
  380. Xboolean extern_out = FALSE;
  381. X
  382. X/* If TRUE, generate static declarations */
  383. Xboolean static_out = FALSE;
  384. X
  385. X/* If TRUE, generate variable declarations */
  386. Xboolean variables_out = FALSE;
  387. X
  388. X/* If TRUE, enable formal parameter promotion */
  389. Xboolean promote_param = TRUE;
  390. X
  391. X/* Style of function prototype to generate */
  392. XPrototypeStyle proto_style = PROTO_ANSI;
  393. X
  394. X/* Function definition style converted to */
  395. XFuncDefStyle func_style = FUNC_NONE;
  396. X
  397. X/* Name of macro to guard prototypes */
  398. Xchar *macro_name = "P_";
  399. X
  400. X/* If TRUE, output prototype macro definition */
  401. Xboolean define_macro = TRUE;
  402. X
  403. X/* If TRUE, output file name comments */
  404. Xboolean file_comment_out = TRUE;
  405. X
  406. X/* Output formats for function declarators */
  407. XFuncFormat fmt[] = {
  408. X    /* miscellaneous function declarator */
  409. X    { "", " ", "", "", " ", "" },
  410. X    /* prototype */
  411. X    { "", " ", "", "", " ", "" },
  412. X    /* function definition */
  413. X    { "", "\n", " ", "", " ", "" },
  414. X    /* function definition with parameter comments */
  415. X    { "", "\n", " ", "\n    ", "\n    ", "\n" },
  416. X};
  417. X
  418. X/* Include file directories */
  419. X#ifdef MSDOS
  420. Xint num_inc_dir = 1;
  421. Xchar *inc_dir[MAX_INC_DIR] = { "" };
  422. X#else
  423. Xint num_inc_dir = 2;
  424. Xchar *inc_dir[MAX_INC_DIR] = { "", "/usr/include" };
  425. X#endif
  426. X
  427. X/* C preprocessor command */
  428. X#ifdef CPP
  429. Xextern FILE *popen();
  430. Xextern int pclose();
  431. Xstatic char *cpp_cmd;
  432. X#endif
  433. X
  434. X
  435. X/* Try to allocate some memory.
  436. X * If unsuccessful, output an error message and exit.
  437. X */
  438. Xchar *
  439. Xxmalloc (n)
  440. Xunsigned n;
  441. X{
  442. X    char *p;
  443. X
  444. X    if ((p = malloc(n)) == NULL) {
  445. X    fprintf(stderr, "%s: out of memory\n", progname);
  446. X    exit(1);
  447. X    }
  448. X    return p;
  449. X}
  450. X
  451. X/* Copy the string into allocated memory.
  452. X * If unsuccessful, output an error message and exit.
  453. X */
  454. Xchar *
  455. Xxstrdup (src)
  456. Xchar *src;
  457. X{
  458. X    return strcpy(xmalloc(strlen(src)+1), src);
  459. X}
  460. X
  461. X/* Output the current source file name and line number.
  462. X */
  463. Xvoid
  464. Xput_error ()
  465. X{
  466. X    fprintf(stderr, "\"%s\", line %d: ", cur_file_name(), cur_line_num());
  467. X}
  468. X
  469. X/* Scan for options from a string.
  470. X */
  471. Xstatic void
  472. Xparse_options (src, maxargc, pargc, argv)
  473. Xchar *src;
  474. Xint maxargc, *pargc;
  475. Xchar **argv;
  476. X{
  477. X    char *g, *p, c;
  478. X    int argc;
  479. X
  480. X    argc = 0;
  481. X    g = xstrdup(src);
  482. X    c = *g;
  483. X    while (c != '\0' && argc < maxargc) {
  484. X    while (c == ' ' || c == '\t')
  485. X        c = *++g;
  486. X    if (c == '\0')
  487. X        break;
  488. X    argv[argc++] = g;
  489. X
  490. X    p = g;
  491. X    while (1) {
  492. X        if (c == ' ' || c == '\t' || c == '\0') {
  493. X        *p = '\0';
  494. X        break;
  495. X        } else if (c == '"') {
  496. X        while (1) {
  497. X            c = *++g;
  498. X            if (c == '"') {
  499. X            c = *++g;
  500. X            break;
  501. X            } else if (c == '\0') {
  502. X            break;
  503. X            } else {
  504. X            *p++ = c;
  505. X            }
  506. X        }
  507. X        } else {
  508. X        *p++ = c;
  509. X        c = *++g;
  510. X        }
  511. X    }
  512. X    if (c != '\0')
  513. X        c = *++g;
  514. X    }
  515. X
  516. X    *pargc = argc;
  517. X}
  518. X
  519. X/* Replace any character escape sequences in a string with the actual
  520. X * characters.    Return a pointer to malloc'ed memory containing the result.
  521. X * This function knows only a few escape sequences.
  522. X */
  523. Xstatic char *
  524. Xescape_string (src)
  525. Xchar *src;
  526. X{
  527. X    char *result, *get, *put;
  528. X
  529. X    result = xstrdup(src);
  530. X    put = result;
  531. X    get = src;
  532. X    while (*get != '\0') {
  533. X    if (*get == '\\') {
  534. X        switch (*(++get)) {
  535. X        case 'n':
  536. X        *put++ = '\n';
  537. X        ++get;
  538. X        break;
  539. X        case 't':
  540. X        *put++ = '\t';
  541. X        ++get;
  542. X        break;
  543. X        default:
  544. X        if (*get != '\0')
  545. X            *put++ = *get++;
  546. X        }
  547. X    } else {
  548. X        *put++ = *get++;
  549. X    }
  550. X    }
  551. X    *put = *get;
  552. X    return result;
  553. X}
  554. X
  555. X/* Trim any path name separator from the end of the string.
  556. X * Return a pointer to the string.
  557. X */
  558. Xchar *
  559. Xtrim_path_sep (s)
  560. Xchar *s;
  561. X{
  562. X    char ch;
  563. X    int n;
  564. X
  565. X    n = strlen(s);
  566. X    if (n > 0) {
  567. X    ch = s[n-1];
  568. X    if (ch == '/' || ch == '\\')
  569. X        s[n-1] = '\0';
  570. X    }
  571. X    return s;
  572. X}
  573. X
  574. X/* Output usage message and exit.
  575. X */
  576. Xstatic void
  577. Xusage ()
  578. X{
  579. X    fprintf(stderr, "usage: %s [ option ... ] [ file ... ]\n", progname);
  580. X    fputs("  -a       convert function definitions to ANSI style\n", stderr);
  581. X    fputs("  -e       output \"extern\" keyword before global declarations\n",
  582. X    stderr);
  583. X    fputs("  -f n     set function prototype style (0 to 4)\n", stderr);
  584. X    fputs("  -n       omit file name comments\n", stderr);
  585. X    fputs("  -p       disable formal parameter promotion\n", stderr);
  586. X    fputs("  -s       output static declarations\n", stderr);
  587. X    fputs("  -t       convert function definitions to traditional style\n",
  588. X    stderr);
  589. X    fputs("  -v       output variable declarations\n", stderr);
  590. X    fputs("  -m name  set name of prototype macro\n", stderr);
  591. X    fputs("  -d       omit prototype macro definition\n", stderr);
  592. X    fputs("  -P fmt   set prototype format template \"int main (a, b)\"\n",
  593. X    stderr);
  594. X    fputs("  -F fmt   set function definition format template \"int main (a, b)\"\n",
  595. X    stderr);
  596. X    fputs("  -C fmt   set format for function definition with parameter comments\n",
  597. X    stderr);
  598. X    fputs("  -V       print version information\n", stderr);
  599. X    fputs("  -D name[=value]\n", stderr);
  600. X    fputs("  -U name\n", stderr);
  601. X    fputs("  -I directory\n", stderr);
  602. X    fputs("           C preprocessor options\n", stderr);
  603. X    exit(1);
  604. X}
  605. X
  606. X#define MAX_OPTIONS 20
  607. X
  608. X/* Process the command line options.
  609. X */
  610. Xstatic void
  611. Xprocess_options (pargc, pargv)
  612. Xint *pargc;
  613. Xchar ***pargv;
  614. X{
  615. X    int argc, eargc, nargc;
  616. X    char **argv, *eargv[MAX_OPTIONS], **nargv;
  617. X    int i, c;
  618. X    char *s;
  619. X#ifdef CPP
  620. X    char tmp[MAX_TEXT_SIZE];
  621. X#endif
  622. X
  623. X    argc = *pargc;
  624. X    argv = *pargv;
  625. X    if ((s = getenv("CPROTO")) != NULL) {
  626. X    parse_options(s, MAX_OPTIONS, &eargc, eargv);
  627. X    nargv = (char **)xmalloc((eargc+argc+1)*sizeof(char *));
  628. X    nargv[0] = argv[0];
  629. X    nargc = 1;
  630. X    for (i = 0; i < eargc; ++i)
  631. X        nargv[nargc++] = eargv[i];
  632. X    for (i = 1; i < argc; ++i)
  633. X        nargv[nargc++] = argv[i];
  634. X    nargv[nargc] = NULL;
  635. X    argc = nargc;
  636. X    argv = nargv;
  637. X    }
  638. X
  639. X    while ((c = getopt(argc, argv, "aC:D:deF:f:I:m:nP:pstU:Vv")) != EOF) {
  640. X    switch (c) {
  641. X    case 'I':
  642. X        if (num_inc_dir < MAX_INC_DIR) {
  643. X        inc_dir[num_inc_dir++] = trim_path_sep(xstrdup(optarg));
  644. X        } else {
  645. X        fprintf(stderr, "%s: too many include directories\n",
  646. X            progname);
  647. X        }
  648. X    case 'D':
  649. X    case 'U':
  650. X#ifdef CPP
  651. X        sprintf(tmp, " -%c%s", c, optarg);
  652. X        strcat(cpp_cmd, tmp);
  653. X#endif
  654. X        break;
  655. X    case 'a':
  656. X        func_style = FUNC_ANSI;
  657. X        break;
  658. X    case 'd':
  659. X        define_macro = FALSE;
  660. X        break;
  661. X    case 'e':
  662. X        extern_out = TRUE;
  663. X        break;
  664. X    case 'C':
  665. X    case 'F':
  666. X    case 'P':
  667. X        s = escape_string(optarg);
  668. X        i = (c == 'C') ? FMT_FUNC_COMMENT :
  669. X        ((c == 'F') ? FMT_FUNC : FMT_PROTO);
  670. X
  671. X        fmt[i].decl_spec_prefix = s;
  672. X        while (*s != '\0' && isascii(*s) && !isalnum(*s)) ++s;
  673. X        if (*s == '\0') usage();
  674. X        *s++ = '\0';
  675. X        while (*s != '\0' && isascii(*s) && isalnum(*s)) ++s;
  676. X        if (*s == '\0') usage();
  677. X
  678. X        fmt[i].declarator_prefix = s;
  679. X        while (*s != '\0' && isascii(*s) && !isalnum(*s)) ++s;
  680. X        if (*s == '\0') usage();
  681. X        *s++ = '\0';
  682. X        while (*s != '\0' && isascii(*s) && isalnum(*s)) ++s;
  683. X        if (*s == '\0') usage();
  684. X
  685. X        fmt[i].declarator_suffix = s;
  686. X        while (*s != '\0' && *s != '(') ++s;
  687. X        if (*s == '\0') usage();
  688. X        *s++ = '\0';
  689. X
  690. X        fmt[i].first_param_prefix = s;
  691. X        while (*s != '\0' && isascii(*s) && !isalnum(*s)) ++s;
  692. X        if (*s == '\0') usage();
  693. X        *s++ = '\0';
  694. X        while (*s != '\0' && *s != ',') ++s;
  695. X        if (*s == '\0') usage();
  696. X
  697. X        fmt[i].middle_param_prefix = ++s;
  698. X        while (*s != '\0' && isascii(*s) && !isalnum(*s)) ++s;
  699. X        if (*s == '\0') usage();
  700. X        *s++ = '\0';
  701. X        while (*s != '\0' && isascii(*s) && isalnum(*s)) ++s;
  702. X        if (*s == '\0') usage();
  703. X
  704. X        fmt[i].last_param_suffix = s;
  705. X        while (*s != '\0' && *s != ')') ++s;
  706. X        *s = '\0';
  707. X
  708. X        break;
  709. X    case 'f':
  710. X        proto_style = atoi(optarg);
  711. X        if (proto_style < 0 || proto_style > PROTO_MACRO)
  712. X        usage();
  713. X        break;
  714. X    case 'm':
  715. X        macro_name = optarg;
  716. X        break;
  717. X    case 'n':
  718. X        file_comment_out = FALSE;
  719. X        break;
  720. X    case 'p':
  721. X        promote_param = FALSE;
  722. X        break;
  723. X    case 's':
  724. X        static_out = TRUE;
  725. X        break;
  726. X    case 't':
  727. X        func_style = FUNC_TRADITIONAL;
  728. X        break;
  729. X    case 'V':
  730. X        fprintf(stderr, "%s patchlevel %d\n", rcsid, PATCHLEVEL);
  731. X        break;
  732. X    case 'v':
  733. X        variables_out = TRUE;
  734. X        break;
  735. X    default:
  736. X        usage();
  737. X    }
  738. X    }
  739. X
  740. X    *pargc = argc;
  741. X    *pargv = argv;
  742. X}
  743. X
  744. Xint
  745. Xmain (argc, argv)
  746. Xint argc;
  747. Xchar **argv;
  748. X{
  749. X    int i;
  750. X    FILE *inf;
  751. X#ifdef CPP
  752. X    unsigned n;
  753. X    char *cmd;
  754. X
  755. X    /* Allocate buffer for C preprocessor command line. */
  756. X    n = strlen(CPP) + 1;
  757. X    for (i = 0; i < argc; ++i) {
  758. X    n += strlen(argv[i]) + 1;
  759. X    }
  760. X    cpp_cmd = xmalloc(n);
  761. X    strcpy(cpp_cmd, CPP);
  762. X    cmd = xmalloc(n);
  763. X#endif
  764. X    process_options(&argc, &argv);
  765. X
  766. X    if (proto_style == PROTO_MACRO && define_macro) {
  767. X    printf("#if defined(__STDC__) || defined(__cplusplus)\n");
  768. X    printf("#define %s(s) s\n", macro_name);
  769. X    printf("#else\n");
  770. X    printf("#define %s(s) ()\n", macro_name);
  771. X    printf("#endif\n\n");
  772. X    }
  773. X
  774. X    init_parser();
  775. X    if (optind == argc) {
  776. X    if (func_style != FUNC_NONE) {
  777. X        proto_style = PROTO_NONE;
  778. X        variables_out = FALSE;
  779. X        file_comment_out = FALSE;
  780. X    }
  781. X    process_file(stdin, "stdin");
  782. X    pop_file();
  783. X    } else {
  784. X    for (i = optind; i < argc; ++i) {
  785. X#ifdef CPP
  786. X        if (func_style == FUNC_NONE) {
  787. X        sprintf(cmd, "%s %s", cpp_cmd, argv[i]);
  788. X        if ((inf = popen(cmd, "r")) == NULL) {
  789. X            fprintf(stderr, "%s: error running cpp\n", progname);
  790. X            continue;
  791. X        }
  792. X        } else {
  793. X        if ((inf = fopen(argv[i], "r")) == NULL) {
  794. X            fprintf(stderr, "%s: cannot read file %s\n", progname,
  795. X            argv[i]);
  796. X            continue;
  797. X        }
  798. X        }
  799. X#else
  800. X        if ((inf = fopen(argv[i], "r")) == NULL) {
  801. X        fprintf(stderr, "%s: cannot read file %s\n", progname, argv[i]);
  802. X        continue;
  803. X        }
  804. X#endif
  805. X        process_file(inf, argv[i]);
  806. X#ifdef CPP
  807. X        if (func_style == FUNC_NONE) {
  808. X        pclose(inf);
  809. X        } else {
  810. X        pop_file();
  811. X        }
  812. X#else
  813. X        pop_file();
  814. X#endif
  815. X    }
  816. X    }
  817. X
  818. X    if (proto_style == PROTO_MACRO && define_macro) {
  819. X    printf("\n#undef %s\n", macro_name);
  820. X    }
  821. X
  822. X    return 0;
  823. X}
  824. END_OF_cproto.c
  825. if test 10336 -ne `wc -c <cproto.c`; then
  826.     echo shar: \"cproto.c\" unpacked with wrong size!
  827. fi
  828. # end of overwriting check
  829. fi
  830. if test -f popen.c -a "${1}" != "-c" ; then 
  831.   echo shar: Will not over-write existing file \"popen.c\"
  832. else
  833. echo shar: Extracting \"popen.c\" \(1567 characters\)
  834. sed "s/^X//" >popen.c <<'END_OF_popen.c'
  835. X/* $Id: popen.c 3.2 92/03/14 11:58:07 cthuang Exp $
  836. X *
  837. X * Imitate a UNIX pipe in MS-DOS.
  838. X */
  839. X#include <stdio.h>
  840. X#include <stdlib.h>
  841. X#include <process.h>
  842. X#include <io.h>
  843. X#include "cproto.h"
  844. X
  845. Xstatic char pipe_name[FILENAME_MAX];    /* name of the temporary file */
  846. X
  847. X/* Open a pipe for reading.
  848. X */
  849. XFILE *
  850. Xpopen (cmd, type)
  851. Xchar *cmd, *type;
  852. X{
  853. X    char *tmpdir, *argv[30], **arg, *cmdline, *s, opt[FILENAME_MAX];
  854. X    int ostdout, status;
  855. X
  856. X    /* Set temporary file name. */
  857. X    if ((tmpdir = getenv("TMP")) == NULL) {
  858. X    pipe_name[0] = '\0';
  859. X    } else {
  860. X    strcpy(pipe_name, tmpdir);
  861. X    trim_path_sep(pipe_name);
  862. X    strcat(pipe_name, "/");
  863. X    }
  864. X    strcat(pipe_name, tmpnam(NULL));
  865. X
  866. X    /* Split the command into an argument array. */
  867. X    cmdline = xstrdup(cmd);
  868. X    arg = argv;
  869. X    s = strtok(cmdline, " ");
  870. X    *arg++ = s;
  871. X#ifdef M_I86
  872. X    sprintf(opt, "-o%s.", pipe_name);
  873. X#else
  874. X    sprintf(opt, "-o%s", pipe_name);
  875. X#endif
  876. X    *arg++ = opt;
  877. X    while ((s = strtok(NULL, " ")) != NULL) {
  878. X    *arg++ = s;
  879. X    }
  880. X    *arg = NULL;
  881. X    /* Redirect the program's stdout to /dev/null. */
  882. X    ostdout = dup(fileno(stdout));
  883. X    freopen("nul", "w", stdout);
  884. X    /* Run the program. */
  885. X    status = spawnvp(P_WAIT, argv[0], argv);
  886. X    /* Restore stdout. */
  887. X    dup2(ostdout, fileno(stdout));
  888. X    free(cmdline);
  889. X
  890. X    if (status != 0)
  891. X    return NULL;
  892. X    /* Open the intermediate file and return the stream. */
  893. X    return fopen(pipe_name, type) ;
  894. X}
  895. X/* Close the pipe.
  896. X */
  897. Xint
  898. Xpclose (f)
  899. XFILE *f;
  900. X{
  901. X    int status;
  902. X    status = fclose(f);
  903. X    unlink(pipe_name);
  904. X    return status;
  905. X}
  906. END_OF_popen.c
  907. if test 1567 -ne `wc -c <popen.c`; then
  908.     echo shar: \"popen.c\" unpacked with wrong size!
  909. fi
  910. # end of overwriting check
  911. fi
  912. if test -f semantic.c -a "${1}" != "-c" ; then 
  913.   echo shar: Will not over-write existing file \"semantic.c\"
  914. else
  915. echo shar: Extracting \"semantic.c\" \(18260 characters\)
  916. sed "s/^X//" >semantic.c <<'END_OF_semantic.c'
  917. X/* $Id: semantic.c 3.3 92/03/14 11:58:17 cthuang Exp $
  918. X *
  919. X * Semantic actions executed by the parser of the
  920. X * C function prototype generator.
  921. X */
  922. X#include <stdio.h>
  923. X#include "cproto.h"
  924. X#include "semantic.h"
  925. X
  926. X/* Head function declarator in a prototype or function definition */
  927. Xstatic Declarator *func_declarator;
  928. X
  929. X/* Where the declarator appears */
  930. Xstatic int where;
  931. X
  932. X/* Output format to use */
  933. Xstatic int format;
  934. X
  935. X/* Initialize a new declaration specifier part.
  936. X */
  937. Xvoid
  938. Xnew_decl_spec (decl_spec, text, offset, flags)
  939. XDeclSpec *decl_spec;
  940. Xchar *text;
  941. Xlong offset;
  942. Xint flags;
  943. X{
  944. X    decl_spec->text = xstrdup(text);
  945. X    decl_spec->begin = offset;
  946. X    decl_spec->flags = flags;
  947. X}
  948. X
  949. X/* Free storage used by a declaration specifier part.
  950. X */
  951. Xvoid
  952. Xfree_decl_spec (decl_spec)
  953. XDeclSpec *decl_spec;
  954. X{
  955. X    free(decl_spec->text);
  956. X}
  957. X
  958. X/* Create a new string by joining two strings with a space between them.
  959. X * Return a pointer to the resultant string.
  960. X * If out of memory, output an error message and exit.
  961. X */
  962. Xstatic char *
  963. Xconcat_string (a, b)
  964. Xchar *a, *b;
  965. X{
  966. X    char *result;
  967. X
  968. X    result = xmalloc(strlen(a) + strlen(b) + 2);
  969. X    strcpy(result, a);
  970. X    strcat(result, " ");
  971. X    strcat(result, b);
  972. X    return result;
  973. X}
  974. X
  975. X/* Append two declaration specifier parts together.
  976. X */
  977. Xvoid
  978. Xjoin_decl_specs (result, a, b)
  979. XDeclSpec *result, *a, *b;
  980. X{
  981. X    result->text = concat_string(a->text, b->text);
  982. X    result->flags = a->flags | b->flags;
  983. X    result->begin = a->begin;
  984. X}
  985. X
  986. X/* Output an error message if the declaration specifier is an untagged
  987. X * struct, union or enum.
  988. X */
  989. Xvoid
  990. Xcheck_untagged (decl_spec)
  991. XDeclSpec *decl_spec;
  992. X{
  993. X    if (strstr(decl_spec->text, "struct {}") != NULL) {
  994. X    put_error();
  995. X    fputs("untagged struct declaration\n", stderr);
  996. X    } else if (strstr(decl_spec->text, "union {}") != NULL) {
  997. X    put_error();
  998. X    fputs("untagged union declaration\n", stderr);
  999. X    } else if (strstr(decl_spec->text, "enum {}") != NULL) {
  1000. X    put_error();
  1001. X    fputs("untagged enum declaration\n", stderr);
  1002. X    }
  1003. X}
  1004. X
  1005. X/* Allocate and initialize a declarator.
  1006. X */
  1007. XDeclarator *
  1008. Xnew_declarator (text, name, offset)
  1009. Xchar *text, *name;
  1010. Xlong offset;
  1011. X{
  1012. X    Declarator *d;
  1013. X
  1014. X    d = (Declarator *)xmalloc(sizeof(Declarator));
  1015. X    d->text = xstrdup(text);
  1016. X    d->name = xstrdup(name);
  1017. X    d->begin = offset;
  1018. X    d->begin_comment = d->end_comment = 0;
  1019. X    d->func_def = FUNC_NONE;
  1020. X    new_ident_list(&d->params);
  1021. X    d->head = d;
  1022. X    d->func_stack = NULL;
  1023. X    return d;
  1024. X}
  1025. X
  1026. X/* Free storage used by a declarator.
  1027. X */
  1028. Xvoid
  1029. Xfree_declarator (d)
  1030. XDeclarator *d;
  1031. X{
  1032. X    free(d->text);
  1033. X    free(d->name);
  1034. X    free_param_list(&(d->params));
  1035. X    if (d->func_stack != NULL)
  1036. X    free_declarator(d->func_stack);
  1037. X    free(d);
  1038. X}
  1039. X
  1040. X/* Initialize a declarator list and add the given declarator to it.
  1041. X */
  1042. Xvoid
  1043. Xnew_decl_list (decl_list, declarator)
  1044. XDeclaratorList *decl_list;
  1045. XDeclarator *declarator;
  1046. X{
  1047. X    decl_list->first = decl_list->last = declarator;
  1048. X    declarator->next = NULL;
  1049. X}
  1050. X
  1051. X/* Free storage used by the declarators in the declarator list.
  1052. X */
  1053. Xvoid
  1054. Xfree_decl_list (decl_list)
  1055. XDeclaratorList *decl_list;
  1056. X{
  1057. X    Declarator *d, *next;
  1058. X
  1059. X    d = decl_list->first;
  1060. X    while (d != NULL) {
  1061. X    next = d->next;
  1062. X    free_declarator(d);
  1063. X    d = next;
  1064. X    }
  1065. X}
  1066. X
  1067. X/* Add the declarator to the declarator list.
  1068. X */
  1069. Xvoid
  1070. Xadd_decl_list (to, from, declarator)
  1071. XDeclaratorList *to, *from;
  1072. XDeclarator *declarator;
  1073. X{
  1074. X    to->first = from->first;
  1075. X    from->last->next = declarator;
  1076. X    to->last = declarator;
  1077. X    to->last->next = NULL;
  1078. X}
  1079. X
  1080. X/* Initialize the parameter structure.
  1081. X */
  1082. Xvoid
  1083. Xnew_parameter (param, decl_spec, declarator)
  1084. XParameter *param;        /* parameter to be initialized */
  1085. XDeclSpec *decl_spec;
  1086. XDeclarator *declarator;
  1087. X{
  1088. X    if (decl_spec == NULL) {
  1089. X    new_decl_spec(&(param->decl_spec), "", 0L, DS_JUNK);
  1090. X    } else {
  1091. X    param->decl_spec = *decl_spec;
  1092. X    }
  1093. X
  1094. X    if (declarator == NULL) {
  1095. X    declarator = new_declarator("", "", 0L);
  1096. X    }
  1097. X    param->declarator = declarator;
  1098. X
  1099. X    param->comment = NULL;
  1100. X}
  1101. X
  1102. X/* Free the storage used by the parameter.
  1103. X */
  1104. Xvoid
  1105. Xfree_parameter (param)
  1106. XParameter *param;
  1107. X{
  1108. X    free_decl_spec(&(param->decl_spec));
  1109. X    free_declarator(param->declarator);
  1110. X    if (param->comment != NULL)
  1111. X    free(param->comment);
  1112. X}
  1113. X
  1114. X/* Return TRUE if the parameter is void.
  1115. X */
  1116. Xboolean
  1117. Xis_void_parameter (p)
  1118. XParameter *p;
  1119. X{
  1120. X    return p == NULL || (strcmp(p->decl_spec.text, "void") == 0 &&
  1121. X    strlen(p->declarator->text) == 0);
  1122. X}
  1123. X
  1124. X/* Initialize a list of function parameters.
  1125. X */
  1126. Xvoid
  1127. Xnew_param_list (param_list, param)
  1128. XParameterList *param_list;
  1129. XParameter *param;
  1130. X{
  1131. X    Parameter *p;
  1132. X
  1133. X    p = (Parameter *)xmalloc(sizeof(Parameter));
  1134. X    *p = *param;
  1135. X    
  1136. X    param_list->first = param_list->last = p;
  1137. X    p->next = NULL;
  1138. X
  1139. X    param_list->begin_comment = param_list->end_comment = 0;
  1140. X    param_list->comment = NULL;
  1141. X}
  1142. X
  1143. X/* Free storage used by the elements in the function parameter list.
  1144. X */
  1145. Xvoid
  1146. Xfree_param_list (param_list)
  1147. XParameterList *param_list;
  1148. X{
  1149. X    Parameter *p, *next;
  1150. X
  1151. X    p = param_list->first;
  1152. X    while (p != NULL) {
  1153. X    next = p->next;
  1154. X    free_parameter(p);
  1155. X    free(p);
  1156. X    p = next;
  1157. X    }
  1158. X
  1159. X    if (param_list->comment != NULL)
  1160. X    free(param_list->comment);
  1161. X}
  1162. X
  1163. X/* Add the function parameter declaration to the list.
  1164. X */
  1165. Xvoid
  1166. Xadd_param_list (to, from, param)
  1167. XParameterList *to, *from;
  1168. XParameter *param;
  1169. X{
  1170. X    Parameter *p;
  1171. X
  1172. X    p = (Parameter *)xmalloc(sizeof(Parameter));
  1173. X    *p = *param;
  1174. X
  1175. X    to->first = from->first;
  1176. X    from->last->next = p;
  1177. X    to->last = p;
  1178. X    p->next = NULL;
  1179. X}
  1180. X
  1181. X/* Initialize an empty list of function parameter names.
  1182. X */
  1183. Xvoid
  1184. Xnew_ident_list (param_list)
  1185. XParameterList *param_list;
  1186. X{
  1187. X    param_list->first = param_list->last = NULL;
  1188. X    param_list->begin_comment = param_list->end_comment = 0;
  1189. X    param_list->comment = NULL;
  1190. X}
  1191. X
  1192. X/* Add an item to the list of function parameter declarations but set only
  1193. X * the parameter name field.
  1194. X */
  1195. Xvoid
  1196. Xadd_ident_list (to, from, name)
  1197. XParameterList *to, *from;
  1198. Xchar *name;
  1199. X{
  1200. X    Parameter *p;
  1201. X    Declarator *declarator;
  1202. X
  1203. X    p = (Parameter *)xmalloc(sizeof(Parameter));
  1204. X    declarator = new_declarator(name, name, 0L);
  1205. X    new_parameter(p, NULL, declarator);
  1206. X
  1207. X    to->first = from->first;
  1208. X    if (to->first == NULL) {
  1209. X    to->first = p;
  1210. X    } else {
  1211. X    from->last->next = p;
  1212. X    }
  1213. X    to->last = p;
  1214. X    p->next = NULL;
  1215. X}
  1216. X
  1217. X/* Search the list of parameters for a matching parameter name.
  1218. X * Return a pointer to the matching parameter or NULL if not found.
  1219. X */
  1220. Xstatic Parameter *
  1221. Xsearch_parameter_list (params, name)
  1222. XParameterList *params;
  1223. Xchar *name;
  1224. X{
  1225. X    Parameter *p;
  1226. X
  1227. X    for (p = params->first; p != NULL; p = p->next) {
  1228. X    if (strcmp(p->declarator->name, name) == 0)
  1229. X        return p;
  1230. X    }
  1231. X    return (Parameter *)NULL;
  1232. X}
  1233. X
  1234. X/* For each name in the declarator list <declarators>, set the declaration
  1235. X * specifier part of the parameter in <params> having the same name.
  1236. X * This is also where we promote formal parameters.  Parameters of type
  1237. X * "char", "unsigned char", "short", or "unsigned short" are promoted to
  1238. X * "int".  Parameters of type "float" are promoted to "double".
  1239. X */
  1240. Xvoid
  1241. Xset_param_types (params, decl_spec, declarators)
  1242. XParameterList *params;
  1243. XDeclSpec *decl_spec;
  1244. XDeclaratorList *declarators;
  1245. X{
  1246. X    Declarator *d;
  1247. X    Parameter *p;
  1248. X    char *decl_spec_text;
  1249. X
  1250. X    for (d = declarators->first; d != NULL; d = d->next) {
  1251. X    /* Search the parameter list for a matching name. */
  1252. X    p = search_parameter_list(params, d->name);
  1253. X    if (p == NULL) {
  1254. X        put_error();
  1255. X        fprintf(stderr, "declared argument \"%s\" is missing\n", d->name);
  1256. X    } else {
  1257. X        decl_spec_text = decl_spec->text;
  1258. X        if (promote_param && strcmp(d->text, d->name) == 0) {
  1259. X        if (decl_spec->flags & (DS_CHAR | DS_SHORT))
  1260. X            decl_spec_text = "int";
  1261. X        else if (decl_spec->flags & DS_FLOAT)
  1262. X            decl_spec_text = "double";
  1263. X        }
  1264. X        free(p->decl_spec.text);
  1265. X        p->decl_spec.text = xstrdup(decl_spec_text);
  1266. X
  1267. X        free_declarator(p->declarator);
  1268. X        p->declarator = d;
  1269. X    }
  1270. X    }
  1271. X}
  1272. X
  1273. Xstatic void put_declarator();
  1274. X
  1275. X/* Output a function parameter.
  1276. X */
  1277. Xstatic void
  1278. Xput_parameter (outf, p)
  1279. XFILE *outf;
  1280. XParameter *p;
  1281. X{
  1282. X    fputs(p->decl_spec.text, outf);
  1283. X    if (strlen(p->declarator->text) > 0) {
  1284. X    if (strcmp(p->declarator->text, "...") != 0)
  1285. X        fputc(' ', outf);
  1286. X    put_declarator(outf, p->declarator);
  1287. X    }
  1288. X}
  1289. X
  1290. X/* Output parameter type list. */
  1291. X
  1292. Xstatic void
  1293. Xput_parameters (outf, declarator)
  1294. XFILE *outf;
  1295. XDeclarator *declarator;
  1296. X{
  1297. X    Parameter *p;
  1298. X    int f;
  1299. X
  1300. X    if (where == FUNC_DEF && func_style == FUNC_TRADITIONAL) {
  1301. X
  1302. X    /* Output traditional style parameter name list. */
  1303. X    p = declarator->params.first;
  1304. X
  1305. X    /* Output paramter name list only for head function declarator. */
  1306. X    if (!is_void_parameter(p) && declarator == func_declarator) {
  1307. X        fputs(fmt[format].first_param_prefix, outf);
  1308. X        fputs(p->declarator->name, outf);
  1309. X        p = p->next;
  1310. X        while (p != NULL && strcmp(p->declarator->text, "...") != 0) {
  1311. X        fputc(',', outf);
  1312. X        fputs(fmt[format].middle_param_prefix, outf);
  1313. X        fputs(p->declarator->name, outf);
  1314. X        p = p->next;
  1315. X        }
  1316. X        fputs(fmt[format].last_param_suffix, outf);
  1317. X    }
  1318. X    } else {
  1319. X
  1320. X    /* Output parameter type list. */
  1321. X    if (where == FUNC_PROTO && proto_style == PROTO_TRADITIONAL &&
  1322. X        declarator == func_declarator)
  1323. X        fputs("/*", outf);
  1324. X
  1325. X    p = declarator->params.first;
  1326. X    if (is_void_parameter(p)) {
  1327. X        if (p != NULL || ((where == FUNC_PROTO || where == FUNC_DEF) &&
  1328. X        declarator == func_declarator))
  1329. X        fputs("void", outf);
  1330. X    } else {
  1331. X        f = (declarator == func_declarator) ? format : FMT_OTHER;
  1332. X
  1333. X        if (where == FUNC_DEF && declarator->params.comment != NULL)
  1334. X        fputs(declarator->params.comment, outf);
  1335. X        
  1336. X        fputs(fmt[f].first_param_prefix, outf);
  1337. X        put_parameter(outf, p);
  1338. X
  1339. X        while (p->next != NULL) {
  1340. X        fputc(',', outf);
  1341. X        if (where == FUNC_DEF && p->comment != NULL)
  1342. X            fputs(p->comment, outf);
  1343. X
  1344. X        p = p->next;
  1345. X        fputs(fmt[f].middle_param_prefix, outf);
  1346. X        put_parameter(outf, p);
  1347. X        }
  1348. X        if (where == FUNC_DEF && p->comment != NULL)
  1349. X        fputs(p->comment, outf);
  1350. X
  1351. X        fputs(fmt[f].last_param_suffix, outf);
  1352. X    }
  1353. X
  1354. X    if (where == FUNC_PROTO && proto_style == PROTO_TRADITIONAL &&
  1355. X        declarator == func_declarator)
  1356. X        fputs("*/", outf);
  1357. X    }
  1358. X}
  1359. X
  1360. X/* Output a function declarator.
  1361. X */
  1362. Xstatic void
  1363. Xput_func_declarator (outf, declarator)
  1364. XFILE *outf;
  1365. XDeclarator *declarator;
  1366. X{
  1367. X    char *s, *t, *decl_text;
  1368. X    int f;
  1369. X
  1370. X    /* Output declarator text before function declarator place holder. */
  1371. X    if ((s = strstr(declarator->text, "%s")) == NULL)
  1372. X    return;
  1373. X    *s = '\0';
  1374. X    fputs(declarator->text, outf);
  1375. X
  1376. X    /* Substitute place holder with function declarator. */
  1377. X    if (declarator->func_stack->func_def == FUNC_NONE) {
  1378. X
  1379. X    decl_text = declarator->func_stack->text;
  1380. X    if (strlen(declarator->name) == 0) {
  1381. X        fputs(decl_text, outf);
  1382. X    } else {
  1383. X
  1384. X        /* Output the declarator text before the declarator name. */
  1385. X        if ((t = strstr(decl_text, declarator->name)) == NULL)
  1386. X        return;
  1387. X        *t = '\0';
  1388. X        fputs(decl_text, outf);
  1389. X        *t = declarator->name[0];
  1390. X
  1391. X        /* Output the declarator prefix before the name. */
  1392. X        f = (declarator == func_declarator) ? format : FMT_OTHER;
  1393. X        if (strcmp(fmt[f].declarator_prefix, " ") != 0)
  1394. X        fputs(fmt[f].declarator_prefix, outf);
  1395. X
  1396. X        if (where == FUNC_PROTO && proto_style == PROTO_ABSTRACT &&
  1397. X        declarator != func_declarator)
  1398. X        fputs("/*", outf);
  1399. X
  1400. X        /* Output the declarator name. */
  1401. X        fputs(declarator->name, outf);
  1402. X
  1403. X        if (where == FUNC_PROTO && proto_style == PROTO_ABSTRACT &&
  1404. X        declarator != func_declarator)
  1405. X        fputs("*/", outf);
  1406. X
  1407. X        /* Output the remaining declarator text. */
  1408. X        fputs(t + strlen(declarator->name), outf);
  1409. X
  1410. X        /* Output the declarator suffix. */
  1411. X        fputs(fmt[f].declarator_suffix, outf);
  1412. X    }
  1413. X    } else {
  1414. X    put_func_declarator(outf, declarator->func_stack);
  1415. X    }
  1416. X    *s = '%';
  1417. X    s += 2;
  1418. X
  1419. X    /* Output declarator text up to but before parameters place holder. */
  1420. X    if ((t = strstr(s, "()")) == NULL)
  1421. X    return;
  1422. X    *t = '\0';
  1423. X    fputs(s, outf);
  1424. X
  1425. X    if (where == FUNC_PROTO && proto_style == PROTO_MACRO &&
  1426. X    declarator == func_declarator) {
  1427. X    fprintf(outf, " %s(", macro_name);
  1428. X    }
  1429. X
  1430. X    /* Substitute place holder with function parameters. */
  1431. X    fputc(*t++ = '(', outf);
  1432. X    put_parameters(outf, declarator);
  1433. X    fputs(t, outf);
  1434. X
  1435. X    if (where == FUNC_PROTO && proto_style == PROTO_MACRO &&
  1436. X    declarator == func_declarator) {
  1437. X    fputc(')', outf);
  1438. X    }
  1439. X}
  1440. X
  1441. X/* Output a declarator.
  1442. X */
  1443. Xstatic void
  1444. Xput_declarator (outf, declarator)
  1445. XFILE *outf;
  1446. XDeclarator *declarator;
  1447. X{
  1448. X    char *s;
  1449. X
  1450. X    if (declarator->func_def == FUNC_NONE) {
  1451. X    if (where == FUNC_PROTO && proto_style == PROTO_ABSTRACT &&
  1452. X        strlen(declarator->name) > 0) {
  1453. X        if ((s = strstr(declarator->text, declarator->name)) == NULL)
  1454. X        return;
  1455. X        *s = '\0';
  1456. X        fprintf(outf, "%s/*%s*/%s", declarator->text,
  1457. X        declarator->name, s + strlen(declarator->name));
  1458. X        *s = declarator->name[0];
  1459. X    } else {
  1460. X        fputs(declarator->text, outf);
  1461. X    }
  1462. X    } else {
  1463. X    put_func_declarator(outf, declarator);
  1464. X    }
  1465. X}
  1466. X
  1467. X/* Output a declaration specifier for an external declaration.
  1468. X */
  1469. Xstatic void
  1470. Xput_decl_spec (outf, decl_spec)
  1471. XFILE *outf;
  1472. XDeclSpec *decl_spec;
  1473. X{
  1474. X    if (extern_out && (decl_spec->flags & DS_STATIC) == 0) {
  1475. X    if (strstr(decl_spec->text, "extern") == NULL) {
  1476. X        fputs("extern ", outf);
  1477. X    }
  1478. X    }
  1479. X    fputs(decl_spec->text, outf);
  1480. X    fputc(' ', outf);
  1481. X}
  1482. X
  1483. X/* Generate variable declarations.
  1484. X */
  1485. Xvoid
  1486. Xgen_declarations (decl_spec, decl_list)
  1487. XDeclSpec *decl_spec;        /* declaration specifier */
  1488. XDeclaratorList *decl_list;    /* list of declared variables */
  1489. X{
  1490. X    Declarator *d;
  1491. X
  1492. X    if (!variables_out || (decl_spec->flags & DS_JUNK))
  1493. X    return;
  1494. X    if (!static_out && (decl_spec->flags & DS_STATIC))
  1495. X    return;
  1496. X
  1497. X    func_declarator = NULL;
  1498. X    where = FUNC_OTHER;
  1499. X    format = FMT_OTHER;
  1500. X    for (d = decl_list->first; d != NULL; d = d->next) {
  1501. X    if (d->func_def == FUNC_NONE) {
  1502. X        fputs(fmt[FMT_PROTO].decl_spec_prefix, stdout);
  1503. X        put_decl_spec(stdout, decl_spec);
  1504. X        put_declarator(stdout, d);
  1505. X        fputs(";\n", stdout);
  1506. X    }
  1507. X    }
  1508. X}
  1509. X
  1510. X/* If a parameter name appears in the parameter list of a traditional style
  1511. X * function definition but is not declared in the parameter declarations,
  1512. X * then assign it the default type "int".
  1513. X */
  1514. Xstatic void
  1515. Xset_param_decl_spec (declarator)
  1516. XDeclarator *declarator;
  1517. X{
  1518. X    Parameter *p;
  1519. X
  1520. X    for (p = declarator->params.first; p != NULL; p = p->next) {
  1521. X    if (strlen(p->decl_spec.text) == 0 &&
  1522. X        strcmp(p->declarator->text, "...") != 0) {
  1523. X        free(p->decl_spec.text);
  1524. X        p->decl_spec.text = xstrdup("int");
  1525. X    }
  1526. X    }
  1527. X}
  1528. X
  1529. X/* Generate a function prototype.
  1530. X */
  1531. Xvoid
  1532. Xgen_prototype (decl_spec, declarator)
  1533. XDeclSpec *decl_spec;
  1534. XDeclarator *declarator;
  1535. X{
  1536. X    if (proto_style == PROTO_NONE)
  1537. X    return;
  1538. X    if (decl_spec->flags & DS_JUNK)
  1539. X    return;
  1540. X    if (!static_out && (decl_spec->flags & DS_STATIC))
  1541. X    return;
  1542. X
  1543. X    func_declarator = declarator->head;
  1544. X    set_param_decl_spec(func_declarator);
  1545. X
  1546. X    where = FUNC_PROTO;
  1547. X    format = FMT_PROTO;
  1548. X    fputs(fmt[format].decl_spec_prefix, stdout);
  1549. X    put_decl_spec(stdout, decl_spec);
  1550. X    put_func_declarator(stdout, declarator);
  1551. X    fputs(";\n", stdout);
  1552. X}
  1553. X
  1554. X/* Generate a declarator for a function pointer declarator or prototype.
  1555. X */
  1556. Xvoid
  1557. Xgen_func_declarator (declarator)
  1558. XDeclarator *declarator;
  1559. X{
  1560. X    /* Go to the beginning of the function declarator in the temporary
  1561. X     * file and overwrite it with the converted declarator.
  1562. X     */
  1563. X    fseek(cur_tmp_file(), declarator->begin, 0);
  1564. X    func_declarator = NULL;
  1565. X    where = FUNC_DEF;
  1566. X    format = FMT_FUNC;
  1567. X    put_func_declarator(cur_tmp_file(), declarator);
  1568. X    cur_file_changed();
  1569. X}
  1570. X
  1571. X/* Generate a function definition head.
  1572. X */
  1573. Xvoid
  1574. Xgen_func_definition (decl_spec, declarator)
  1575. XDeclSpec *decl_spec;
  1576. XDeclarator *declarator;
  1577. X{
  1578. X    Parameter *p;
  1579. X    ParameterList *params;
  1580. X    char *comment;
  1581. X    int comment_len, n;
  1582. X
  1583. X    /* Return if the function is already defined in the desired style. */
  1584. X    if (declarator->func_def == func_style)
  1585. X    return;
  1586. X
  1587. X    /* Save the text between the function head and the function body.
  1588. X     * Read the temporary file from after the last ) or ; to the
  1589. X     * end of the file.
  1590. X     */
  1591. X    comment_len = (int)(ftell(cur_tmp_file()) - begin_comment);
  1592. X    comment = xmalloc(comment_len);
  1593. X    fseek(cur_tmp_file(), begin_comment, 0);
  1594. X    fread(comment, sizeof(char), comment_len, cur_tmp_file());
  1595. X
  1596. X    func_declarator = declarator->head;
  1597. X    format = FMT_FUNC;
  1598. X
  1599. X    /* Save the text before the parameter declarations. */
  1600. X    if (func_style == FUNC_ANSI) {
  1601. X    params = &func_declarator->params;
  1602. X    n = (int)(params->end_comment - params->begin_comment);
  1603. X    if (n > 0) {
  1604. X        params->comment = xmalloc(n+1);
  1605. X        fseek(cur_tmp_file(), params->begin_comment, 0);
  1606. X        fread(params->comment, sizeof(char), n, cur_tmp_file());
  1607. X        params->comment[n] = '\0';
  1608. X        format = FMT_FUNC_COMMENT;
  1609. X    }
  1610. X    }
  1611. X
  1612. X    /* Get the parameter comments. */
  1613. X    for (p = func_declarator->params.first; p != NULL; p = p->next) {
  1614. X    n = (int)(p->declarator->end_comment - p->declarator->begin_comment);
  1615. X    if (n > 0) {
  1616. X        p->comment = xmalloc(n+1);
  1617. X        fseek(cur_tmp_file(), p->declarator->begin_comment, 0);
  1618. X        fread(p->comment, sizeof(char), n, cur_tmp_file());
  1619. X        p->comment[n] = '\0';
  1620. X        format = FMT_FUNC_COMMENT;
  1621. X    }
  1622. X    }
  1623. X
  1624. X    set_param_decl_spec(func_declarator);
  1625. X
  1626. X    /* Go to the beginning of the function head in the temporary file
  1627. X     * and overwrite it with the converted function head.
  1628. X     */
  1629. X    fseek(cur_tmp_file(), decl_spec->begin, 0);
  1630. X
  1631. X    /* Output declarator specifiers. */
  1632. X    fputs(fmt[format].decl_spec_prefix, cur_tmp_file());
  1633. X    fputs(decl_spec->text, cur_tmp_file());
  1634. X    fputc(' ', cur_tmp_file());
  1635. X
  1636. X    /* Output function declarator. */
  1637. X    where = FUNC_DEF;
  1638. X    put_func_declarator(cur_tmp_file(), declarator);
  1639. X
  1640. X    if (func_style == FUNC_TRADITIONAL) {
  1641. X    /* Output traditional style parameter declarations. */
  1642. X    p = func_declarator->params.first;
  1643. X    if (!is_void_parameter(p)) {
  1644. X        fputc('\n', cur_tmp_file());
  1645. X        put_parameter(cur_tmp_file(), p);
  1646. X        fputc(';', cur_tmp_file());
  1647. X        p = p->next;
  1648. X        while (p != NULL && strcmp(p->declarator->text, "...") != 0) {
  1649. X        fputc('\n', cur_tmp_file());
  1650. X        put_parameter(cur_tmp_file(), p);
  1651. X        fputc(';', cur_tmp_file());
  1652. X        p = p->next;
  1653. X        }
  1654. X    }
  1655. X    }
  1656. X
  1657. X    /* Output text between function head and body. */
  1658. X    fwrite(comment, sizeof(char), comment_len, cur_tmp_file());
  1659. X    free(comment);
  1660. X
  1661. X    cur_file_changed();
  1662. X}
  1663. END_OF_semantic.c
  1664. if test 18260 -ne `wc -c <semantic.c`; then
  1665.     echo shar: \"semantic.c\" unpacked with wrong size!
  1666. fi
  1667. # end of overwriting check
  1668. fi
  1669. if test -f strstr.c -a "${1}" != "-c" ; then 
  1670.   echo shar: Will not over-write existing file \"strstr.c\"
  1671. else
  1672. echo shar: Extracting \"strstr.c\" \(547 characters\)
  1673. sed "s/^X//" >strstr.c <<'END_OF_strstr.c'
  1674. X/* $Id: strstr.c 3.2 92/03/06 00:51:10 cthuang Exp $
  1675. X *
  1676. X * Simple implementation of the ANSI strstr() function
  1677. X */
  1678. X#include <stdio.h>
  1679. X#include "config.h"
  1680. X
  1681. X/* Search for a substring within the given string.
  1682. X * Return a pointer to the first occurence within the string,
  1683. X * or NULL if not found.
  1684. X */
  1685. Xchar *
  1686. Xstrstr (src, key)
  1687. Xchar *src, *key;
  1688. X{
  1689. X    char *s;
  1690. X    int keylen;
  1691. X
  1692. X    keylen = strlen(key);
  1693. X    s = strchr(src, *key);
  1694. X    while (s != NULL) {
  1695. X    if (strncmp(s, key, keylen) == 0)
  1696. X        return s;
  1697. X    s = strchr(s+1, *key);
  1698. X    }
  1699. X    return NULL;
  1700. X}
  1701. END_OF_strstr.c
  1702. if test 547 -ne `wc -c <strstr.c`; then
  1703.     echo shar: \"strstr.c\" unpacked with wrong size!
  1704. fi
  1705. # end of overwriting check
  1706. fi
  1707. if test -f symbol.c -a "${1}" != "-c" ; then 
  1708.   echo shar: Will not over-write existing file \"symbol.c\"
  1709. else
  1710. echo shar: Extracting \"symbol.c\" \(2326 characters\)
  1711. sed "s/^X//" >symbol.c <<'END_OF_symbol.c'
  1712. X/* $Id: symbol.c 3.1 92/03/03 10:43:52 cthuang Exp $
  1713. X *
  1714. X * Implements a symbol table abstract data type.
  1715. X */
  1716. X#include <stdio.h>
  1717. X#include "cproto.h"
  1718. X#include "symbol.h"
  1719. X
  1720. X
  1721. X/* Create a symbol table.
  1722. X * Return a pointer to the symbol table or NULL if an error occurs.
  1723. X */
  1724. XSymbolTable *
  1725. Xnew_symbol_table ()
  1726. X{
  1727. X    SymbolTable *symtab;
  1728. X    int i;
  1729. X
  1730. X    if ((symtab = (SymbolTable *)xmalloc(sizeof(SymbolTable))) != NULL) {
  1731. X    for (i = 0; i < SYM_MAX_HASH; ++i)
  1732. X        symtab->bucket[i] = NULL;
  1733. X    }
  1734. X    return symtab;
  1735. X}
  1736. X
  1737. X
  1738. X/* Free the memory allocated to the symbol table.
  1739. X */
  1740. Xvoid
  1741. Xfree_symbol_table (symtab)
  1742. XSymbolTable *symtab;
  1743. X{
  1744. X    int i;
  1745. X    Symbol *sym, *next;
  1746. X
  1747. X    for (i = 0; i < SYM_MAX_HASH; ++i) {
  1748. X    sym = symtab->bucket[i];
  1749. X    while (sym != NULL) {
  1750. X        next = sym->next;
  1751. X        free(sym->name);
  1752. X        free(sym);
  1753. X        sym = next;
  1754. X    }
  1755. X    }
  1756. X}
  1757. X
  1758. X
  1759. X/* This is a simple hash function mapping a symbol name to a hash bucket. */
  1760. X
  1761. Xstatic unsigned
  1762. Xhash (name)
  1763. Xchar *name;
  1764. X{
  1765. X    char *s;
  1766. X    unsigned h;
  1767. X
  1768. X    h = 0;
  1769. X    s = name;
  1770. X    while (*s != '\0')
  1771. X    h = (h << 1) ^ *s++;
  1772. X    return h % SYM_MAX_HASH;
  1773. X}
  1774. X
  1775. X
  1776. X/* Search the list of symbols <list> for the symbol <name>.
  1777. X * Return a pointer to the symbol or NULL if not found.
  1778. X */
  1779. Xstatic Symbol *
  1780. Xsearch_symbol_list (list, name)
  1781. XSymbol *list;
  1782. Xchar *name;
  1783. X{
  1784. X    Symbol *sym;
  1785. X
  1786. X    for (sym = list; sym != NULL; sym = sym->next) {
  1787. X    if (strcmp(sym->name, name) == 0)
  1788. X        return sym;
  1789. X    }
  1790. X    return NULL;
  1791. X}
  1792. X
  1793. X
  1794. X/* Look for symbol <name> in symbol table <symtab>.
  1795. X * Return a pointer to the symbol or NULL if not found.
  1796. X */
  1797. XSymbol *
  1798. Xfind_symbol (symtab, name)
  1799. XSymbolTable *symtab;
  1800. Xchar *name;
  1801. X{
  1802. X    return search_symbol_list(symtab->bucket[hash(name)], name);
  1803. X}
  1804. X
  1805. X
  1806. X/* If the symbol <name> does not already exist in symbol table <symtab>,
  1807. X * then add the symbol to the symbol table.
  1808. X * Return a pointer to the symbol or NULL on an error.
  1809. X */
  1810. XSymbol *
  1811. Xnew_symbol (symtab, name, flags)
  1812. XSymbolTable *symtab;    /* symbol table */
  1813. Xchar *name;        /* symbol name */
  1814. Xint flags;        /* symbol attributes */
  1815. X{
  1816. X    Symbol *sym;
  1817. X    int i;
  1818. X
  1819. X    if ((sym = find_symbol(symtab, name)) == NULL) {
  1820. X    if ((sym = (Symbol *)xmalloc(sizeof(Symbol))) != NULL) {
  1821. X        sym->name = xstrdup(name);
  1822. X        sym->flags = flags;
  1823. X        i = hash(name);
  1824. X        sym->next = symtab->bucket[i];
  1825. X        symtab->bucket[i] = sym;
  1826. X    }
  1827. X    }
  1828. X    return sym;
  1829. X}
  1830. END_OF_symbol.c
  1831. if test 2326 -ne `wc -c <symbol.c`; then
  1832.     echo shar: \"symbol.c\" unpacked with wrong size!
  1833. fi
  1834. # end of overwriting check
  1835. fi
  1836. echo shar: End of shell archive.
  1837. exit 0
  1838.  
  1839. exit 0 # Just in case...
  1840.