home *** CD-ROM | disk | FTP | other *** search
/ Dream 48 / Amiga_Dream_48.iso / Atari / c / cpp.zoo / src / main.c < prev    next >
C/C++ Source or Header  |  1993-06-03  |  6KB  |  287 lines

  1. #include <stdio.h>
  2. #include <stddef.h>
  3. #include <stdlib.h>
  4. #include <signal.h>
  5. #include <time.h>
  6. #include "global.h"
  7. #include "ztype.h"
  8. #include "patchlev.h"
  9.  
  10. FILE *outf = stdout;
  11. FILE *inf = NULL;
  12. char *argv0;
  13. char **I_list;
  14. char date_string[12], time_string[9];
  15. int nerrs;
  16.  
  17. int sl_style = SL_NORMAL, keep_comments = 0, do_trigraphs = 0, ansi = 0, w_bad_chars = 1, w_nest_cmts = 0, f_cpp_cmts = 0;
  18.  
  19. static void usage()
  20. {
  21.   fprintf(stderr, "usage: %s [-Dname[=value]...] [-Uname] "
  22.       "[ infile [ outfile ] ]\n", argv0
  23.   );
  24.   exit(1);
  25. }
  26.  
  27. static void dammit(sig)
  28.   int sig;
  29. {
  30.   fatal("received signal %d", sig);
  31. }
  32.  
  33. static void setup_signals()
  34. {
  35.   signal(SIGHUP, dammit);
  36.   signal(SIGINT, dammit);
  37.   signal(SIGQUIT, dammit);
  38.   signal(SIGILL, dammit);
  39.   signal(SIGTRAP, dammit);
  40.   signal(SIGABRT, dammit);
  41.   signal(SIGEMT, dammit);
  42.   signal(SIGFPE, dammit);
  43.   signal(SIGBUS, dammit);
  44.   signal(SIGSEGV, dammit);
  45.   signal(SIGSYS, dammit);
  46.   signal(SIGPIPE, dammit);
  47.   signal(SIGALRM, dammit);
  48.   signal(SIGTERM, dammit);
  49. }
  50.  
  51. /* add_include() -- adds |path| to the list of include directories */
  52. static void add_include(path)
  53.   char *path;
  54. {
  55.   static char **cur_I = NULL;
  56.   static int n_I;
  57.   ptrdiff_t dp;
  58.  
  59.   if (!cur_I)
  60.     cur_I = I_list = (char **)mallok((n_I = 3) * sizeof (char *));
  61.  
  62.   if (cur_I - I_list == n_I) {
  63.     dp = cur_I - I_list;
  64.     I_list = reallok(I_list, (n_I *= 2) * sizeof (char *));
  65.  
  66.     cur_I = I_list + dp;
  67.   }
  68.   *cur_I++ = path;
  69. }
  70.  
  71. /* long_option() -- parses long option |s| */
  72. static void long_option(s)
  73.   char *s;
  74. {
  75.   int yesno = 1;
  76.   char *t;
  77.  
  78.   if (*s == 'W' || *s == 'f') {
  79.     if (s[1] == 'n' && s[2] == 'o' && s[3] == '-') {
  80.       yesno = 0;
  81.       t += 4;
  82.     } else
  83.       t = s + 1;
  84.     if (*s == 'W') {        /* warnings */
  85.       if (streq(t, "bad-chars"))
  86.     w_bad_chars = yesno;
  87.       else if (streq(t, "nested-comments"))
  88.     w_nest_cmts = yesno;
  89.       else {
  90.     error("unknown -W option:  %s", t);
  91.     usage();
  92.       }
  93.     } else {            /* actions */
  94.       if (streq(t, "c++-comments"))
  95.     f_cpp_cmts = yesno;
  96.       else {
  97.     error("unknown -f option:  %s", t);
  98.     usage();
  99.       }
  100.     }
  101.   } else if (streq(s, "ansi")) {
  102.     ansi = 1;
  103.     do_trigraphs ^= 1;
  104.   } else {
  105.     error("unrecognized option -%s", s);
  106.     usage();
  107.   }
  108. }
  109.  
  110. /*
  111.    opt_define() -- handle -Dfred.  |s| points to the beginning of the token
  112.    to #define.
  113. */
  114. static void opt_define(s)
  115.   char *s;
  116. {
  117.   Macro *M, *M1;
  118.   char *t;
  119.   unsigned int hv;
  120.   int hmm = 0;
  121.  
  122.   hv = hash_id(s, &t);
  123.   if (*t && *t != '=') {
  124.     error("malformed -D option \"%s\"", s);
  125.     return;
  126.   }
  127.   if (*t)
  128.     *t++ = '\0';
  129.   else
  130.     t = "1";
  131.   M1 = (Macro *)mallok(sizeof (Macro));
  132.  
  133.   M1->nargs = M1->flags = 0;
  134.   M1->m_text = tokenize_string(t);
  135.   if (M = lookup(s, hv)) {
  136.  
  137.     /*
  138.        guard against re-#definition of magic tokens or previously -U'd tokens
  139.     */
  140.     if (M->flags & (UNDEF | MAGIC))
  141.       hmm = 1;
  142.     if (hmm || !macro_eq(M1, M)) {
  143.       if (!hmm)
  144.     error("non-identical redefinition of \"%s\"", s);
  145.     }
  146.     free_tlist(M1->m_text);
  147.     free(M1);
  148.     return;
  149.   }
  150.   hash_add(s, hv, M1);
  151. }
  152.  
  153. /*
  154.    opt_undefine() -- handle -Ufred.  |s| points to the beginning of the token
  155.    to #undef.
  156. */
  157. static void opt_undefine(s)
  158.   char *s;
  159. {
  160.   Token T;
  161.   Macro *M;
  162.   int was_there = 0;
  163.   unsigned int hv;
  164.  
  165.   hv = hash_id(s, NULL);
  166.   if (M = lookup(s, hv)) {
  167.     if (M->flags & MAGIC)
  168.       return;
  169.     if (M->m_text)
  170.       free_tlist(M->m_text);
  171.     was_there = 1;
  172.   } else {
  173.     M = (Macro *)mallok(sizeof (Macro));
  174.  
  175.     M->nargs = M->flags = 0;
  176.   }
  177.   M->m_text = NULL;
  178.   M->flags |= UNDEF;
  179.   if (!was_there)
  180.     hash_add(s, hv, M);
  181. }
  182.  
  183. /* main() -- guess... */
  184. main(argc, argv)
  185.   int argc;
  186.   char **argv;
  187. {
  188.   int i;
  189.   char *infnam;
  190.   int num_Is = 3;
  191.   char **cur_I, *incdir;
  192.   time_t t;
  193.   struct tm *T;
  194.  
  195.   argv0 = argv[0];
  196.   Z_type_init();
  197.   hash_setup();
  198.   cond_setup();
  199.   setup_signals();
  200.   time(&t);
  201.   T = localtime(&t);
  202.   strftime(date_string, 12, "%b %d %Y", T);
  203.   strftime(time_string, 9, "%H:%M:%S", T);
  204.   add_include(NULL);
  205.   for (i = 1; i < argc && *argv[i] == '-' && argv[i][1] != '\0'; i++) {
  206.     switch (argv[i][1]) {
  207.     case 'P':
  208.       switch (argv[i][2]) {
  209.       case '0':
  210.       case '\0':
  211.     sl_style = SL_NONE;
  212.     break;
  213.       case '1':
  214.     sl_style = SL_NORMAL;
  215.     break;
  216.       case '2':
  217.     sl_style = SL_LINE;
  218.     break;
  219.       default:
  220.     error("bad argument '%c' to -P option", argv[i][2]);
  221.       }
  222.       break;
  223.     case 'C':
  224.       keep_comments = 1;
  225.       break;
  226.     case 'T':
  227.       do_trigraphs ^= 1;
  228.       break;
  229.     case 'I':
  230.       add_include(copy_filename(argv[i] + 2, 0), 0);
  231.       break;
  232.     case 'D':
  233.       opt_define(argv[i] + 2);
  234.       break;
  235.     case 'U':
  236.       opt_undefine(argv[i] + 2);
  237.       break;
  238.     case 'V':
  239.       fprintf(stderr, "CPP -- C preprocessor v%d.%d.%d\n"
  240.           "(c) 1993 Hacker Ltd., all rights reserved\n",
  241.           CPP_VERSION, CPP_RELEASE, CPP_PATCHLEVEL);
  242.       break;
  243.     default:
  244.       long_option(argv[i] + 1);
  245.     }
  246.   }
  247.   hash_clean_undef();
  248.   if (incdir = getenv("INCLUDE")) {
  249.     char *s = incdir;
  250.     size_t len;
  251.  
  252.     while (*s) {
  253.       len = strcspn(s, ";,");
  254.       add_include(copy_filename(s, len));
  255.       s += len;
  256.       if (*s)
  257.     s++;
  258.     }
  259.   }
  260.   add_include(NULL);
  261.   if (argc - i > 2) {
  262.     error("too many arguments");
  263.     usage();
  264.   }
  265.   if (i < argc && !streq(argv[i], "-"))
  266.     infnam = copy_filename(argv[i], 0);
  267.   else
  268.     infnam = STDIN_NAME;
  269.   if (i + 1 < argc && (streq(argv[i + 1], "-") || !(outf = xfopen(argv[i + 1], "w"))))
  270.     fatal("%s: cannot open output file %s", argv0, argv[i + 1]);
  271.   process_file(infnam);
  272.   free(infnam);
  273.   for (cur_I = I_list + 1; *cur_I; cur_I++)
  274.     if (*cur_I)
  275.       free(*cur_I);
  276.   free(I_list);
  277.   fclose(outf);
  278.   hash_free();
  279.   cond_shutdown();
  280.   tok_shutdown();
  281.   if (nerrs > 0) {
  282.     fprintf(stderr, "%d errors\n", nerrs);
  283.     return 1;
  284.   }
  285.   return 0;
  286. }
  287.