maint: run update-copyright for 2014.
[m4/ericb.git] / src / main.c
blobd8adabc78a05cf7c832b63cea53548f0e42bded9
1 /* GNU m4 -- A simple macro processor
3 Copyright (C) 1989-1994, 1999-2000, 2003-2010, 2013-2014 Free
4 Software Foundation, Inc.
6 This file is part of GNU M4.
8 GNU M4 is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 GNU M4 is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include <config.h>
24 #include <locale.h>
26 #include "m4.h"
28 #include "closein.h"
29 #include "configmake.h"
30 #include "getopt.h"
31 #include "propername.h"
32 #include "quotearg.h"
33 #include "version-etc.h"
34 #include "xstrtol.h"
36 #define AUTHORS \
37 proper_name_utf8 ("Rene' Seindal", "Ren\xc3\xa9 Seindal"), \
38 proper_name ("Gary V. Vaughan"), \
39 proper_name ("Eric Blake")
41 typedef struct deferred
43 struct deferred *next;
44 int code; /* deferred optchar */
45 const char *value;
46 } deferred;
49 /* Error handling functions. */
51 #ifdef USE_STACKOVF
53 /* Tell user stack overflowed and abort. */
54 static void
55 stackovf_handler (void)
57 /* FIXME - calling gettext and error inside a signal handler is dangerous,
58 since these functions invoke functions that are not signal-safe. We
59 are sort of justified by the fact that we will exit and never return,
60 but this should really be fixed. */
61 error (EXIT_FAILURE, 0, _("stack overflow (infinite define recursion?)"));
64 #endif /* USE_STACKOVF */
68 /* Print a usage message and exit with STATUS. */
69 static void
70 usage (int status)
72 if (status != EXIT_SUCCESS)
73 xfprintf (stderr, _("Try `%s --help' for more information.\n"),
74 m4_get_program_name ());
75 else
77 xprintf (_("Usage: %s [OPTION]... [FILE]...\n"), m4_get_program_name ());
78 fputs (_("\
79 Process macros in FILEs.\n\
80 If no FILE or if FILE is `-', standard input is read. If no FILE, and both\n\
81 standard input and standard error are terminals, -i is implied.\n\
82 "), stdout);
83 puts ("");
84 fputs (_("\
85 Mandatory or optional arguments to long options are mandatory or optional\n\
86 for short options too.\n\
87 \n\
88 Operation modes:\n\
89 --help display this help and exit\n\
90 --version output version information and exit\n\
91 "), stdout);
92 fputs (_("\
93 -b, --batch buffer output, process interrupts\n\
94 -c, --discard-comments do not copy comments to the output\n\
95 -E, --fatal-warnings once: warnings become errors, twice: stop\n\
96 execution at first error\n\
97 -i, --interactive unbuffer output, ignore interrupts\n\
98 -P, --prefix-builtins force a `m4_' prefix to all builtins\n\
99 -Q, --quiet, --silent suppress some warnings for builtins\n\
100 -r, --regexp-syntax[=SPEC] set default regexp syntax to SPEC [GNU_M4]\n\
101 --safer disable potentially unsafe builtins\n\
102 -W, --warnings enable all warnings\n\
103 "), stdout);
104 puts ("");
105 fputs (_("\
106 SPEC is any one of:\n\
107 AWK, BASIC, BSD_M4, ED, EMACS, EXTENDED, GNU_AWK, GNU_EGREP, GNU_M4,\n\
108 GREP, POSIX_AWK, POSIX_EGREP, MINIMAL, MINIMAL_BASIC, SED.\n\
109 "), stdout);
110 puts ("");
111 fputs (_("\
112 Preprocessor features:\n\
113 -B, --prepend-include=DIR add DIR to include path before `.'\n\
114 -D, --define=NAME[=VALUE] define NAME as having VALUE, or empty\n\
115 --import-environment import all environment variables as macros\n\
116 -I, --include=DIR add DIR to include path after `.'\n\
117 "), stdout);
118 fputs (_("\
119 --popdef=NAME popdef NAME\n\
120 -p, --pushdef=NAME[=VALUE] pushdef NAME as having VALUE, or empty\n\
121 -s, --synclines short for --syncoutput=1\n\
122 --syncoutput[=STATE] set generation of `#line NUM \"FILE\"' lines\n\
123 to STATE (0=off, 1=on, default 0)\n\
124 -U, --undefine=NAME undefine NAME\n\
125 "), stdout);
126 puts ("");
127 fputs (_("\
128 Limits control:\n\
129 -g, --gnu override -G to re-enable GNU extensions\n\
130 -G, --traditional, --posix suppress all GNU extensions\n\
131 -L, --nesting-limit=NUMBER change artificial nesting limit [1024]\n\
132 "), stdout);
133 puts ("");
134 fputs (_("\
135 Frozen state files:\n\
136 -F, --freeze-state=FILE produce a frozen state on FILE at end\n\
137 -R, --reload-state=FILE reload a frozen state from FILE at start\n\
138 "), stdout);
139 puts ("");
140 fputs (_("\
141 Debugging:\n\
142 -d, --debug[=[-|+]FLAGS], --debugmode[=[-|+]FLAGS]\n\
143 set debug level (no FLAGS implies `+adeq')\n\
144 --debugfile[=FILE] redirect debug and trace output to FILE\n\
145 (default stderr, discard if empty string)\n\
146 -l, --debuglen=NUM restrict macro tracing size\n\
147 -t, --trace=NAME, --traceon=NAME\n\
148 trace NAME when it is defined\n\
149 --traceoff=NAME no longer trace NAME\n\
150 "), stdout);
151 puts ("");
152 fputs (_("\
153 FLAGS is any of:\n\
154 a show actual arguments in trace\n\
155 c show collection line in trace\n\
156 d warn when dereferencing undefined macros (default on unless -E)\n\
157 e show expansion in trace\n\
158 f include current input file name in trace and debug\n\
159 i show changes in input files in debug\n\
160 l include current input line number in trace and debug\n\
161 "), stdout);
162 fputs (_("\
163 m show module information in trace, debug, and dumpdef\n\
164 o output dumpdef to stderr rather than debug file\n\
165 p show results of path searches in debug\n\
166 q quote values in dumpdef and trace, useful with a or e\n\
167 s show full stack of pushdef values in dumpdef\n\
168 t trace all macro calls, regardless of per-macro traceon state\n\
169 x include unique macro call id in trace, useful with c\n\
170 V shorthand for all of the above flags\n\
171 "), stdout);
172 puts ("");
173 fputs (_("\
174 If defined, the environment variable `M4PATH' is a colon-separated list\n\
175 of directories included after any specified by `-I' or `-B'. The\n\
176 environment variable `POSIXLY_CORRECT' implies -G -Q; otherwise GNU\n\
177 extensions are enabled by default.\n\
178 "), stdout);
179 puts ("");
180 fputs (_("\
181 Exit status is 0 for success, 1 for failure, 63 for frozen file version\n\
182 mismatch, or whatever value was passed to the m4exit macro.\n\
183 "), stdout);
184 emit_bug_reporting_address ();
186 exit (status);
189 /* For long options that have no equivalent short option, use a
190 non-character as a pseudo short option, starting with CHAR_MAX + 1. */
191 enum
193 ARGLENGTH_OPTION = CHAR_MAX + 1, /* not quite -l, because of message */
194 DEBUGFILE_OPTION, /* no short opt */
195 ERROR_OUTPUT_OPTION, /* not quite -o, because of message */
196 HASHSIZE_OPTION, /* not quite -H, because of message */
197 IMPORT_ENVIRONMENT_OPTION, /* no short opt */
198 POPDEF_OPTION, /* no short opt */
199 PREPEND_INCLUDE_OPTION, /* not quite -B, because of message */
200 SAFER_OPTION, /* -S still has old no-op semantics */
201 SYNCOUTPUT_OPTION, /* not quite -s, because of opt arg */
202 TRACEOFF_OPTION, /* no short opt */
203 WORD_REGEXP_OPTION, /* deprecated, used to be -W */
205 HELP_OPTION, /* no short opt */
206 VERSION_OPTION /* no short opt */
209 /* Decode options and launch execution. */
210 static const struct option long_options[] =
212 {"batch", no_argument, NULL, 'b'},
213 {"debug", optional_argument, NULL, 'd'},
214 {"debuglen", required_argument, NULL, 'l'},
215 {"debugmode", optional_argument, NULL, 'd'},
216 {"define", required_argument, NULL, 'D'},
217 {"discard-comments", no_argument, NULL, 'c'},
218 {"fatal-warnings", no_argument, NULL, 'E'},
219 {"freeze-state", required_argument, NULL, 'F'},
220 {"gnu", no_argument, NULL, 'g'},
221 {"include", required_argument, NULL, 'I'},
222 {"interactive", no_argument, NULL, 'i'},
223 {"nesting-limit", required_argument, NULL, 'L'},
224 {"posix", no_argument, NULL, 'G'},
225 {"prefix-builtins", no_argument, NULL, 'P'},
226 {"pushdef", required_argument, NULL, 'p'},
227 {"quiet", no_argument, NULL, 'Q'},
228 {"regexp-syntax", optional_argument, NULL, 'r'},
229 {"reload-state", required_argument, NULL, 'R'},
230 {"silent", no_argument, NULL, 'Q'},
231 {"synclines", no_argument, NULL, 's'},
232 {"trace", required_argument, NULL, 't'},
233 {"traceon", required_argument, NULL, 't'},
234 {"traditional", no_argument, NULL, 'G'},
235 {"undefine", required_argument, NULL, 'U'},
236 {"warnings", no_argument, NULL, 'W'},
238 {"arglength", required_argument, NULL, ARGLENGTH_OPTION},
239 {"debugfile", optional_argument, NULL, DEBUGFILE_OPTION},
240 {"hashsize", required_argument, NULL, HASHSIZE_OPTION},
241 {"error-output", required_argument, NULL, ERROR_OUTPUT_OPTION},
242 {"import-environment", no_argument, NULL, IMPORT_ENVIRONMENT_OPTION},
243 {"popdef", required_argument, NULL, POPDEF_OPTION},
244 {"prepend-include", required_argument, NULL, PREPEND_INCLUDE_OPTION},
245 {"safer", no_argument, NULL, SAFER_OPTION},
246 {"syncoutput", optional_argument, NULL, SYNCOUTPUT_OPTION},
247 {"traceoff", required_argument, NULL, TRACEOFF_OPTION},
248 {"word-regexp", required_argument, NULL, WORD_REGEXP_OPTION},
250 {"help", no_argument, NULL, HELP_OPTION},
251 {"version", no_argument, NULL, VERSION_OPTION},
253 { NULL, 0, NULL, 0 },
256 /* POSIX requires only -D, -U, and -s; and says that the first two
257 must be recognized when interspersed with file names. Traditional
258 behavior also handles -s between files. Starting OPTSTRING with
259 '-' forces getopt_long to hand back file names as arguments to opt
260 '\1', rather than reordering the command line. */
261 #define OPTSTRING "-B:D:EF:GH:I:L:PQR:S:T:U:Wbcd::egil:o:p:r::st:"
263 /* For determining whether to be interactive. */
264 enum interactive_choice
266 INTERACTIVE_UNKNOWN, /* Still processing arguments, no -b or -i yet */
267 INTERACTIVE_YES, /* -i specified last */
268 INTERACTIVE_NO /* -b specified last */
271 /* Convert OPT to size_t, reporting an error using long option index
272 OI or short option character OPTCHAR if it does not fit. */
273 static size_t
274 size_opt (char const *opt, int oi, int optchar)
276 unsigned long int size;
277 strtol_error status = xstrtoul (opt, NULL, 10, &size, "kKmMgGtTPEZY0");
278 if (SIZE_MAX < size && status == LONGINT_OK)
279 status = LONGINT_OVERFLOW;
280 if (status != LONGINT_OK)
281 xstrtol_fatal (status, oi, optchar, long_options, opt);
282 return size;
285 /* Process a command line file NAME. */
286 static bool
287 process_file (m4 *context, const char *name)
289 bool new_input = true;
291 if (STREQ (name, "-"))
292 /* TRANSLATORS: This is a short name for `standard input', used
293 when a command line file was given as `-'. */
294 m4_push_file (context, stdin, _("stdin"), false);
295 else
296 new_input = m4_load_filename (context, NULL, name, NULL, false);
298 if (new_input)
299 m4_macro_expand_input (context);
301 return new_input;
305 /* Main entry point. Parse arguments, load modules, then parse input. */
307 main (int argc, char *const *argv, char *const *envp)
309 deferred *head = NULL; /* head of deferred argument list */
310 deferred *tail = NULL;
311 deferred *defn;
312 size_t size; /* for parsing numeric option arguments */
314 bool import_environment = false; /* true to import environment */
315 bool seen_file = false;
316 const char *debugfile = NULL;
317 const char *frozen_file_to_read = NULL;
318 const char *frozen_file_to_write = NULL;
319 enum interactive_choice interactive = INTERACTIVE_UNKNOWN;
321 m4 *context;
323 int exit_status;
325 /* Initialize gnulib error module. */
326 m4_set_program_name (argv[0]);
327 atexit (close_stdin);
329 setlocale (LC_ALL, "");
330 #ifdef ENABLE_NLS
331 textdomain (PACKAGE);
332 #endif
334 context = m4_create ();
336 #ifdef USE_STACKOVF
337 setup_stackovf_trap (argv, envp, stackovf_handler);
338 #endif
340 if (getenv ("POSIXLY_CORRECT"))
342 m4_set_posixly_correct_opt (context, true);
343 m4_set_suppress_warnings_opt (context, true);
345 set_quoting_style (NULL, escape_quoting_style);
346 set_char_quoting (NULL, ':', 1);
348 /* First, we decode the arguments, to size up tables and stuff.
349 Avoid lasting side effects; for example 'm4 --debugfile=oops
350 --help' must not create the file `oops'. */
351 while (1)
353 int oi = -1;
354 int optchar = getopt_long (argc, (char **) argv, OPTSTRING,
355 long_options, &oi);
356 if (optchar == -1)
357 break;
359 switch (optchar)
361 default:
362 usage (EXIT_FAILURE);
364 case 'H':
365 case HASHSIZE_OPTION:
366 /* -H was supported in 1.4.x, but is a no-op now. FIXME -
367 remove support for -H after 2.0. */
368 error (0, 0, _("warning: `%s' is deprecated"),
369 optchar == 'H' ? "-H" : "--hashsize");
370 break;
372 case 'S':
373 case 'T':
374 /* Compatibility junk: options that other implementations
375 support, but which we ignore as no-ops and don't list in
376 --help. */
377 error (0, 0, _("warning: `-%c' is deprecated"),
378 optchar);
379 break;
381 case WORD_REGEXP_OPTION:
382 /* Supported in 1.4.x as -W, but no longer present. */
383 error (0, 0, _("warning: `%s' is deprecated"), "--word-regexp");
384 break;
386 case 's':
387 optchar = SYNCOUTPUT_OPTION;
388 optarg = "1";
389 /* fall through */
390 case 'D':
391 case 'U':
392 case 'p':
393 case 'r':
394 case 't':
395 case POPDEF_OPTION:
396 case SYNCOUTPUT_OPTION:
397 case TRACEOFF_OPTION:
398 defer:
399 /* Arguments that cannot be handled until later are accumulated. */
401 defn = (deferred *) xmalloc (sizeof *defn);
402 defn->code = optchar;
403 defn->value = optarg;
404 defn->next = NULL;
406 if (head == NULL)
407 head = defn;
408 else
409 tail->next = defn;
410 tail = defn;
411 break;
413 case '\1':
414 seen_file = true;
415 goto defer;
417 case 'B':
418 /* In 1.4.x, -B<num> was a no-op option for compatibility with
419 Solaris m4. Warn if optarg is all numeric. FIXME -
420 silence this warning after 2.0. */
421 if (isdigit (to_uchar (*optarg)))
423 char *end;
424 errno = 0;
425 strtol (optarg, &end, 10);
426 if (*end == '\0' && errno == 0)
427 error (0, 0, _("warning: recommend using `-B ./%s' instead"),
428 optarg);
430 /* fall through */
431 case PREPEND_INCLUDE_OPTION:
432 m4_add_include_directory (context, optarg, true);
433 break;
435 case 'E':
436 m4_debug_decode (context, "-d", SIZE_MAX);
437 if (m4_get_fatal_warnings_opt (context))
438 m4_set_warnings_exit_opt (context, true);
439 else
440 m4_set_fatal_warnings_opt (context, true);
441 break;
443 case 'F':
444 frozen_file_to_write = optarg;
445 break;
447 case 'G':
448 m4_set_posixly_correct_opt (context, true);
449 break;
451 case 'I':
452 m4_add_include_directory (context, optarg, false);
453 break;
455 case 'L':
456 size = size_opt (optarg, oi, optchar);
457 if (!size)
458 size = SIZE_MAX;
459 m4_set_nesting_limit_opt (context, size);
460 break;
462 case 'P':
463 m4_set_prefix_builtins_opt (context, true);
464 break;
466 case 'Q':
467 m4_set_suppress_warnings_opt (context, true);
468 break;
470 case 'R':
471 frozen_file_to_read = optarg;
472 break;
474 case 'W':
475 /* FIXME - should W take an optional argument, to allow -Wall,
476 -Wnone, -Werror, -Wcategory, -Wno-category? If so, then have
477 -W == -Wall. */
478 m4_set_suppress_warnings_opt (context, false);
479 break;
481 case 'b':
482 interactive = INTERACTIVE_NO;
483 break;
485 case 'c':
486 m4_set_discard_comments_opt (context, true);
487 break;
489 case 'd':
490 /* Staggered handling of 'd', since -dm is useful prior to
491 first file and prior to reloading, but other -d must also
492 have effect between files. */
493 if (seen_file || frozen_file_to_read)
494 goto defer;
495 if (m4_debug_decode (context, optarg, SIZE_MAX) < 0)
496 error (0, 0, _("bad debug flags: %s"),
497 quotearg_style (locale_quoting_style, optarg));
498 break;
500 case 'e':
501 error (0, 0, _("warning: `%s' is deprecated, use `%s' instead"),
502 "-e", "-i");
503 /* fall through */
504 case 'i':
505 interactive = INTERACTIVE_YES;
506 break;
508 case 'g':
509 m4_set_posixly_correct_opt (context, false);
510 break;
512 case ARGLENGTH_OPTION:
513 error (0, 0, _("warning: `%s' is deprecated, use `%s' instead"),
514 "--arglength", "--debuglen");
515 /* fall through */
516 case 'l':
517 size = size_opt (optarg, oi, optchar);
518 if (!size)
519 size = SIZE_MAX;
520 m4_set_max_debug_arg_length_opt (context, size);
521 break;
523 case DEBUGFILE_OPTION:
524 /* Staggered handling of '--debugfile', since it is useful
525 prior to first file and prior to reloading, but other
526 uses must also have effect between files. */
527 if (seen_file || frozen_file_to_read)
528 goto defer;
529 debugfile = optarg;
530 break;
532 case 'o':
533 case ERROR_OUTPUT_OPTION:
534 /* FIXME: -o is inconsistent with other tools' use of
535 -o/--output for creating an output file instead of using
536 stdout, and --error-output is misnamed since it does not
537 affect error messages to stderr. Change the meaning of -o
538 after 2.1. */
539 error (0, 0, _("warning: `%s' is deprecated, use `%s' instead"),
540 optchar == 'o' ? "-o" : "--error-output", "--debugfile");
541 /* Don't call m4_debug_set_output here, as it has side effects. */
542 debugfile = optarg;
543 break;
545 case IMPORT_ENVIRONMENT_OPTION:
546 import_environment = true;
547 break;
549 case SAFER_OPTION:
550 m4_set_safer_opt (context, true);
551 break;
553 case VERSION_OPTION:
554 version_etc (stdout, PACKAGE, PACKAGE_NAME, VERSION, AUTHORS, NULL);
555 exit (EXIT_SUCCESS);
556 break;
558 case HELP_OPTION:
559 usage (EXIT_SUCCESS);
560 break;
564 /* Do the basic initializations. */
565 if (debugfile && !m4_debug_set_output (context, NULL, debugfile))
566 m4_error (context, 0, errno, NULL, _("cannot set debug file %s"),
567 quotearg_style (locale_quoting_style, debugfile));
568 m4_input_init (context);
569 m4_output_init (context);
571 if (frozen_file_to_read)
572 reload_frozen_state (context, frozen_file_to_read);
573 else
575 m4_module_load (context, "m4", NULL);
576 if (m4_get_posixly_correct_opt (context))
577 m4_module_load (context, "traditional", NULL);
578 else
579 m4_module_load (context, "gnu", NULL);
582 /* Import environment variables as macros. The definition are
583 prepended to the macro definition list, so -U can override
584 environment variables. */
586 if (import_environment)
588 char *const *env;
590 for (env = envp; *env != NULL; env++)
592 defn = (deferred *) xmalloc (sizeof *defn);
593 defn->code = 'D';
594 defn->value = *env;
595 defn->next = head;
596 head = defn;
600 /* Handle deferred command line macro definitions. Must come after
601 initialization of the symbol table. */
602 defn = head;
603 while (defn != NULL)
605 deferred *next;
606 const char *arg = defn->value;
608 switch (defn->code)
610 case 'D':
611 case 'p':
613 m4_symbol_value *value = m4_symbol_value_create ();
615 const char *str = strchr (arg, '=');
616 size_t len = str ? str - arg : strlen (arg);
618 m4_set_symbol_value_text (value, xstrdup (str ? str + 1 : ""),
619 str ? strlen (str + 1) : 0, 0);
621 if (defn->code == 'D')
622 m4_symbol_define (M4SYMTAB, arg, len, value);
623 else
624 m4_symbol_pushdef (M4SYMTAB, arg, len, value);
626 break;
628 case 'U':
629 m4_symbol_delete (M4SYMTAB, arg, strlen (arg));
630 break;
632 case 'd':
633 if (m4_debug_decode (context, arg, SIZE_MAX) < 0)
634 error (0, 0, _("bad debug flags: %s"),
635 quotearg_style (locale_quoting_style, arg));
636 break;
638 case 'r':
639 m4_set_regexp_syntax_opt (context, m4_regexp_syntax_encode (arg));
640 if (m4_get_regexp_syntax_opt (context) < 0)
641 m4_error (context, EXIT_FAILURE, 0, NULL,
642 _("bad syntax-spec: %s"),
643 quotearg_style (locale_quoting_style, arg));
644 break;
646 case 't':
647 m4_set_symbol_name_traced (M4SYMTAB, arg, strlen (arg), true);
648 break;
650 case '\1':
651 if (process_file (context, arg))
652 seen_file = true;
653 break;
655 case DEBUGFILE_OPTION:
656 if (!m4_debug_set_output (context, NULL, arg))
657 m4_error (context, 0, errno, NULL, _("cannot set debug file %s"),
658 quotearg_style (locale_quoting_style,
659 arg ? arg : _("stderr")));
660 break;
662 case POPDEF_OPTION:
664 size_t len = strlen (arg);
665 if (m4_symbol_lookup (M4SYMTAB, arg, len))
666 m4_symbol_popdef (M4SYMTAB, arg, len);
668 break;
670 case SYNCOUTPUT_OPTION:
672 bool previous = m4_get_syncoutput_opt (context);
673 m4_call_info info = {0};
674 info.name = "--syncoutput";
675 info.name_len = strlen (info.name);
676 m4_set_syncoutput_opt (context,
677 m4_parse_truth_arg (context, &info, arg,
678 SIZE_MAX, previous));
680 break;
682 case TRACEOFF_OPTION:
683 m4_set_symbol_name_traced (M4SYMTAB, arg, strlen (arg), false);
684 break;
686 default:
687 assert (!"INTERNAL ERROR: bad code in deferred arguments");
688 abort ();
691 next = defn->next;
692 free (defn);
693 defn = next;
697 /* Interactive if specified, or if no input files and stdin and
698 stderr are terminals, to match sh behavior. Interactive mode
699 means unbuffered output, and interrupts ignored. */
701 m4_set_interactive_opt (context, (interactive == INTERACTIVE_YES
702 || (interactive == INTERACTIVE_UNKNOWN
703 && optind == argc && !seen_file
704 && isatty (STDIN_FILENO)
705 && isatty (STDERR_FILENO))));
706 if (m4_get_interactive_opt (context))
708 signal (SIGINT, SIG_IGN);
709 setbuf (stdout, NULL);
711 else
712 signal (SIGPIPE, SIG_DFL);
715 /* Handle remaining input files. Each file is pushed on the input,
716 and the input read. */
718 if (optind == argc && !seen_file)
719 process_file (context, "-");
720 else
721 for (; optind < argc; optind++)
722 process_file (context, argv[optind]);
724 /* Now handle wrapup text.
725 FIXME - when -F is in effect, should wrapped text be frozen? */
726 while (m4_pop_wrapup (context))
727 m4_macro_expand_input (context);
729 if (frozen_file_to_write)
730 produce_frozen_state (context, frozen_file_to_write);
731 else
733 m4_make_diversion (context, 0);
734 m4_undivert_all (context);
737 /* The remaining cleanup functions systematically free all of the
738 memory we still have pointers to. By definition, if there is
739 anything left when we're done: it was caused by a memory leak.
740 Strictly, we don't need to do this, but it makes leak detection
741 a whole lot easier! */
743 m4_output_exit ();
744 m4_input_exit ();
746 /* Change debug stream back to stderr, to force flushing the debug
747 stream and detect any errors it might have encountered. The
748 three standard streams are closed by close_stdin. */
749 m4_debug_set_output (context, NULL, NULL);
751 exit_status = m4_get_exit_status (context);
752 m4_delete (context);
754 m4_hash_exit ();
755 quotearg_free ();
757 #ifdef USE_STACKOVF
758 stackovf_exit ();
759 #endif
761 exit (exit_status);