1 /* GNU m4 -- A simple macro processor
2 
3    Copyright (C) 1989-1994, 2004-2014, 2016-2017, 2020-2021 Free
4    Software Foundation, Inc.
5 
6    This file is part of GNU M4.
7 
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.
12 
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.
17 
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <https://www.gnu.org/licenses/>.
20 */
21 
22 #include "m4.h"
23 
24 #include <getopt.h>
25 #include <limits.h>
26 #include <signal.h>
27 
28 #include "c-stack.h"
29 #include "configmake.h"
30 #include "ignore-value.h"
31 #include "progname.h"
32 #include "propername.h"
33 #include "version-etc.h"
34 
35 #ifdef DEBUG_STKOVF
36 # include "assert.h"
37 #endif
38 
39 /* TRANSLATORS: This is a non-ASCII name: The first name is (with
40    Unicode escapes) "Ren\u00e9" or (with HTML entities) "Ren&eacute;".  */
41 #define AUTHORS proper_name_utf8 ("Rene' Seindal", "Ren\xC3\xA9 Seindal")
42 
43 static _Noreturn void usage (int);
44 
45 /* Enable sync output for /lib/cpp (-s).  */
46 int sync_output = 0;
47 
48 /* Debug (-d[flags]).  */
49 int debug_level = 0;
50 
51 /* Hash table size (should be a prime) (-Hsize).  */
52 size_t hash_table_size = HASHMAX;
53 
54 /* Disable GNU extensions (-G).  */
55 int no_gnu_extensions = 0;
56 
57 /* Prefix all builtin functions by `m4_'.  */
58 int prefix_all_builtins = 0;
59 
60 /* Max length of arguments in trace output (-lsize).  */
61 int max_debug_argument_length = 0;
62 
63 /* Suppress warnings about missing arguments.  */
64 int suppress_warnings = 0;
65 
66 /* If true, then warnings affect exit status.  */
67 static bool fatal_warnings = false;
68 
69 /* If not zero, then value of exit status for warning diagnostics.  */
70 int warning_status = 0;
71 
72 /* Artificial limit for expansion_level in macro.c.  */
73 int nesting_limit = 1024;
74 
75 #ifdef ENABLE_CHANGEWORD
76 /* User provided regexp for describing m4 words.  */
77 const char *user_word_regexp = "";
78 #endif
79 
80 /* Global catchall for any errors that should affect final error status, but
81    where we try to continue execution in the meantime.  */
82 int retcode;
83 
84 struct macro_definition
85 {
86   struct macro_definition *next;
87   int code; /* D, U, s, t, '\1', or DEBUGFILE_OPTION.  */
88   const char *arg;
89 };
90 typedef struct macro_definition macro_definition;
91 
92 /* Error handling functions.  */
93 
94 /*-----------------------.
95 | Wrapper around error.  |
96 `-----------------------*/
97 
98 void
m4_error(int status,int errnum,const char * format,...)99 m4_error (int status, int errnum, const char *format, ...)
100 {
101   va_list args;
102   va_start (args, format);
103   verror_at_line (status, errnum, current_line ? current_file : NULL,
104                   current_line, format, args);
105   if (fatal_warnings && ! retcode)
106     retcode = EXIT_FAILURE;
107   va_end (args);
108 }
109 
110 void
m4_failure(int errnum,const char * format,...)111 m4_failure (int errnum, const char *format, ...)
112 {
113   va_list args;
114   va_start (args, format);
115   verror_at_line (EXIT_FAILURE, errnum, current_line ? current_file : NULL,
116                   current_line, format, args);
117   assume (false);
118 }
119 
120 /*-------------------------------.
121 | Wrapper around error_at_line.  |
122 `-------------------------------*/
123 
124 void
m4_error_at_line(int status,int errnum,const char * file,int line,const char * format,...)125 m4_error_at_line (int status, int errnum, const char *file, int line,
126                   const char *format, ...)
127 {
128   va_list args;
129   va_start (args, format);
130   verror_at_line (status, errnum, line ? file : NULL, line, format, args);
131   if (fatal_warnings && ! retcode)
132     retcode = EXIT_FAILURE;
133   va_end (args);
134 }
135 
136 void
m4_failure_at_line(int errnum,const char * file,int line,const char * format,...)137 m4_failure_at_line (int errnum, const char *file, int line,
138                     const char *format, ...)
139 {
140   va_list args;
141   va_start (args, format);
142   verror_at_line (EXIT_FAILURE, errnum, line ? file : NULL,
143                   line, format, args);
144   assume (false);
145 }
146 
147 #ifndef SIGBUS
148 # define SIGBUS SIGILL
149 #endif
150 
151 #ifndef NSIG
152 # ifndef MAX
153 #  define MAX(a,b) ((a) < (b) ? (b) : (a))
154 # endif
155 # define NSIG (MAX (SIGABRT, MAX (SIGILL, MAX (SIGFPE,  \
156                                                MAX (SIGSEGV, SIGBUS)))) + 1)
157 #endif
158 
159 /* Pre-translated messages for program errors.  Do not translate in
160    the signal handler, since gettext and strsignal are not
161    async-signal-safe.  */
162 static const char * volatile program_error_message;
163 static const char * volatile signal_message[NSIG];
164 
165 /* Print a nicer message about any programmer errors, then exit.  This
166    must be aysnc-signal safe, since it is executed as a signal
167    handler.  If SIGNO is zero, this represents a stack overflow; in
168    that case, we return to allow c_stack_action to handle things.  */
169 static void
fault_handler(int signo)170 fault_handler (int signo)
171 {
172   if (signo)
173     {
174       /* POSIX states that reading static memory is, in general, not
175          async-safe.  However, the static variables that we read are
176          never modified once this handler is installed, so this
177          particular usage is safe.  And it seems an oversight that
178          POSIX claims strlen is not async-safe.  Ignore write
179          failures, since we will exit with non-zero status anyway.  */
180 #define WRITE(f, b, l) ignore_value (write (f, b, l))
181       WRITE (STDERR_FILENO, program_name, strlen (program_name));
182       WRITE (STDERR_FILENO, ": ", 2);
183       WRITE (STDERR_FILENO, program_error_message,
184              strlen (program_error_message));
185       if (signal_message[signo])
186         {
187           WRITE (STDERR_FILENO, ": ", 2);
188           WRITE (STDERR_FILENO, signal_message[signo],
189                  strlen (signal_message[signo]));
190         }
191       WRITE (STDERR_FILENO, "\n", 1);
192 #undef WRITE
193       _exit (EXIT_INTERNAL_ERROR);
194     }
195 }
196 
197 
198 /*---------------------------------------------.
199 | Print a usage message and exit with STATUS.  |
200 `---------------------------------------------*/
201 
202 static void
usage(int status)203 usage (int status)
204 {
205   if (status != EXIT_SUCCESS)
206     {
207       xfprintf (stderr, _("Try `%s --help' for more information."),
208                 program_name);
209       fputs ("\n", stderr);
210     }
211   else
212     {
213       xprintf (_("Usage: %s [OPTION]... [FILE]...\n"), program_name);
214       fputs (_("\
215 Process macros in FILEs.  If no FILE or if FILE is `-', standard input\n\
216 is read.\n\
217 "), stdout);
218       puts ("");
219       fputs (_("\
220 Mandatory or optional arguments to long options are mandatory or optional\n\
221 for short options too.\n\
222 "), stdout);
223       puts ("");
224       fputs (_("\
225 Operation modes:\n\
226       --help                   display this help and exit\n\
227       --version                output version information and exit\n\
228 "), stdout);
229       fputs (_("\
230   -E, --fatal-warnings         once: warnings become errors, twice: stop\n\
231                                  execution at first error\n\
232   -i, --interactive            unbuffer output, ignore interrupts\n\
233   -P, --prefix-builtins        force a `m4_' prefix to all builtins\n\
234   -Q, --quiet, --silent        suppress some warnings for builtins\n\
235 "), stdout);
236       xprintf (_("\
237       --warn-macro-sequence[=REGEXP]\n\
238                                warn if macro definition matches REGEXP,\n\
239                                  default %s\n\
240 "), DEFAULT_MACRO_SEQUENCE);
241 #ifdef ENABLE_CHANGEWORD
242       fputs (_("\
243   -W, --word-regexp=REGEXP     use REGEXP for macro name syntax\n\
244 "), stdout);
245 #endif
246       puts ("");
247       fputs (_("\
248 Preprocessor features:\n\
249   -D, --define=NAME[=VALUE]    define NAME as having VALUE, or empty\n\
250   -I, --include=DIRECTORY      append DIRECTORY to include path\n\
251   -s, --synclines              generate `#line NUM \"FILE\"' lines\n\
252   -U, --undefine=NAME          undefine NAME\n\
253 "), stdout);
254       puts ("");
255       xprintf (_("\
256 Limits control:\n\
257   -g, --gnu                    override -G to re-enable GNU extensions\n\
258   -G, --traditional            suppress all GNU extensions\n\
259   -H, --hashsize=PRIME         set symbol lookup hash table size [509]\n\
260   -L, --nesting-limit=NUMBER   change nesting limit, 0 for unlimited [%d]\n\
261 "), nesting_limit);
262       puts ("");
263       fputs (_("\
264 Frozen state files:\n\
265   -F, --freeze-state=FILE      produce a frozen state on FILE at end\n\
266   -R, --reload-state=FILE      reload a frozen state from FILE at start\n\
267 "), stdout);
268       puts ("");
269       fputs (_("\
270 Debugging:\n\
271   -d, --debug[=FLAGS]          set debug level (no FLAGS implies `aeq')\n\
272       --debugfile[=FILE]       redirect debug and trace output to FILE\n\
273                                  (default stderr, discard if empty string)\n\
274   -l, --arglength=NUM          restrict macro tracing size\n\
275   -t, --trace=NAME             trace NAME when it is defined\n\
276 "), stdout);
277       puts ("");
278       fputs (_("\
279 FLAGS is any of:\n\
280   a   show actual arguments\n\
281   c   show before collect, after collect and after call\n\
282   e   show expansion\n\
283   f   say current input file name\n\
284   i   show changes in input files\n\
285 "), stdout);
286       fputs (_("\
287   l   say current input line number\n\
288   p   show results of path searches\n\
289   q   quote values as necessary, with a or e flag\n\
290   t   trace for all macro calls, not only traceon'ed\n\
291   x   add a unique macro call id, useful with c flag\n\
292   V   shorthand for all of the above flags\n\
293 "), stdout);
294       puts ("");
295       fputs (_("\
296 If defined, the environment variable `M4PATH' is a colon-separated list\n\
297 of directories included after any specified by `-I'.\n\
298 "), stdout);
299       puts ("");
300       fputs (_("\
301 Exit status is 0 for success, 1 for failure, 63 for frozen file version\n\
302 mismatch, or whatever value was passed to the m4exit macro.\n\
303 "), stdout);
304       emit_bug_reporting_address ();
305     }
306   exit (status);
307 }
308 
309 /*--------------------------------------.
310 | Decode options and launch execution.  |
311 `--------------------------------------*/
312 
313 /* For long options that have no equivalent short option, use a
314    non-character as a pseudo short option, starting with CHAR_MAX + 1.  */
315 enum
316 {
317   DEBUGFILE_OPTION = CHAR_MAX + 1,      /* no short opt */
318   DIVERSIONS_OPTION,                    /* not quite -N, because of message */
319   WARN_MACRO_SEQUENCE_OPTION,           /* no short opt */
320 
321   HELP_OPTION,                          /* no short opt */
322   VERSION_OPTION                        /* no short opt */
323 };
324 
325 static const struct option long_options[] =
326 {
327   {"arglength", required_argument, NULL, 'l'},
328   {"debug", optional_argument, NULL, 'd'},
329   {"define", required_argument, NULL, 'D'},
330   {"error-output", required_argument, NULL, 'o'}, /* FIXME: deprecate in 2.0 */
331   {"fatal-warnings", no_argument, NULL, 'E'},
332   {"freeze-state", required_argument, NULL, 'F'},
333   {"gnu", no_argument, NULL, 'g'},
334   {"hashsize", required_argument, NULL, 'H'},
335   {"include", required_argument, NULL, 'I'},
336   {"interactive", no_argument, NULL, 'i'},
337   {"nesting-limit", required_argument, NULL, 'L'},
338   {"prefix-builtins", no_argument, NULL, 'P'},
339   {"quiet", no_argument, NULL, 'Q'},
340   {"reload-state", required_argument, NULL, 'R'},
341   {"silent", no_argument, NULL, 'Q'},
342   {"synclines", no_argument, NULL, 's'},
343   {"trace", required_argument, NULL, 't'},
344   {"traditional", no_argument, NULL, 'G'},
345   {"undefine", required_argument, NULL, 'U'},
346 #ifdef ENABLE_CHANGEWORD
347   {"word-regexp", required_argument, NULL, 'W'},
348 #endif
349 
350   {"debugfile", optional_argument, NULL, DEBUGFILE_OPTION},
351   {"diversions", required_argument, NULL, DIVERSIONS_OPTION},
352   {"warn-macro-sequence", optional_argument, NULL, WARN_MACRO_SEQUENCE_OPTION},
353 
354   {"help", no_argument, NULL, HELP_OPTION},
355   {"version", no_argument, NULL, VERSION_OPTION},
356 
357   { NULL, 0, NULL, 0 },
358 };
359 
360 /* Process a command line file NAME, and return true only if it was
361    stdin.  */
362 static void
process_file(const char * name)363 process_file (const char *name)
364 {
365   if (STREQ (name, "-"))
366     {
367       /* If stdin is a terminal, we want to allow 'm4 - file -'
368          to read input from stdin twice, like GNU cat.  Besides,
369          there is no point closing stdin before wrapped text, to
370          minimize bugs in syscmd called from wrapped text.  */
371       push_file (stdin, "stdin", false);
372     }
373   else
374     {
375       char *full_name;
376       FILE *fp = m4_path_search (name, &full_name);
377       if (fp == NULL)
378         {
379           error (0, errno, _("cannot open `%s'"), name);
380           /* Set the status to EXIT_FAILURE, even though we
381              continue to process files after a missing file.  */
382           retcode = EXIT_FAILURE;
383           return;
384         }
385       push_file (fp, full_name, true);
386       free (full_name);
387     }
388   expand_input ();
389 }
390 
391 /* POSIX requires only -D, -U, and -s; and says that the first two
392    must be recognized when interspersed with file names.  Traditional
393    behavior also handles -s between files.  Starting OPTSTRING with
394    '-' forces getopt_long to hand back file names as arguments to opt
395    '\1', rather than reordering the command line.  */
396 #ifdef ENABLE_CHANGEWORD
397 #define OPTSTRING "-B:D:EF:GH:I:L:N:PQR:S:T:U:W:d::egil:o:st:"
398 #else
399 #define OPTSTRING "-B:D:EF:GH:I:L:N:PQR:S:T:U:d::egil:o:st:"
400 #endif
401 
402 int
main(int argc,char * const * argv)403 main (int argc, char *const *argv)
404 {
405   struct sigaction act;
406   macro_definition *head;       /* head of deferred argument list */
407   macro_definition *tail;
408   macro_definition *defn;
409   int optchar;                  /* option character */
410 
411   macro_definition *defines;
412   bool interactive = false;
413   bool seen_file = false;
414   const char *debugfile = NULL;
415   const char *frozen_file_to_read = NULL;
416   const char *frozen_file_to_write = NULL;
417   const char *macro_sequence = "";
418 
419   set_program_name (argv[0]);
420   retcode = EXIT_SUCCESS;
421   setlocale (LC_ALL, "");
422   bindtextdomain (PACKAGE, LOCALEDIR);
423   textdomain (PACKAGE);
424   atexit (close_stdin);
425 
426   include_init ();
427   debug_init ();
428 
429   /* Stack overflow and program error handling.  Ignore failure to
430      install a handler, since this is merely for improved output on
431      crash, and we should never crash ;).  We install SIGBUS and
432      SIGSEGV handlers prior to using the c-stack module; depending on
433      the platform, c-stack will then override none, SIGSEGV, or both
434      handlers.  */
435   program_error_message
436     = xasprintf (_("internal error detected; please report this bug to <%s>"),
437                  PACKAGE_BUGREPORT);
438   signal_message[SIGSEGV] = xstrdup (strsignal (SIGSEGV));
439   signal_message[SIGABRT] = xstrdup (strsignal (SIGABRT));
440   signal_message[SIGILL] = xstrdup (strsignal (SIGILL));
441   signal_message[SIGFPE] = xstrdup (strsignal (SIGFPE));
442   if (SIGBUS != SIGILL && SIGBUS != SIGSEGV)
443     signal_message[SIGBUS] = xstrdup (strsignal (SIGBUS));
444   sigemptyset (&act.sa_mask);
445   /* One-shot - if we fault while handling a fault, we want to revert
446      to default signal behavior.  */
447   act.sa_flags = SA_NODEFER | SA_RESETHAND;
448   act.sa_handler = fault_handler;
449   sigaction (SIGSEGV, &act, NULL);
450   sigaction (SIGABRT, &act, NULL);
451   sigaction (SIGILL, &act, NULL);
452   sigaction (SIGFPE, &act, NULL);
453   sigaction (SIGBUS, &act, NULL);
454   if (c_stack_action (fault_handler) == 0)
455     nesting_limit = 0;
456 
457 #ifdef DEBUG_STKOVF
458   /* Make it easier to test our fault handlers.  Exporting M4_CRASH=0
459      attempts a SIGSEGV, exporting it as 1 attempts an assertion
460      failure with a fallback to abort.  */
461   {
462     char *crash = getenv ("M4_CRASH");
463     if (crash)
464       {
465         if (!strtol (crash, NULL, 10))
466           ++*(int *) 8;
467         assert (false);
468         abort ();
469       }
470   }
471 #endif /* DEBUG_STKOVF */
472 
473   /* First, we decode the arguments, to size up tables and stuff.  */
474   head = tail = NULL;
475 
476   while ((optchar = getopt_long (argc, (char **) argv, OPTSTRING,
477                                  long_options, NULL)) != -1)
478     switch (optchar)
479       {
480       default:
481         usage (EXIT_FAILURE);
482 
483       case 'B':
484       case 'S':
485       case 'T':
486         /* Compatibility junk: options that other implementations
487            support, but which we ignore as no-ops and don't list in
488            --help.  */
489         error (0, 0, _("warning: `m4 -%c' may be removed in a future release"),
490                optchar);
491         break;
492 
493       case 'N':
494       case DIVERSIONS_OPTION:
495         /* -N became an obsolete no-op in 1.4.x.  */
496         error (0, 0, _("warning: `m4 %s' is deprecated"),
497                optchar == 'N' ? "-N" : "--diversions");
498         break;
499 
500       case 'D':
501       case 'U':
502       case 's':
503       case 't':
504       case '\1':
505       case DEBUGFILE_OPTION:
506         /* Arguments that cannot be handled until later are accumulated.  */
507 
508         defn = (macro_definition *) xmalloc (sizeof (macro_definition));
509         defn->code = optchar;
510         defn->arg = optarg;
511         defn->next = NULL;
512 
513         if (head == NULL)
514           head = defn;
515         else
516           tail->next = defn;
517         tail = defn;
518 
519         break;
520 
521       case 'E':
522         if (! fatal_warnings)
523           fatal_warnings = true;
524         else
525           warning_status = EXIT_FAILURE;
526         break;
527 
528       case 'F':
529         frozen_file_to_write = optarg;
530         break;
531 
532       case 'G':
533         no_gnu_extensions = 1;
534         break;
535 
536       case 'H':
537         hash_table_size = strtol (optarg, NULL, 10);
538         if (hash_table_size == 0)
539           hash_table_size = HASHMAX;
540         break;
541 
542       case 'I':
543         add_include_directory (optarg);
544         break;
545 
546       case 'L':
547         nesting_limit = strtol (optarg, NULL, 10);
548         break;
549 
550       case 'P':
551         prefix_all_builtins = 1;
552         break;
553 
554       case 'Q':
555         suppress_warnings = 1;
556         break;
557 
558       case 'R':
559         frozen_file_to_read = optarg;
560         break;
561 
562 #ifdef ENABLE_CHANGEWORD
563       case 'W':
564         user_word_regexp = optarg;
565         break;
566 #endif
567 
568       case 'd':
569         debug_level = debug_decode (optarg);
570         if (debug_level < 0)
571           {
572             error (0, 0, _("bad debug flags: `%s'"), optarg);
573             debug_level = 0;
574           }
575         break;
576 
577       case 'e':
578         error (0, 0, _("warning: `m4 -e' is deprecated, use `-i' instead"));
579         FALLTHROUGH;
580       case 'i':
581         interactive = true;
582         break;
583 
584       case 'g':
585         no_gnu_extensions = 0;
586         break;
587 
588       case 'l':
589         max_debug_argument_length = strtol (optarg, NULL, 10);
590         if (max_debug_argument_length <= 0)
591           max_debug_argument_length = 0;
592         break;
593 
594       case 'o':
595         /* -o/--error-output are deprecated synonyms of --debugfile,
596            but don't issue a deprecation warning until autoconf 2.61
597            or later is more widely established, as such a warning
598            would interfere with all earlier versions of autoconf.  */
599         /* Don't call debug_set_output here, as it has side effects.  */
600         debugfile = optarg;
601         break;
602 
603       case WARN_MACRO_SEQUENCE_OPTION:
604          /* Don't call set_macro_sequence here, as it can exit.
605             --warn-macro-sequence sets optarg to NULL (which uses the
606             default regexp); --warn-macro-sequence= sets optarg to ""
607             (which disables these warnings).  */
608         macro_sequence = optarg;
609         break;
610 
611       case VERSION_OPTION:
612         version_etc (stdout, PACKAGE, PACKAGE_NAME, VERSION, AUTHORS, NULL);
613         exit (EXIT_SUCCESS);
614         break;
615 
616       case HELP_OPTION:
617         usage (EXIT_SUCCESS);
618         break;
619       }
620 
621   defines = head;
622 
623   /* Do the basic initializations.  */
624   if (debugfile && !debug_set_output (debugfile))
625     M4ERROR ((warning_status, errno, _("cannot set debug file `%s'"),
626               debugfile));
627 
628   input_init ();
629   output_init ();
630   symtab_init ();
631   set_macro_sequence (macro_sequence);
632   include_env_init ();
633 
634   if (frozen_file_to_read)
635     reload_frozen_state (frozen_file_to_read);
636   else
637     builtin_init ();
638 
639   /* Interactive mode means unbuffered output, and interrupts ignored.  */
640 
641   if (interactive)
642     {
643       signal (SIGINT, SIG_IGN);
644       setbuf (stdout, (char *) NULL);
645     }
646 
647   /* Handle deferred command line macro definitions.  Must come after
648      initialization of the symbol table.  */
649 
650   while (defines != NULL)
651     {
652       macro_definition *next;
653       symbol *sym;
654 
655       switch (defines->code)
656         {
657         case 'D':
658           {
659             /* defines->arg is read-only, so we need a copy.  */
660             char *macro_name = xstrdup (defines->arg);
661             char *macro_value = strchr (macro_name, '=');
662             if (macro_value)
663               *macro_value++ = '\0';
664             define_user_macro (macro_name, macro_value, SYMBOL_INSERT);
665             free (macro_name);
666           }
667           break;
668 
669         case 'U':
670           lookup_symbol (defines->arg, SYMBOL_DELETE);
671           break;
672 
673         case 't':
674           sym = lookup_symbol (defines->arg, SYMBOL_INSERT);
675           SYMBOL_TRACED (sym) = true;
676           break;
677 
678         case 's':
679           sync_output = 1;
680           break;
681 
682         case '\1':
683           seen_file = true;
684           process_file (defines->arg);
685           break;
686 
687         case DEBUGFILE_OPTION:
688           if (!debug_set_output (defines->arg))
689             M4ERROR ((warning_status, errno, _("cannot set debug file `%s'"),
690                       debugfile ? debugfile : _("stderr")));
691           break;
692 
693         default:
694           M4ERROR ((0, 0, "INTERNAL ERROR: bad code in deferred arguments"));
695           abort ();
696         }
697 
698       next = defines->next;
699       free (defines);
700       defines = next;
701     }
702 
703   /* Handle remaining input files.  Each file is pushed on the input,
704      and the input read.  Wrapup text is handled separately later.  */
705 
706   if (optind == argc && !seen_file)
707     process_file ("-");
708   else
709     for (; optind < argc; optind++)
710       process_file (argv[optind]);
711 
712   /* Now handle wrapup text.  */
713 
714   while (pop_wrapup ())
715     expand_input ();
716 
717   /* Change debug stream back to stderr, to force flushing the debug
718      stream and detect any errors it might have encountered.  The
719      three standard streams are closed by close_stdin.  */
720   debug_set_output (NULL);
721 
722   if (frozen_file_to_write)
723     produce_frozen_state (frozen_file_to_write);
724   else
725     {
726       make_diversion (0);
727       undivert_all ();
728     }
729   output_exit ();
730   free_macro_sequence ();
731   exit (retcode);
732 }
733