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é". */
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