* src/output.c (make_diversion): Avoid size_t overflow.
[m4.git] / src / m4.c
blob964eeeb3f08e99ae2614baff868e5630b29dd728
1 /* GNU m4 -- A simple macro processor
3 Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 2004, 2005, 2006 Free
4 Software Foundation, Inc.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA
22 #include "m4.h"
24 #include <getopt.h>
25 #include <limits.h>
26 #include <signal.h>
28 static void usage (int);
30 /* Enable sync output for /lib/cpp (-s). */
31 int sync_output = 0;
33 /* Debug (-d[flags]). */
34 int debug_level = 0;
36 /* Hash table size (should be a prime) (-Hsize). */
37 size_t hash_table_size = HASHMAX;
39 /* Disable GNU extensions (-G). */
40 int no_gnu_extensions = 0;
42 /* Prefix all builtin functions by `m4_'. */
43 int prefix_all_builtins = 0;
45 /* Max length of arguments in trace output (-lsize). */
46 int max_debug_argument_length = 0;
48 /* Suppress warnings about missing arguments. */
49 int suppress_warnings = 0;
51 /* If not zero, then value of exit status for warning diagnostics. */
52 int warning_status = 0;
54 /* Artificial limit for expansion_level in macro.c. */
55 int nesting_limit = 1024;
57 #ifdef ENABLE_CHANGEWORD
58 /* User provided regexp for describing m4 words. */
59 const char *user_word_regexp = "";
60 #endif
62 /* The name this program was run with. */
63 const char *program_name;
65 struct macro_definition
67 struct macro_definition *next;
68 int code; /* D, U or t */
69 const char *macro;
71 typedef struct macro_definition macro_definition;
73 /* Error handling functions. */
75 /*-----------------------.
76 | Wrapper around error. |
77 `-----------------------*/
79 void
80 m4_error (int status, int errnum, const char *format, ...)
82 va_list args;
83 va_start (args, format);
84 verror_at_line (status, errnum, current_line ? current_file : NULL,
85 current_line, format, args);
88 /*-------------------------------.
89 | Wrapper around error_at_line. |
90 `-------------------------------*/
92 void
93 m4_error_at_line (int status, int errnum, const char *file, int line,
94 const char *format, ...)
96 va_list args;
97 va_start (args, format);
98 verror_at_line (status, errnum, line ? file : NULL, line, format, args);
101 #ifdef USE_STACKOVF
103 /*---------------------------------------.
104 | Tell user stack overflowed and abort. |
105 `---------------------------------------*/
107 static void
108 stackovf_handler (void)
110 M4ERROR ((EXIT_FAILURE, 0,
111 "ERROR: stack overflow. (Infinite define recursion?)"));
114 #endif /* USE_STACKOV */
117 /*---------------------------------------------.
118 | Print a usage message and exit with STATUS. |
119 `---------------------------------------------*/
121 static void
122 usage (int status)
124 if (status != EXIT_SUCCESS)
125 fprintf (stderr, "Try `%s --help' for more information.\n", program_name);
126 else
128 printf ("Usage: %s [OPTION]... [FILE]...\n", program_name);
129 fputs ("\
130 Process macros in FILEs. If no FILE or if FILE is `-', standard input\n\
131 is read.\n\
132 ", stdout);
133 fputs ("\
135 Mandatory or optional arguments to long options are mandatory or optional\n\
136 for short options too.\n\
138 Operation modes:\n\
139 --help display this help and exit\n\
140 --version output version information and exit\n\
141 -E, --fatal-warnings stop execution after first warning\n\
142 -i, --interactive unbuffer output, ignore interrupts\n\
143 -P, --prefix-builtins force a `m4_' prefix to all builtins\n\
144 -Q, --quiet, --silent suppress some warnings for builtins\n\
145 ", stdout);
146 #ifdef ENABLE_CHANGEWORD
147 fputs ("\
148 -W, --word-regexp=REGEXP use REGEXP for macro name syntax\n\
149 ", stdout);
150 #endif
151 fputs ("\
153 Preprocessor features:\n\
154 -D, --define=NAME[=VALUE] define NAME as having VALUE, or empty\n\
155 -I, --include=DIRECTORY append DIRECTORY to include path\n\
156 -s, --synclines generate `#line NUM \"FILE\"' lines\n\
157 -U, --undefine=NAME undefine NAME\n\
158 ", stdout);
159 fputs ("\
161 Limits control:\n\
162 -G, --traditional suppress all GNU extensions\n\
163 -H, --hashsize=PRIME set symbol lookup hash table size [509]\n\
164 -L, --nesting-limit=NUMBER change artificial nesting limit [1024]\n\
165 ", stdout);
166 fputs ("\
168 Frozen state files:\n\
169 -F, --freeze-state=FILE produce a frozen state on FILE at end\n\
170 -R, --reload-state=FILE reload a frozen state from FILE at start\n\
171 ", stdout);
172 fputs ("\
174 Debugging:\n\
175 -d, --debug[=FLAGS] set debug level (no FLAGS implies `aeq')\n\
176 --debugfile=FILE redirect debug and trace output\n\
177 -l, --arglength=NUM restrict macro tracing size\n\
178 -t, --trace=NAME trace NAME when it is defined\n\
179 ", stdout);
180 fputs ("\
182 FLAGS is any of:\n\
183 a show actual arguments\n\
184 c show before collect, after collect and after call\n\
185 e show expansion\n\
186 f say current input file name\n\
187 i show changes in input files\n\
188 l say current input line number\n\
189 p show results of path searches\n\
190 q quote values as necessary, with a or e flag\n\
191 t trace for all macro calls, not only traceon'ed\n\
192 x add a unique macro call id, useful with c flag\n\
193 V shorthand for all of the above flags\n\
194 ", stdout);
195 fputs ("\
197 If defined, the environment variable `M4PATH' is a colon-separated list\n\
198 of directories included after any specified by `-I'.\n\
199 ", stdout);
200 fputs ("\
202 Exit status is 0 for success, 1 for failure, 63 for frozen file version\n\
203 mismatch, or whatever value was passed to the m4exit macro.\n\
204 ", stdout);
205 printf ("\nReport bugs to <%s>.\n", PACKAGE_BUGREPORT);
207 exit (status);
210 /*--------------------------------------.
211 | Decode options and launch execution. |
212 `--------------------------------------*/
214 /* For long options that have no equivalent short option, use a
215 non-character as a pseudo short option, starting with CHAR_MAX + 1. */
216 enum
218 DEBUGFILE_OPTION = CHAR_MAX + 1, /* no short opt */
219 DIVERSIONS_OPTION, /* not quite -N, because of message */
221 HELP_OPTION, /* no short opt */
222 VERSION_OPTION /* no short opt */
225 static const struct option long_options[] =
227 {"arglength", required_argument, NULL, 'l'},
228 {"debug", optional_argument, NULL, 'd'},
229 {"define", required_argument, NULL, 'D'},
230 {"error-output", required_argument, NULL, 'o'}, /* FIXME: deprecate in 2.0 */
231 {"fatal-warnings", no_argument, NULL, 'E'},
232 {"freeze-state", required_argument, NULL, 'F'},
233 {"hashsize", required_argument, NULL, 'H'},
234 {"include", required_argument, NULL, 'I'},
235 {"interactive", no_argument, NULL, 'i'},
236 {"nesting-limit", required_argument, NULL, 'L'},
237 {"prefix-builtins", no_argument, NULL, 'P'},
238 {"quiet", no_argument, NULL, 'Q'},
239 {"reload-state", required_argument, NULL, 'R'},
240 {"silent", no_argument, NULL, 'Q'},
241 {"synclines", no_argument, NULL, 's'},
242 {"trace", required_argument, NULL, 't'},
243 {"traditional", no_argument, NULL, 'G'},
244 {"undefine", required_argument, NULL, 'U'},
245 {"word-regexp", required_argument, NULL, 'W'},
247 {"debugfile", required_argument, NULL, DEBUGFILE_OPTION},
248 {"diversions", required_argument, NULL, DIVERSIONS_OPTION},
250 {"help", no_argument, NULL, HELP_OPTION},
251 {"version", no_argument, NULL, VERSION_OPTION},
253 { NULL, 0, NULL, 0 },
256 /* Global catchall for any errors that should affect final error status, but
257 where we try to continue execution in the meantime. */
258 int retcode;
260 #ifdef ENABLE_CHANGEWORD
261 #define OPTSTRING "B:D:EF:GH:I:L:N:PQR:S:T:U:W:d::eil:o:st:"
262 #else
263 #define OPTSTRING "B:D:EF:GH:I:L:N:PQR:S:T:U:d::eil:o:st:"
264 #endif
267 main (int argc, char *const *argv, char *const *envp)
269 macro_definition *head; /* head of deferred argument list */
270 macro_definition *tail;
271 macro_definition *new;
272 int optchar; /* option character */
274 macro_definition *defines;
275 FILE *fp;
276 boolean read_stdin = FALSE;
277 boolean interactive = FALSE;
278 const char *debugfile = NULL;
279 const char *frozen_file_to_read = NULL;
280 const char *frozen_file_to_write = NULL;
282 program_name = argv[0];
283 retcode = EXIT_SUCCESS;
284 atexit (close_stdout);
286 include_init ();
287 debug_init ();
288 #ifdef USE_STACKOVF
289 setup_stackovf_trap (argv, envp, stackovf_handler);
290 #endif
292 /* First, we decode the arguments, to size up tables and stuff. */
294 head = tail = NULL;
296 while (optchar = getopt_long (argc, (char **) argv, OPTSTRING,
297 long_options, NULL),
298 optchar != EOF)
299 switch (optchar)
301 default:
302 usage (EXIT_FAILURE);
304 case 'B':
305 case 'S':
306 case 'T':
307 /* Compatibility junk: options that other implementations
308 support, but which we ignore as no-ops and don't list in
309 --help. */
310 error (0, 0, "Warning: `m4 -%c' may be removed in a future release",
311 optchar);
312 break;
314 case 'N':
315 case DIVERSIONS_OPTION:
316 /* -N became an obsolete no-op in 1.4.x. */
317 error (0, 0, "Warning: `m4 %s' is deprecated",
318 optchar == 'N' ? "-N" : "--diversions");
320 case 'D':
321 case 'U':
322 case 't':
324 /* Arguments that cannot be handled until later are accumulated. */
326 new = (macro_definition *) xmalloc (sizeof (macro_definition));
327 new->code = optchar;
328 new->macro = optarg;
329 new->next = NULL;
331 if (head == NULL)
332 head = new;
333 else
334 tail->next = new;
335 tail = new;
337 break;
339 case 'E':
340 warning_status = EXIT_FAILURE;
341 break;
343 case 'F':
344 frozen_file_to_write = optarg;
345 break;
347 case 'G':
348 no_gnu_extensions = 1;
349 break;
351 case 'H':
352 hash_table_size = atol (optarg);
353 if (hash_table_size == 0)
354 hash_table_size = HASHMAX;
355 break;
357 case 'I':
358 add_include_directory (optarg);
359 break;
361 case 'L':
362 nesting_limit = atoi (optarg);
363 break;
365 case 'P':
366 prefix_all_builtins = 1;
367 break;
369 case 'Q':
370 suppress_warnings = 1;
371 break;
373 case 'R':
374 frozen_file_to_read = optarg;
375 break;
377 #ifdef ENABLE_CHANGEWORD
378 case 'W':
379 user_word_regexp = optarg;
380 break;
381 #endif
383 case 'd':
384 debug_level = debug_decode (optarg);
385 if (debug_level < 0)
387 error (0, 0, "bad debug flags: `%s'", optarg);
388 debug_level = 0;
390 break;
392 case 'e':
393 error (0, 0, "Warning: `m4 -e' is deprecated, use `-i' instead");
394 /* fall through */
395 case 'i':
396 interactive = TRUE;
397 break;
399 case 'l':
400 max_debug_argument_length = atoi (optarg);
401 if (max_debug_argument_length <= 0)
402 max_debug_argument_length = 0;
403 break;
405 case 'o':
406 /* -o/--error-output are deprecated synonyms of --debugfile,
407 but don't issue a deprecation warning until autoconf 2.61
408 or later is more widely established, as such a warning
409 would interfere with all earlier versions of autoconf. */
410 case DEBUGFILE_OPTION:
411 /* Don't call debug_set_output here, as it has side effects. */
412 debugfile = optarg;
413 break;
415 case 's':
416 sync_output = 1;
417 break;
419 case VERSION_OPTION:
420 printf ("%s\n", PACKAGE_STRING);
421 fputs ("\
422 Copyright (C) 2006 Free Software Foundation, Inc.\n\
423 This is free software; see the source for copying conditions. There is NO\n\
424 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
426 Written by Rene' Seindal.\n\
427 ", stdout);
428 exit (EXIT_SUCCESS);
429 break;
431 case HELP_OPTION:
432 usage (EXIT_SUCCESS);
433 break;
436 defines = head;
438 /* Do the basic initializations. */
439 if (debugfile && !debug_set_output (debugfile))
440 M4ERROR ((0, errno, "cannot set debug file `%s'", debugfile));
442 input_init ();
443 output_init ();
444 symtab_init ();
445 include_env_init ();
447 if (frozen_file_to_read)
448 reload_frozen_state (frozen_file_to_read);
449 else
450 builtin_init ();
452 /* Handle deferred command line macro definitions. Must come after
453 initialisation of the symbol table. */
455 while (defines != NULL)
457 macro_definition *next;
458 char *macro_value;
459 symbol *sym;
461 switch (defines->code)
463 case 'D':
464 macro_value = strchr (defines->macro, '=');
465 if (macro_value == NULL)
466 macro_value = "";
467 else
468 *macro_value++ = '\0';
469 define_user_macro (defines->macro, macro_value, SYMBOL_INSERT);
470 break;
472 case 'U':
473 lookup_symbol (defines->macro, SYMBOL_DELETE);
474 break;
476 case 't':
477 sym = lookup_symbol (defines->macro, SYMBOL_INSERT);
478 SYMBOL_TRACED (sym) = TRUE;
479 break;
481 default:
482 M4ERROR ((warning_status, 0,
483 "INTERNAL ERROR: bad code in deferred arguments"));
484 abort ();
487 next = defines->next;
488 free (defines);
489 defines = next;
492 /* Interactive mode means unbuffered output, and interrupts ignored. */
494 if (interactive)
496 signal (SIGINT, SIG_IGN);
497 setbuf (stdout, (char *) NULL);
500 /* Handle the various input files. Each file is pushed on the input,
501 and the input read. Wrapup text is handled separately later. */
503 if (optind == argc)
505 /* No point closing stdin until after wrapped text is
506 processed. */
507 push_file (stdin, "stdin", FALSE);
508 read_stdin = TRUE;
509 expand_input ();
511 else
512 for (; optind < argc; optind++)
514 if (strcmp (argv[optind], "-") == 0)
516 /* If stdin is a terminal, we want to allow 'm4 - file -'
517 to read input from stdin twice, like GNU cat. Besides,
518 there is no point closing stdin before wrapped text, to
519 minimize bugs in syscmd called from wrapped text. */
520 push_file (stdin, "stdin", FALSE);
521 read_stdin = TRUE;
523 else
525 const char *name;
526 fp = m4_path_search (argv[optind], &name);
527 if (fp == NULL)
529 error (0, errno, "%s", argv[optind]);
530 /* Set the status to EXIT_FAILURE, even though we
531 continue to process files after a missing file. */
532 retcode = EXIT_FAILURE;
533 continue;
535 push_file (fp, name, TRUE);
536 free ((char *) name);
538 expand_input ();
540 #undef NEXTARG
542 /* Now handle wrapup text. */
544 while (pop_wrapup ())
545 expand_input ();
547 /* Change debug stream back to stderr, to force flushing the debug
548 stream and detect any errors it might have encountered. Close
549 stdin if we read from it, to detect any errors. */
550 debug_set_output (NULL);
551 if (read_stdin && fclose (stdin) == EOF)
553 M4ERROR ((warning_status, errno, "error reading file"));
554 retcode = EXIT_FAILURE;
557 if (frozen_file_to_write)
558 produce_frozen_state (frozen_file_to_write);
559 else
561 make_diversion (0);
562 undivert_all ();
564 exit (retcode);