1 /* GNU m4 -- A simple macro processor
3 Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1999, 2000, 2003,
4 2004, 2005, 2006, 2007, 2008 Free 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/>.
28 #include "close-stream.h"
30 #include "configmake.h"
32 #include "propername.h"
34 #include "version-etc.h"
38 proper_name_utf8 ("Rene' Seindal", "Ren\xc3\xa9 Seindal"), \
39 proper_name ("Gary V. Vaughan"), \
40 proper_name ("Eric Blake")
42 typedef struct deferred
44 struct deferred
*next
;
45 int code
; /* deferred optchar */
50 /* Error handling functions. */
54 /* Tell user stack overflowed and abort. */
56 stackovf_handler (void)
58 /* FIXME - calling gettext and error inside a signal handler is dangerous,
59 since these functions invoke functions that are not signal-safe. We
60 are sort of justified by the fact that we will exit and never return,
61 but this should really be fixed. */
62 error (EXIT_FAILURE
, 0, _("stack overflow (infinite define recursion?)"));
65 #endif /* USE_STACKOVF */
69 /* Print a usage message and exit with STATUS. */
73 if (status
!= EXIT_SUCCESS
)
74 xfprintf (stderr
, _("Try `%s --help' for more information.\n"),
75 m4_get_program_name ());
78 xprintf (_("Usage: %s [OPTION]... [FILE]...\n"), m4_get_program_name ());
80 Process macros in FILEs.\n\
81 If no FILE or if FILE is `-', standard input is read. If no FILE, and both\n\
82 standard input and standard error are terminals, -i is implied.\n\
86 Mandatory or optional arguments to long options are mandatory or optional\n\
87 for short options too.\n\
90 --help display this help and exit\n\
91 --version output version information and exit\n\
94 -b, --batch buffer output, process interrupts\n\
95 -c, --discard-comments do not copy comments to the output\n\
96 -E, --fatal-warnings once: warnings become errors, twice: stop\n\
97 execution at first error\n\
98 -i, --interactive unbuffer output, ignore interrupts\n\
99 -P, --prefix-builtins force a `m4_' prefix to all builtins\n\
100 -Q, --quiet, --silent suppress some warnings for builtins\n\
101 -r, --regexp-syntax[=SPEC] set default regexp syntax to SPEC [GNU_M4]\n\
102 --safer disable potentially unsafe builtins\n\
103 -W, --warnings enable all warnings\n\
107 SPEC is any one of:\n\
108 AWK, BASIC, BSD_M4, ED, EMACS, EXTENDED, GNU_AWK, GNU_EGREP, GNU_M4,\n\
109 GREP, POSIX_AWK, POSIX_EGREP, MINIMAL, MINIMAL_BASIC, SED.\n\
113 Dynamic loading features:\n\
114 -M, --module-directory=DIR add DIR to module search path before\n\
116 -m, --load-module=MODULE load dynamic MODULE\n\
117 --unload-module=MODULE unload dynamic MODULE\n\
121 Preprocessor features:\n\
122 -B, --prepend-include=DIR add DIR to include path before `.'\n\
123 -D, --define=NAME[=VALUE] define NAME as having VALUE, or empty\n\
124 --import-environment import all environment variables as macros\n\
125 -I, --include=DIR add DIR to include path after `.'\n\
128 --popdef=NAME popdef NAME\n\
129 -p, --pushdef=NAME[=VALUE] pushdef NAME as having VALUE, or empty\n\
130 -s, --synclines short for --syncoutput=1\n\
131 --syncoutput[=STATE] set generation of `#line NUM \"FILE\"' lines\n\
132 to STATE (0=off, 1=on, default 0 if omitted)\n\
133 -U, --undefine=NAME undefine NAME\n\
138 -g, --gnu override -G to re-enable GNU extensions\n\
139 -G, --traditional, --posix suppress all GNU extensions\n\
140 -L, --nesting-limit=NUMBER change artificial nesting limit [1024]\n\
144 Frozen state files:\n\
145 -F, --freeze-state=FILE produce a frozen state on FILE at end\n\
146 -R, --reload-state=FILE reload a frozen state from FILE at start\n\
151 -d, --debug[=[-|+]FLAGS], --debugmode[=[-|+]FLAGS]\n\
152 set debug level (no FLAGS implies `+adeq')\n\
153 --debugfile=FILE redirect debug and trace output\n\
154 -l, --debuglen=NUM restrict macro tracing size\n\
155 -t, --trace=NAME, --traceon=NAME\n\
156 trace NAME when it is defined\n\
157 --traceoff=NAME no longer trace NAME\n\
162 a show actual arguments in trace\n\
163 c show collection line in trace\n\
164 d warn when dereferencing undefined macros (default on unless -E)\n\
165 e show expansion in trace\n\
166 f include current input file name in trace and debug\n\
167 i show changes in input files in debug\n\
168 l include current input line number in trace and debug\n\
171 m show module information in trace, debug, and dumpdef\n\
172 p show results of path searches in debug\n\
173 q quote values in dumpdef and trace, useful with a or e\n\
174 s show full stack of pushdef values in dumpdef\n\
175 t trace all macro calls, regardless of per-macro traceon state\n\
176 x include unique macro call id in trace, useful with c\n\
177 V shorthand for all of the above flags\n\
181 If defined, the environment variable `M4PATH' is a colon-separated list\n\
182 of directories included after any specified by `-I', and the variable\n\
183 `M4MODPATH' is a colon-separated list of directories searched before any\n\
184 specified by `-M'. The environment variable `POSIXLY_CORRECT' implies\n\
185 -G -Q; otherwise GNU extensions are enabled by default.\n\
189 Exit status is 0 for success, 1 for failure, 63 for frozen file version\n\
190 mismatch, or whatever value was passed to the m4exit macro.\n\
193 /* TRANSLATORS: the placeholder indicates the bug-reporting
194 address for this application. Please add _another line_
195 saying "Report translation bugs to <...>\n" with the address
196 for translation bugs (typically your translation team's web
197 or email address). */
198 xprintf (_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT
);
203 /* For long options that have no equivalent short option, use a
204 non-character as a pseudo short option, starting with CHAR_MAX + 1. */
207 ARGLENGTH_OPTION
= CHAR_MAX
+ 1, /* not quite -l, because of message */
208 DEBUGFILE_OPTION
, /* no short opt */
209 ERROR_OUTPUT_OPTION
, /* not quite -o, because of message */
210 HASHSIZE_OPTION
, /* not quite -H, because of message */
211 IMPORT_ENVIRONMENT_OPTION
, /* no short opt */
212 POPDEF_OPTION
, /* no short opt */
213 PREPEND_INCLUDE_OPTION
, /* not quite -B, because of message */
214 SAFER_OPTION
, /* -S still has old no-op semantics */
215 SYNCOUTPUT_OPTION
, /* not quite -s, because of opt arg */
216 TRACEOFF_OPTION
, /* no short opt */
217 UNLOAD_MODULE_OPTION
, /* no short opt */
218 WORD_REGEXP_OPTION
, /* deprecated, used to be -W */
220 HELP_OPTION
, /* no short opt */
221 VERSION_OPTION
/* no short opt */
224 /* Decode options and launch execution. */
225 static const struct option long_options
[] =
227 {"batch", no_argument
, NULL
, 'b'},
228 {"debug", optional_argument
, NULL
, 'd'},
229 {"debuglen", required_argument
, NULL
, 'l'},
230 {"debugmode", optional_argument
, NULL
, 'd'},
231 {"define", required_argument
, NULL
, 'D'},
232 {"discard-comments", no_argument
, NULL
, 'c'},
233 {"fatal-warnings", no_argument
, NULL
, 'E'},
234 {"freeze-state", required_argument
, NULL
, 'F'},
235 {"gnu", no_argument
, NULL
, 'g'},
236 {"include", required_argument
, NULL
, 'I'},
237 {"interactive", no_argument
, NULL
, 'i'},
238 {"load-module", required_argument
, NULL
, 'm'},
239 {"module-directory", required_argument
, NULL
, 'M'},
240 {"nesting-limit", required_argument
, NULL
, 'L'},
241 {"posix", no_argument
, NULL
, 'G'},
242 {"prefix-builtins", no_argument
, NULL
, 'P'},
243 {"pushdef", required_argument
, NULL
, 'p'},
244 {"quiet", no_argument
, NULL
, 'Q'},
245 {"regexp-syntax", optional_argument
, NULL
, 'r'},
246 {"reload-state", required_argument
, NULL
, 'R'},
247 {"silent", no_argument
, NULL
, 'Q'},
248 {"synclines", no_argument
, NULL
, 's'},
249 {"trace", required_argument
, NULL
, 't'},
250 {"traceon", required_argument
, NULL
, 't'},
251 {"traditional", no_argument
, NULL
, 'G'},
252 {"undefine", required_argument
, NULL
, 'U'},
253 {"warnings", no_argument
, NULL
, 'W'},
255 {"arglength", required_argument
, NULL
, ARGLENGTH_OPTION
},
256 {"debugfile", required_argument
, NULL
, DEBUGFILE_OPTION
},
257 {"hashsize", required_argument
, NULL
, HASHSIZE_OPTION
},
258 {"error-output", required_argument
, NULL
, ERROR_OUTPUT_OPTION
},
259 {"import-environment", no_argument
, NULL
, IMPORT_ENVIRONMENT_OPTION
},
260 {"popdef", required_argument
, NULL
, POPDEF_OPTION
},
261 {"prepend-include", required_argument
, NULL
, PREPEND_INCLUDE_OPTION
},
262 {"safer", no_argument
, NULL
, SAFER_OPTION
},
263 {"syncoutput", optional_argument
, NULL
, SYNCOUTPUT_OPTION
},
264 {"traceoff", required_argument
, NULL
, TRACEOFF_OPTION
},
265 {"unload-module", required_argument
, NULL
, UNLOAD_MODULE_OPTION
},
266 {"word-regexp", required_argument
, NULL
, WORD_REGEXP_OPTION
},
268 {"help", no_argument
, NULL
, HELP_OPTION
},
269 {"version", no_argument
, NULL
, VERSION_OPTION
},
271 { NULL
, 0, NULL
, 0 },
274 /* POSIX requires only -D, -U, and -s; and says that the first two
275 must be recognized when interspersed with file names. Traditional
276 behavior also handles -s between files. Starting OPTSTRING with
277 '-' forces getopt_long to hand back file names as arguments to opt
278 '\1', rather than reordering the command line. */
279 #define OPTSTRING "-B:D:EF:GH:I:L:M:PQR:S:T:U:Wbcd::egil:m:o:p:r::st:"
281 /* For determining whether to be interactive. */
282 enum interactive_choice
284 INTERACTIVE_UNKNOWN
, /* Still processing arguments, no -b or -i yet */
285 INTERACTIVE_YES
, /* -i specified last */
286 INTERACTIVE_NO
/* -b specified last */
289 /* Convert OPT to size_t, reporting an error using long option index
290 OI or short option character OPTCHAR if it does not fit. */
292 size_opt (char const *opt
, int oi
, int optchar
)
294 unsigned long int size
;
295 strtol_error status
= xstrtoul (opt
, NULL
, 10, &size
, "kKmMgGtTPEZY0");
296 if (SIZE_MAX
< size
&& status
== LONGINT_OK
)
297 status
= LONGINT_OVERFLOW
;
298 if (status
!= LONGINT_OK
)
299 xstrtol_fatal (status
, oi
, optchar
, long_options
, opt
);
303 /* Process a command line file NAME, and return true only if it was
306 process_file (m4
*context
, const char *name
)
308 if (strcmp (name
, "-") == 0)
309 m4_push_file (context
, stdin
, "stdin", false);
313 FILE *fp
= m4_path_search (context
, name
, &full_name
);
316 m4_error (context
, 0, errno
, NULL
, _("cannot open file `%s'"), name
);
319 m4_push_file (context
, fp
, full_name
, true);
322 m4_macro_expand_input (context
);
326 /* Main entry point. Parse arguments, load modules, then parse input. */
328 main (int argc
, char *const *argv
, char *const *envp
)
330 deferred
*head
= NULL
; /* head of deferred argument list */
331 deferred
*tail
= NULL
;
333 size_t size
; /* for parsing numeric option arguments */
335 bool import_environment
= false; /* true to import environment */
336 bool seen_file
= false;
337 const char *debugfile
= NULL
;
338 const char *frozen_file_to_read
= NULL
;
339 const char *frozen_file_to_write
= NULL
;
340 enum interactive_choice interactive
= INTERACTIVE_UNKNOWN
;
346 /* Initialize gnulib error module. */
347 m4_set_program_name (argv
[0]);
348 atexit (close_stdin
);
350 setlocale (LC_ALL
, "");
352 textdomain (PACKAGE
);
355 LTDL_SET_PRELOADED_SYMBOLS ();
357 context
= m4_create ();
359 m4__module_init (context
);
362 setup_stackovf_trap (argv
, envp
, stackovf_handler
);
365 if (getenv ("POSIXLY_CORRECT"))
367 m4_set_posixly_correct_opt (context
, true);
368 m4_set_suppress_warnings_opt (context
, true);
370 set_quoting_style (NULL
, escape_quoting_style
);
371 set_char_quoting (NULL
, ':', 1);
373 /* First, we decode the arguments, to size up tables and stuff.
374 Avoid lasting side effects; for example 'm4 --debugfile=oops
375 --help' must not create the file `oops'. */
379 int optchar
= getopt_long (argc
, (char **) argv
, OPTSTRING
,
387 usage (EXIT_FAILURE
);
390 case HASHSIZE_OPTION
:
391 /* -H was supported in 1.4.x, but is a no-op now. FIXME -
392 remove support for -H after 2.0. */
393 error (0, 0, _("Warning: `%s' is deprecated"),
394 optchar
== 'H' ? "-H" : "--hashsize");
399 /* Compatibility junk: options that other implementations
400 support, but which we ignore as no-ops and don't list in
402 error (0, 0, _("Warning: `-%c' is deprecated"),
406 case WORD_REGEXP_OPTION
:
407 /* Supported in 1.4.x as -W, but no longer present. */
408 error (0, 0, _("Warning: `%s' is deprecated"), "--word-regexp");
412 optchar
= SYNCOUTPUT_OPTION
;
422 case SYNCOUTPUT_OPTION
:
423 case TRACEOFF_OPTION
:
424 case UNLOAD_MODULE_OPTION
:
426 /* Arguments that cannot be handled until later are accumulated. */
428 defn
= (deferred
*) xmalloc (sizeof *defn
);
429 defn
->code
= optchar
;
430 defn
->value
= optarg
;
445 /* In 1.4.x, -B<num> was a no-op option for compatibility with
446 Solaris m4. Warn if optarg is all numeric. FIXME -
447 silence this warning after 2.0. */
448 if (isdigit (to_uchar (*optarg
)))
452 strtol (optarg
, &end
, 10);
453 if (*end
== '\0' && errno
== 0)
454 error (0, 0, _("Warning: recommend using `-B ./%s' instead"),
458 case PREPEND_INCLUDE_OPTION
:
459 m4_add_include_directory (context
, optarg
, true);
463 m4_debug_decode (context
, "-d");
464 if (m4_get_fatal_warnings_opt (context
))
465 m4_set_warnings_exit_opt (context
, true);
467 m4_set_fatal_warnings_opt (context
, true);
471 frozen_file_to_write
= optarg
;
475 m4_set_posixly_correct_opt (context
, true);
479 m4_add_include_directory (context
, optarg
, false);
483 size
= size_opt (optarg
, oi
, optchar
);
486 m4_set_nesting_limit_opt (context
, size
);
490 if (lt_dlinsertsearchdir (lt_dlgetsearchpath (), optarg
) != 0)
492 const char *dlerr
= lt_dlerror ();
494 m4_error (context
, EXIT_FAILURE
, 0, NULL
,
495 _("failed to add search directory `%s'"),
498 m4_error (context
, EXIT_FAILURE
, 0, NULL
,
499 _("failed to add search directory `%s': %s"),
505 m4_set_prefix_builtins_opt (context
, true);
509 m4_set_suppress_warnings_opt (context
, true);
513 frozen_file_to_read
= optarg
;
517 /* FIXME - should W take an optional argument, to allow -Wall,
518 -Wnone, -Werror, -Wcategory, -Wno-category? If so, then have
520 m4_set_suppress_warnings_opt (context
, false);
524 interactive
= INTERACTIVE_NO
;
528 m4_set_discard_comments_opt (context
, true);
532 /* Staggered handling of 'd', since -dm is useful prior to
533 first file and prior to reloading, but other -d must also
534 have effect between files. */
535 if (seen_file
|| frozen_file_to_read
)
537 if (m4_debug_decode (context
, optarg
) < 0)
538 error (0, 0, _("bad debug flags: `%s'"), optarg
);
542 error (0, 0, _("Warning: `%s' is deprecated, use `%s' instead"),
546 interactive
= INTERACTIVE_YES
;
550 m4_set_posixly_correct_opt (context
, false);
553 case ARGLENGTH_OPTION
:
554 error (0, 0, _("Warning: `%s' is deprecated, use `%s' instead"),
555 "--arglength", "--debuglen");
558 size
= size_opt (optarg
, oi
, optchar
);
561 m4_set_max_debug_arg_length_opt (context
, size
);
565 case ERROR_OUTPUT_OPTION
:
566 /* FIXME: -o is inconsistent with other tools' use of
567 -o/--output for creating an output file instead of using
568 stdout, and --error-output is misnamed since it does not
569 affect error messages to stderr. Change the meaning of -o
571 error (0, 0, _("Warning: `%s' is deprecated, use `%s' instead"),
572 optchar
== 'o' ? "-o" : "--error-output", "--debugfile");
574 case DEBUGFILE_OPTION
:
575 /* Don't call m4_debug_set_output here, as it has side effects. */
579 case IMPORT_ENVIRONMENT_OPTION
:
580 import_environment
= true;
584 m4_set_safer_opt (context
, true);
588 version_etc (stdout
, PACKAGE
, PACKAGE_NAME
, VERSION
, AUTHORS
, NULL
);
593 usage (EXIT_SUCCESS
);
598 /* Interactive if specified, or if no input files and stdin and
599 stderr are terminals, to match sh behavior. Interactive mode
600 means unbuffered output, and interrupts ignored. */
602 m4_set_interactive_opt (context
, (interactive
== INTERACTIVE_YES
603 || (interactive
== INTERACTIVE_UNKNOWN
604 && optind
== argc
&& !seen_file
605 && isatty (STDIN_FILENO
)
606 && isatty (STDERR_FILENO
))));
607 if (m4_get_interactive_opt (context
))
609 signal (SIGINT
, SIG_IGN
);
610 setbuf (stdout
, NULL
);
613 signal (SIGPIPE
, SIG_DFL
);
616 /* Do the basic initializations. */
617 if (debugfile
&& !m4_debug_set_output (context
, NULL
, debugfile
))
618 m4_error (context
, 0, errno
, NULL
, _("cannot set debug file `%s'"),
620 m4_input_init (context
);
621 m4_output_init (context
);
622 m4_include_env_init (context
);
624 if (frozen_file_to_read
)
625 reload_frozen_state (context
, frozen_file_to_read
);
628 m4_module_load (context
, "m4", NULL
);
629 if (m4_get_posixly_correct_opt (context
))
630 m4_module_load (context
, "traditional", NULL
);
632 m4_module_load (context
, "gnu", NULL
);
635 /* Import environment variables as macros. The definition are
636 prepended to the macro definition list, so -U can override
637 environment variables. */
639 if (import_environment
)
643 for (env
= envp
; *env
!= NULL
; env
++)
645 defn
= (deferred
*) xmalloc (sizeof *defn
);
653 /* Handle deferred command line macro definitions. Must come after
654 initialization of the symbol table. */
659 const char *arg
= defn
->value
;
666 m4_symbol_value
*value
= m4_symbol_value_create ();
668 const char *str
= strchr (arg
, '=');
669 size_t len
= str
? str
- arg
: strlen (arg
);
671 m4_set_symbol_value_text (value
, xstrdup (str
? str
+ 1 : ""),
672 str
? strlen (str
+ 1) : 0, 0);
674 if (defn
->code
== 'D')
675 m4_symbol_define (M4SYMTAB
, arg
, len
, value
);
677 m4_symbol_pushdef (M4SYMTAB
, arg
, len
, value
);
682 m4_symbol_delete (M4SYMTAB
, arg
, strlen (arg
));
686 if (m4_debug_decode (context
, arg
) < 0)
687 error (0, 0, _("bad debug flags: `%s'"), arg
);
691 /* FIXME - should loading a module result in output? */
692 m4_module_load (context
, arg
, NULL
);
696 m4_set_regexp_syntax_opt (context
, m4_regexp_syntax_encode (arg
));
697 if (m4_get_regexp_syntax_opt (context
) < 0)
698 m4_error (context
, EXIT_FAILURE
, 0, NULL
,
699 _("bad regexp syntax option: `%s'"), arg
);
703 m4_set_symbol_name_traced (M4SYMTAB
, arg
, strlen (arg
), true);
707 process_file (context
, arg
);
712 size_t len
= strlen (arg
);
713 if (m4_symbol_lookup (M4SYMTAB
, arg
, len
))
714 m4_symbol_popdef (M4SYMTAB
, arg
, len
);
718 case SYNCOUTPUT_OPTION
:
720 bool previous
= m4_get_syncoutput_opt (context
);
721 m4_call_info info
= {0};
722 info
.name
= "--syncoutput";
723 info
.name_len
= strlen (info
.name
);
724 m4_set_syncoutput_opt (context
,
725 m4_parse_truth_arg (context
, &info
, arg
,
730 case TRACEOFF_OPTION
:
731 m4_set_symbol_name_traced (M4SYMTAB
, arg
, strlen (arg
), false);
734 case UNLOAD_MODULE_OPTION
:
735 /* FIXME - should unloading a module result in output? */
736 m4_module_unload (context
, arg
, NULL
);
740 assert (!"INTERNAL ERROR: bad code in deferred arguments");
749 /* Handle remaining input files. Each file is pushed on the input,
750 and the input read. */
752 if (optind
== argc
&& !seen_file
)
753 process_file (context
, "-");
755 for (; optind
< argc
; optind
++)
756 process_file (context
, argv
[optind
]);
758 /* Now handle wrapup text.
759 FIXME - when -F is in effect, should wrapped text be frozen? */
760 while (m4_pop_wrapup (context
))
761 m4_macro_expand_input (context
);
763 if (frozen_file_to_write
)
764 produce_frozen_state (context
, frozen_file_to_write
);
767 m4_make_diversion (context
, 0);
768 m4_undivert_all (context
);
771 /* The remaining cleanup functions systematically free all of the
772 memory we still have pointers to. By definition, if there is
773 anything left when we're done: it was caused by a memory leak.
774 Strictly, we don't need to do this, but it makes leak detection
775 a whole lot easier! */
777 m4__module_exit (context
);
781 /* Change debug stream back to stderr, to force flushing the debug
782 stream and detect any errors it might have encountered. The
783 three standard streams are closed by close_stdin. */
784 m4_debug_set_output (context
, NULL
, NULL
);
786 exit_status
= m4_get_exit_status (context
);