home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 4 / FreshFish_May-June1994.bin / bbs / gnu / m4-1.1-src.lha / src / amiga / m4-1.1 / m4.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-09  |  9.9 KB  |  452 lines

  1. /* GNU m4 -- A simple macro processor
  2.    Copyright (C) 1989, 90, 91, 92, 93 Free Software Foundation, Inc.
  3.   
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 2, or (at your option)
  7.    any later version.
  8.   
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.   
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18.  
  19. #include "m4.h"
  20. #include "getopt.h"
  21. #include <sys/types.h>
  22. #include <sys/signal.h>
  23.  
  24. static void usage ();
  25.  
  26. /* Current version numbers.  */
  27. static const char version[] = "1.1";
  28.  
  29. /* Operate interactively (-e).  */
  30. static int interactive = 0;
  31.  
  32. /* Enable sync output for /lib/cpp (-s).  */
  33. int sync_output = 0;
  34.  
  35. /* Debug (-d[flags]).  */
  36. int debug_level = 0;
  37.  
  38. /* Hash table size (should be a prime) (-Hsize).  */
  39. int hash_table_size = HASHMAX;
  40.  
  41. /* Number of diversions allocated.  */
  42. int ndiversion = NDIVERSIONS;
  43.  
  44. /* Disable GNU extensions (-G).  */
  45. int no_gnu_extensions = 0;
  46.  
  47. /* Max length of arguments in trace output (-lsize).  */
  48. int max_debug_argument_length = 0;
  49.  
  50. /* Suppress warnings about missing arguments.  */
  51. int suppress_warnings = 0;
  52.  
  53. /* The name this program was run with. */
  54. const char *program_name;
  55.  
  56. /* If non-zero, display usage information and exit.  */
  57. static int show_help;
  58.  
  59. /* If non-zero, print the version on standard output and exit.  */
  60. static int show_version;
  61.  
  62. struct macro_definition
  63. {
  64.   struct macro_definition *next;
  65.   int code;            /* D, U or t */
  66.   char *macro;
  67. };
  68. typedef struct macro_definition macro_definition;
  69.  
  70. /* Error handling functions.  */
  71.  
  72. /*----------------------------------------------.
  73. | Basic varargs function for all error output.  |
  74. `----------------------------------------------*/
  75.  
  76. static void
  77. vmesg (char *level, va_list args)
  78. {
  79.   char *fmt;
  80.  
  81.   fflush (stdout);
  82.   fmt = va_arg (args, char *);
  83.   fprintf (stderr, "%s:%s:%d: ", program_name, current_file, current_line);
  84.   if (level != NULL)
  85.     fprintf (stderr, "%s: ", level);
  86.   vfprintf (stderr, fmt, args);
  87.   putc ('\n', stderr);
  88. }
  89.  
  90. /*-----------------------------------------.
  91. | Internal errors -- print and dump core.  |
  92. `-----------------------------------------*/
  93.  
  94. volatile void
  95. internal_error (va_alist)
  96.     va_dcl
  97. {
  98.   va_list args;
  99.   va_start (args);
  100.   vmesg ("INTERNAL ERROR", args);
  101.   va_end (args);
  102.  
  103.   abort ();
  104. }
  105.  
  106. /*--------------------------------.
  107. | Fatal error -- print and exit.  |
  108. `--------------------------------*/
  109.  
  110. volatile void
  111. fatal (va_alist)
  112.     va_dcl
  113. {
  114.   va_list args;
  115.   va_start (args);
  116.   vmesg ("ERROR", args);
  117.   va_end (args);
  118.  
  119.   exit (1);
  120. }
  121.  
  122. /*----------------------------------.
  123. | "Normal" error -- just complain.  |
  124. `----------------------------------*/
  125.  
  126. void
  127. m4error (va_alist)
  128.     va_dcl
  129. {
  130.   va_list args;
  131.   va_start (args);
  132.   vmesg ((char *) NULL, args);
  133.   va_end (args);
  134. }
  135.  
  136. /*------------------------------------.
  137. | Warning --- for potential trouble.  |
  138. `------------------------------------*/
  139.  
  140. void
  141. warning (va_alist)
  142.     va_dcl
  143. {
  144.   va_list args;
  145.   va_start (args);
  146.   vmesg ("Warning", args);
  147.   va_end (args);
  148. }
  149.  
  150. /* Memory allocation.  */
  151.  
  152. /*------------------------.
  153. | Failsafe free routine.  |
  154. `------------------------*/
  155.  
  156. void
  157. xfree (void *p)
  158. {
  159.   if (p != NULL)
  160.     free (p);
  161. }
  162.  
  163.  
  164. /*---------------------------------------------.
  165. | Print a usage message and exit with STATUS.  |
  166. `---------------------------------------------*/
  167.  
  168. static void
  169. usage (int status)
  170. {
  171.   if (status != 0)
  172.     fprintf (stderr, "Try `%s --help' for more information.\n", program_name);
  173.   else
  174.     {
  175.       printf ("Usage: %s [OPTION]... [FILE]...\n", program_name);
  176.       printf ("\
  177. \n\
  178.   -D, --define=NAME[=VALUE]   enter NAME has having VALUE, or empty\n\
  179.   -G, --traditional           suppress all GNU extensions\n\
  180.   -H, --hashsize=PRIME        set symbol lookup hash table size\n\
  181.   -I, --include=DIRECTORY     search this directory second for includes\n\
  182.   -N, --diversions=NUMBER     select number of simultaneous diversions\n\
  183.   -P, --prefix-builtins       force a `m4_' prefix to all builtins\n\
  184.   -Q, --quiet, --silent       suppress some warnings for builtins\n\
  185.   -U, --undefine=NAME         delete builtin NAME\n\
  186.   -d, --debug=[FLAGS]         set debug level\n\
  187.   -e, --interactive           unbuffer output, ignore interrupts\n\
  188.   -l, --arglength=NUM         restrict macro tracing size\n\
  189.   -o, --error-output=FILE     redirect debug and trace output\n\
  190.   -s, --synclines             generate `#line NO \"FILE\"' lines\n\
  191.   -t, --trace=NAME            trace NAME when it will be defined\n\
  192.       --help                  display this help and exit\n\
  193.       --version               output version information and exit\n\
  194. \n\
  195. If no FILE or if FILE is `-', standard input is read.\n");
  196.     }
  197.   exit (status);
  198. }
  199.  
  200. /*--------------------------------------.
  201. | Decode options and launch execution.  |
  202. `--------------------------------------*/
  203.  
  204. static const struct option long_options[] =
  205. {
  206.   {"arglength", required_argument, NULL, 'l'},
  207.   {"debug", optional_argument, NULL, 'd'},
  208.   {"diversions", required_argument, NULL, 'N'},
  209.   {"erroroutput", required_argument, NULL, 'o'},
  210.   {"hashsize", required_argument, NULL, 'H'},
  211.   {"include", required_argument, NULL, 'I'},
  212.   {"interactive", no_argument, NULL, 'e'},
  213.   {"prefix-builtins", no_argument, NULL, 'P'},
  214.   {"quiet", no_argument, NULL, 'Q'},
  215.   {"silent", no_argument, NULL, 'Q'},
  216.   {"synclines", no_argument, NULL, 's'},
  217.   {"traditional", no_argument, NULL, 'G'},
  218.  
  219.   {"help", no_argument, &show_help, 1},
  220.   {"version", no_argument, &show_version, 1},
  221.  
  222.   /* These are somewhat troublesome.  */
  223.   { "define", required_argument, NULL, 'D' },
  224.   { "undefine", required_argument, NULL, 'U' },
  225.   { "trace", required_argument, NULL, 't' },
  226.  
  227.   { 0, 0, 0, 0 },
  228. };
  229.  
  230. #define OPTSTRING "B:D:GH:I:N:PQS:T:U:d::el:o:st:"
  231.  
  232. int
  233. main (int argc, char *const *argv)
  234. {
  235.   macro_definition *head;    /* head of deferred argument list */
  236.   macro_definition *tail;
  237.   macro_definition *new;
  238.   int optchar;            /* option character */
  239.  
  240.   macro_definition *defines;
  241.   FILE *fp;
  242.  
  243.   program_name = rindex (argv[0], '/');
  244.   if (program_name == NULL)
  245.     program_name = argv[0];
  246.   else
  247.     program_name++;
  248.  
  249.   include_init ();
  250.   debug_init ();
  251.  
  252.   /* First, we decode the arguments, to size up tables and stuff.  */
  253.  
  254.   head = tail = NULL;
  255.  
  256.   while (optchar = getopt_long (argc, argv, OPTSTRING, long_options, NULL),
  257.      optchar != EOF)
  258.     switch (optchar)
  259.       {
  260.       default:
  261.     usage (1);
  262.  
  263.       case 0:
  264.     break;
  265.  
  266.       case 'e':
  267.     interactive = 1;
  268.     break;
  269.  
  270.       case 's':
  271.     sync_output = 1;
  272.     break;
  273.  
  274.       case 'G':
  275.     no_gnu_extensions = 1;
  276.     break;
  277.  
  278.       case 'Q':
  279.     suppress_warnings = 1;
  280.     break;
  281.  
  282.       case 'd':
  283.     debug_level = debug_decode (optarg);
  284.     if (debug_level < 0)
  285.       {
  286.         error (0, 0, "bad debug flags: `%s'", optarg);
  287.         debug_level = 0;
  288.       }
  289.     break;
  290.  
  291.       case 'l':
  292.     max_debug_argument_length = atoi (optarg);
  293.     if (max_debug_argument_length <= 0)
  294.       max_debug_argument_length = 0;
  295.     break;
  296.  
  297.       case 'o':
  298.     if (!debug_set_output (optarg))
  299.       error (0, errno, optarg);
  300.     break;
  301.  
  302.       case 'H':
  303.     hash_table_size = atoi (optarg);
  304.     if (hash_table_size <= 0)
  305.       hash_table_size = HASHMAX;
  306.     break;
  307.  
  308.       case 'N':
  309.     ndiversion = atoi (optarg);
  310.     if (ndiversion <= 0)
  311.       ndiversion = NDIVERSIONS;
  312.     break;
  313.  
  314.       case 'I':
  315.     add_include_directory (optarg);
  316.     break;
  317.  
  318.       case 'B':            /* compatibility junk */
  319.       case 'S':
  320.       case 'T':
  321.     break;
  322.  
  323.       case 'D':
  324.       case 'U':
  325.       case 't':
  326.  
  327.     /* Arguments that cannot be handled until later are accumulated.  */
  328.  
  329.     new = (macro_definition *) xmalloc (sizeof (macro_definition));
  330.     new->code = optchar;
  331.     new->macro = optarg;
  332.     new->next = NULL;
  333.  
  334.     if (head == NULL)
  335.       head = new;
  336.     else
  337.       tail->next = new;
  338.     tail = new;
  339.  
  340.     break;
  341.  
  342.       case 'P':
  343.     prefix_all_builtins ();
  344.     break;
  345.       }
  346.  
  347.   if (show_version)
  348.     {
  349.       printf ("GNU m4 %s\n", version);
  350.       exit (0);
  351.     }
  352.  
  353.   if (show_help)
  354.     usage (0);
  355.  
  356.   defines = head;
  357.  
  358.   /* Do the basic initialisations.  */
  359.  
  360.   input_init ();
  361.   output_init ();
  362.   symtab_init ();
  363.   builtin_init ();
  364.   include_env_init ();
  365.  
  366.   /* Handle deferred command line macro definitions.  Must come after
  367.      initialisation of the symbol table.  */
  368.  
  369.   while (defines != NULL)
  370.     {
  371.       macro_definition *next;
  372.       char *macro_value;
  373.       symbol *sym;
  374.  
  375.       switch (defines->code)
  376.     {
  377.     case 'D':
  378.       macro_value = index (defines->macro, '=');
  379.       if (macro_value == NULL)
  380.         macro_value = "";
  381.       else
  382.         *macro_value++ = '\0';
  383.       define_user_macro (defines->macro, macro_value, SYMBOL_INSERT);
  384.       break;
  385.  
  386.     case 'U':
  387.       lookup_symbol (defines->macro, SYMBOL_DELETE);
  388.       break;
  389.  
  390.     case 't':
  391.       sym = lookup_symbol (defines->macro, SYMBOL_INSERT);
  392.       SYMBOL_TRACED (sym) = TRUE;
  393.       break;
  394.  
  395.     default:
  396.       internal_error ("bad code in deferred arguments.");
  397.     }
  398.  
  399.       next = defines->next;
  400.       xfree (defines);
  401.       defines = next;
  402.     }
  403.  
  404.   /* Interactive mode means unbuffered output, and interrupts ignored.  */
  405.  
  406.   if (interactive)
  407.     {
  408.       signal (SIGINT, SIG_IGN);
  409.       setbuf (stdout, (char *) NULL);
  410.     }
  411.  
  412.   /* Handle the various input files.  Each file is pushed on the input,
  413.      and the input read.  Wrapup text is handled separately later.  */
  414.  
  415.   if (optind == argc)
  416.     {
  417.       push_file (stdin, "stdin");
  418.       expand_input ();
  419.     }
  420.   else
  421.     for (; optind < argc; optind++)
  422.       {
  423.     if (strcmp (argv[optind], "-") == 0)
  424.       {
  425.         push_file (stdin, "stdin");
  426.       }
  427.     else
  428.       {
  429.         fp = path_search (argv[optind]);
  430.         if (fp == NULL)
  431.           {
  432.         error (0, errno, argv[optind]);
  433.         continue;
  434.           }
  435.         else
  436.           push_file (fp, argv[optind]);
  437.       }
  438.     expand_input ();
  439.       }
  440. #undef NEXTARG
  441.  
  442.   /* Now handle wrapup text.  */
  443.  
  444.   while (pop_wrapup ())
  445.     expand_input ();
  446.  
  447.   make_diversion (0);
  448.   undivert_all ();
  449.  
  450.   exit (0);
  451. }
  452.