]> git.saurik.com Git - bison.git/blame - src/getargs.c
getargs: add support for --flags/-f
[bison.git] / src / getargs.c
CommitLineData
08721544
PE
1/* Parse command line arguments for Bison.
2
c932d613 3 Copyright (C) 1984, 1986, 1989, 1992, 2000-2012 Free Software
ea0a7676 4 Foundation, Inc.
3d8fc6ca 5
9f306f2a 6 This file is part of Bison, the GNU Compiler Compiler.
3d8fc6ca 7
f16b0819
PE
8 This program 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.
3d8fc6ca 12
f16b0819
PE
13 This program 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.
3d8fc6ca 17
9f306f2a 18 You should have received a copy of the GNU General Public License
f16b0819 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
3d8fc6ca 20
2cec9080 21#include <config.h>
3d8fc6ca 22#include "system.h"
d4bd2295 23#include "output.h"
d38a11a6
PE
24
25#include <argmatch.h>
d7e0a1a7 26#include <c-strcase.h>
3b2942e6 27#include <configmake.h>
d38a11a6 28#include <error.h>
f47dbf6b
PE
29
30/* Hack to get <getopt.h> to declare getopt with a prototype. */
31#if lint && ! defined __GNU_LIBRARY__
32# define __GNU_LIBRARY__
33# define HACK_FOR___GNU_LIBRARY___PROTOTYPE 1
34#endif
35
d38a11a6
PE
36#include <getopt.h>
37
f47dbf6b
PE
38#ifdef HACK_FOR___GNU_LIBRARY___PROTOTYPE
39# undef __GNU_LIBRARY__
40# undef HACK_FOR___GNU_LIBRARY___PROTOTYPE
41#endif
42
a055b2f0
AD
43#include <progname.h>
44
b0ce6046 45#include "complain.h"
ec3bc396 46#include "files.h"
d38a11a6 47#include "getargs.h"
23ec25b7 48#include "muscle-tab.h"
4c787a31 49#include "quote.h"
d38a11a6 50#include "uniqstr.h"
3d8fc6ca 51
e0992e54 52bool debug;
d0829076 53bool defines_flag;
4e83ea15 54bool graph_flag;
41d7a5f2 55bool xml_flag;
d0829076
PE
56bool locations_flag;
57bool no_lines_flag;
d0829076
PE
58bool token_table_flag;
59bool yacc_flag; /* for -y */
4e83ea15
AD
60
61bool error_verbose = false;
d2729d44 62
916708d5
AD
63bool nondeterministic_parser = false;
64bool glr_parser = false;
916708d5 65
0db26489 66int feature_flag = feature_none;
4e83ea15
AD
67int report_flag = report_none;
68int trace_flag = trace_none;
6f8bdce2
JD
69int warnings_flag = warnings_conflicts_sr | warnings_conflicts_rr
70 | warnings_other;
4e83ea15 71
0e021770
PE
72static struct bison_language const valid_languages[] = {
73 { "c", "c-skel.m4", ".c", ".h", true },
74 { "c++", "c++-skel.m4", ".cc", ".hh", true },
8405b70c 75 { "java", "java-skel.m4", ".java", ".java", false },
0e021770
PE
76 { "", "", "", "", false }
77};
78
4b1ebc49 79int skeleton_prio = default_prio;
b0ce6046 80const char *skeleton = NULL;
4b1ebc49 81int language_prio = default_prio;
0e021770 82struct bison_language const *language = &valid_languages[0];
f6bd5427 83const char *include = NULL;
b0ce6046 84
273a74fa 85
7b42569e
AD
86/** Decode an option's set of keys.
87 *
88 * \param option option being decoded.
07c39ae9 89 * \param keys array of valid subarguments.
7b42569e 90 * \param values array of corresponding (int) values.
dab96632 91 * \param all the all value.
07c39ae9 92 * \param flags the flags to update
20cc7149 93 * \param args comma separated list of effective subarguments to decode.
7b42569e
AD
94 * If 0, then activate all the flags.
95 *
20cc7149 96 * If VALUE != 0 then KEY sets flags and no-KEY clears them.
dab96632
JD
97 * If VALUE == 0 then KEY clears all flags from \c all and no-KEY sets all
98 * flags from \c all. Thus no-none = all and no-all = none.
7b42569e 99 */
80ac75bc
PE
100static void
101flags_argmatch (const char *option,
7b42569e 102 const char * const keys[], const int values[],
dab96632 103 int all, int *flags, char *args)
7b42569e
AD
104{
105 if (args)
106 {
107 args = strtok (args, ",");
ba7560e2 108 while (args)
7b42569e 109 {
20cc7149
DJ
110 int no = strncmp (args, "no-", 3) == 0 ? 3 : 0;
111 int value = XARGMATCH (option, args + no, keys, values);
7b42569e 112 if (value == 0)
dab96632
JD
113 {
114 if (no)
115 *flags |= all;
116 else
117 *flags &= ~all;
118 }
7b42569e 119 else
dab96632
JD
120 {
121 if (no)
122 *flags &= ~value;
123 else
124 *flags |= value;
125 }
eb095650 126 args = strtok (NULL, ",");
7b42569e 127 }
7b42569e
AD
128 }
129 else
dab96632 130 *flags |= all;
7b42569e
AD
131}
132
80ac75bc 133/** Decode a set of sub arguments.
7b42569e
AD
134 *
135 * \param FlagName the flag familly to update.
07c39ae9 136 * \param Args the effective sub arguments to decode.
7b42569e
AD
137 *
138 * \arg FlagName_args the list of keys.
139 * \arg FlagName_types the list of values.
dab96632 140 * \arg FlagName_all the all value.
7b42569e
AD
141 * \arg FlagName_flag the flag to update.
142 */
143#define FLAGS_ARGMATCH(FlagName, Args) \
144 flags_argmatch ("--" #FlagName, FlagName ## _args, FlagName ## _types, \
dab96632 145 FlagName ## _all, &FlagName ## _flag, Args)
7b42569e
AD
146
147
b8a41559
AD
148/*----------------------.
149| --report's handling. |
150`----------------------*/
151
152static const char * const report_args[] =
153{
154 /* In a series of synonyms, present the most meaningful first, so
155 that argmatch_valid be more readable. */
156 "none",
157 "state", "states",
158 "itemset", "itemsets",
159 "lookahead", "lookaheads", "look-ahead",
160 "solved",
161 "all",
162 0
163};
164
165static const int report_types[] =
166{
167 report_none,
168 report_states, report_states,
169 report_states | report_itemsets, report_states | report_itemsets,
170 report_states | report_lookahead_tokens,
171 report_states | report_lookahead_tokens,
172 report_states | report_lookahead_tokens,
173 report_states | report_solved_conflicts,
174 report_all
175};
176
177ARGMATCH_VERIFY (report_args, report_types);
178
b8a41559 179
273a74fa
AD
180/*---------------------.
181| --trace's handling. |
182`---------------------*/
183
184static const char * const trace_args[] =
185{
186 /* In a series of synonyms, present the most meaningful first, so
187 that argmatch_valid be more readable. */
b8a41559 188 "none - no traces",
c5e3e510
AD
189 "scan - grammar scanner traces",
190 "parse - grammar parser traces",
b8a41559 191 "automaton - construction of the automaton",
273a74fa 192 "bitsets - use of bitsets",
b8a41559 193 "grammar - reading, reducing the grammar",
1509d42f 194 "resource - memory consumption (where available)",
273a74fa 195 "sets - grammar sets: firsts, nullable etc.",
c65e5292 196 "muscles - m4 definitions passed to the skeleton",
327afc7c
AD
197 "tools - m4 invocation",
198 "m4 - m4 traces",
c5e3e510
AD
199 "skeleton - skeleton postprocessing",
200 "time - time consumption",
f805dfcb 201 "ielr - IELR conversion",
273a74fa
AD
202 "all - all of the above",
203 0
204};
205
206static const int trace_types[] =
207{
208 trace_none,
473d0a75
AD
209 trace_scan,
210 trace_parse,
273a74fa
AD
211 trace_automaton,
212 trace_bitsets,
213 trace_grammar,
214 trace_resource,
215 trace_sets,
c65e5292 216 trace_muscles,
273a74fa 217 trace_tools,
327afc7c 218 trace_m4,
c5e3e510
AD
219 trace_skeleton,
220 trace_time,
f805dfcb 221 trace_ielr,
273a74fa
AD
222 trace_all
223};
224
8a6f72f3 225ARGMATCH_VERIFY (trace_args, trace_types);
273a74fa 226
7b42569e
AD
227
228/*------------------------.
229| --warnings's handling. |
230`------------------------*/
231
232static const char * const warnings_args[] =
273a74fa 233{
7b42569e
AD
234 /* In a series of synonyms, present the most meaningful first, so
235 that argmatch_valid be more readable. */
17bd8a73
JD
236 "none - no warnings",
237 "midrule-values - unset or unused midrule values",
44c124a3 238 "yacc - incompatibilities with POSIX Yacc",
6f8bdce2
JD
239 "conflicts-sr - S/R conflicts",
240 "conflicts-rr - R/R conflicts",
8ffd7912 241 "other - all other warnings",
17bd8a73
JD
242 "all - all of the above",
243 "error - warnings are errors",
7b42569e
AD
244 0
245};
246
247static const int warnings_types[] =
248{
249 warnings_none,
17bd8a73 250 warnings_midrule_values,
7b42569e 251 warnings_yacc,
6f8bdce2
JD
252 warnings_conflicts_sr,
253 warnings_conflicts_rr,
8ffd7912 254 warnings_other,
89eb3c76
JD
255 warnings_all,
256 warnings_error
7b42569e
AD
257};
258
259ARGMATCH_VERIFY (warnings_args, warnings_types);
273a74fa 260
0db26489
TR
261/*-----------------------.
262| --feature's handling. |
263`-----------------------*/
264
265static const char * const feature_args[] =
266{
267 "none",
268 "caret", "diagnostics-show-caret",
269 "all",
270 0
271};
272
273static const int feature_types[] =
274{
275 feature_none,
276 feature_caret, feature_caret,
277 feature_all
278};
279
280ARGMATCH_VERIFY (feature_args, feature_types);
273a74fa 281
0e575721
AD
282/*-------------------------------------------.
283| Display the help message and exit STATUS. |
284`-------------------------------------------*/
e79137ac 285
0df27e8b
PE
286static void usage (int) ATTRIBUTE_NORETURN;
287
4a120d45 288static void
0e575721 289usage (int status)
cbd8ffc5 290{
0e575721
AD
291 if (status != 0)
292 fprintf (stderr, _("Try `%s --help' for more information.\n"),
293 program_name);
294 else
295 {
72183df4
DJ
296 /* For ../build-aux/cross-options.pl to work, use the format:
297 ^ -S, --long[=ARGS] (whitespace)
298 A --long option is required.
299 Otherwise, add exceptions to ../build-aux/cross-options.pl. */
300
a92be413 301 printf (_("Usage: %s [OPTION]... FILE\n"), program_name);
0e575721 302 fputs (_("\
51c7ca01 303Generate a deterministic LR or generalized LR (GLR) parser employing\n\
d89e48b3
JD
304LALR(1), IELR(1), or canonical LR(1) parser tables. IELR(1) and\n\
305canonical LR(1) support is experimental.\n\
a92be413
PE
306\n\
307"), stdout);
9f306f2a 308
0e575721 309 fputs (_("\
a92be413 310Mandatory arguments to long options are mandatory for short options too.\n\
8e55b3aa
JD
311"), stdout);
312 fputs (_("\
313The same is true for optional arguments.\n\
a92be413 314"), stdout);
9f306f2a 315
0e575721 316 fputs (_("\
a92be413 317\n\
9f306f2a 318Operation modes:\n\
620b2e36
JD
319 -h, --help display this help and exit\n\
320 -V, --version output version information and exit\n\
321 --print-localedir output directory containing locale-dependent data\n\
322 --print-datadir output directory containing skeletons and XSLT\n\
323 -y, --yacc emulate POSIX Yacc\n\
324 -W, --warnings[=CATEGORY] report the warnings falling in CATEGORY\n\
0db26489 325 -f, --feature[=FEATURE] activate miscellaneous features\n\
a92be413
PE
326\n\
327"), stdout);
9f306f2a 328
0e575721 329 fputs (_("\
9f306f2a 330Parser:\n\
34d41938 331 -L, --language=LANGUAGE specify the output programming language\n\
34d41938
JD
332 -S, --skeleton=FILE specify the skeleton to use\n\
333 -t, --debug instrument the parser for debugging\n\
334 --locations enable location support\n\
4b3847c3
AD
335 -D, --define=NAME[=VALUE] similar to '%define NAME \"VALUE\"'\n\
336 -F, --force-define=NAME[=VALUE] override '%define NAME \"VALUE\"'\n\
34d41938 337 -p, --name-prefix=PREFIX prepend PREFIX to the external symbols\n\
4b3847c3
AD
338 deprecated by '-Dapi.prefix=PREFIX'\n\
339 -l, --no-lines don't generate '#line' directives\n\
34d41938 340 -k, --token-table include a table of token names\n\
0e575721 341"), stdout);
0db26489 342 putc ('\n', stdout);
9f306f2a 343
8e55b3aa
JD
344 /* Keep -d and --defines separate so that ../build-aux/cross-options.pl
345 * won't assume that -d also takes an argument. */
0e575721 346 fputs (_("\
9f306f2a 347Output:\n\
620b2e36
JD
348 --defines[=FILE] also produce a header file\n\
349 -d likewise but cannot specify FILE (for POSIX Yacc)\n\
350 -r, --report=THINGS also produce details on the automaton\n\
351 --report-file=FILE write report to FILE\n\
352 -v, --verbose same as `--report=state'\n\
353 -b, --file-prefix=PREFIX specify a PREFIX for output files\n\
354 -o, --output=FILE leave output to FILE\n\
355 -g, --graph[=FILE] also output a graph of the automaton\n\
356 -x, --xml[=FILE] also output an XML report of the automaton\n\
357 (the XML schema is experimental)\n\
0e575721 358"), stdout);
0db26489 359 putc ('\n', stdout);
86eff183 360
6aeb9c57
AD
361 fputs (_("\
362Warning categories include:\n\
363 `midrule-values' unset or unused midrule values\n\
44c124a3 364 `yacc' incompatibilities with POSIX Yacc\n\
6f8bdce2
JD
365 `conflicts-sr' S/R conflicts (enabled by default)\n\
366 `conflicts-rr' R/R conflicts (enabled by default)\n\
bd526380 367 `deprecated' obsolete constructs\n\
8ffd7912 368 `other' all other warnings (enabled by default)\n\
6aeb9c57
AD
369 `all' all the warnings\n\
370 `no-CATEGORY' turn off warnings in CATEGORY\n\
371 `none' turn off all the warnings\n\
372 `error' treat warnings as errors\n\
373"), stdout);
bd526380 374 putc ('\n', stdout);
6aeb9c57 375
0e575721 376 fputs (_("\
ec3bc396
AD
377THINGS is a list of comma separated words that can include:\n\
378 `state' describe the states\n\
379 `itemset' complete the core item sets with their closure\n\
742e4900 380 `lookahead' explicitly associate lookahead tokens to items\n\
b408954b 381 `solved' describe shift/reduce conflicts solving\n\
ec3bc396
AD
382 `all' include all the above information\n\
383 `none' disable the report\n\
0e575721 384"), stdout);
0db26489
TR
385 putc ('\n', stdout);
386
387 fputs (_("\
388FEATURE is a list of comma separated words that can include:\n\
389 `caret' show errors with carets\n\
390 `all' all of the above\n\
391 `none' disable all of the above\n\
392 "), stdout);
9f306f2a 393
d740d2b5
AD
394 putc ('\n', stdout);
395 printf (_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT);
396 printf (_("%s home page: <%s>.\n"), PACKAGE_NAME, PACKAGE_URL);
397 fputs (_("General help using GNU software: "
398 "<http://www.gnu.org/gethelp/>.\n"),
399 stdout);
400 /* Don't output this redundant message for English locales.
401 Note we still output for 'C' so that it gets included in the
402 man page. */
403 const char *lc_messages = setlocale (LC_MESSAGES, NULL);
404 if (lc_messages && strcmp (lc_messages, "en_"))
405 /* TRANSLATORS: Replace LANG_CODE in this URL with your language
406 code <http://translationproject.org/team/LANG_CODE.html> to
407 form one of the URLs at http://translationproject.org/team/.
408 Otherwise, replace the entire URL with your translation team's
409 email address. */
410 fputs (_("Report translation bugs to "
411 "<http://translationproject.org/team/>.\n"), stdout);
412 fputs (_("For complete documentation, run: info bison.\n"), stdout);
0e575721
AD
413 }
414
415 exit (status);
cbd8ffc5
DM
416}
417
e79137ac
AD
418
419/*------------------------------.
420| Display the version message. |
421`------------------------------*/
422
423static void
0e575721 424version (void)
e79137ac
AD
425{
426 /* Some efforts were made to ease the translators' task, please
427 continue. */
0e575721
AD
428 printf (_("bison (GNU Bison) %s"), VERSION);
429 putc ('\n', stdout);
430 fputs (_("Written by Robert Corbett and Richard Stallman.\n"), stdout);
431 putc ('\n', stdout);
e79137ac 432
0e575721 433 fprintf (stdout,
a005a9c4
AD
434 _("Copyright (C) %d Free Software Foundation, Inc.\n"),
435 PACKAGE_COPYRIGHT_YEAR);
e79137ac
AD
436
437 fputs (_("\
438This is free software; see the source for copying conditions. There is NO\n\
439warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
440"),
0e575721 441 stdout);
e79137ac
AD
442}
443
444
0e021770
PE
445/*-------------------------------------.
446| --skeleton and --language handling. |
447`--------------------------------------*/
448
449void
e186a284 450skeleton_arg (char const *arg, int prio, location loc)
0e021770
PE
451{
452 if (prio < skeleton_prio)
453 {
454 skeleton_prio = prio;
455 skeleton = arg;
456 }
457 else if (prio == skeleton_prio)
c8bf65f0 458 complain_at (loc, _("multiple skeleton declarations are invalid"));
0e021770
PE
459}
460
461void
e186a284 462language_argmatch (char const *arg, int prio, location loc)
0e021770
PE
463{
464 char const *msg;
465
466 if (prio < language_prio)
467 {
468 int i;
469 for (i = 0; valid_languages[i].language[0]; i++)
abf3f74b
JM
470 if (c_strcasecmp (arg, valid_languages[i].language) == 0)
471 {
472 language_prio = prio;
473 language = &valid_languages[i];
474 return;
475 }
4c787a31 476 msg = _("%s: invalid language");
0e021770
PE
477 }
478 else if (language_prio == prio)
479 msg = _("multiple language declarations are invalid");
480 else
481 return;
482
4c787a31 483 complain_at (loc, msg, quotearg_colon (arg));
0e021770
PE
484}
485
e79137ac
AD
486/*----------------------.
487| Process the options. |
488`----------------------*/
489
7020f1e9
AD
490/* Shorts options.
491 Should be computed from long_options. */
492static char const short_options[] =
e14c6831 493 "D:"
34d41938 494 "F:"
7020f1e9
AD
495 "L:"
496 "S:"
497 "T::"
498 "V"
8e55b3aa 499 "W::"
7020f1e9
AD
500 "b:"
501 "d"
0db26489 502 "f::"
7020f1e9
AD
503 "e"
504 "g::"
505 "h"
506 "k"
507 "l"
508 "n"
509 "o:"
510 "p:"
511 "r:"
512 "t"
513 "v"
514 "x::"
515 "y"
516 ;
e2aaf4c4 517
d0829076
PE
518/* Values for long options that do not have single-letter equivalents. */
519enum
520{
f7ab6a50 521 LOCATIONS_OPTION = CHAR_MAX + 1,
d4bd2295 522 PRINT_LOCALEDIR_OPTION,
1bb2bd75
JD
523 PRINT_DATADIR_OPTION,
524 REPORT_FILE_OPTION
d0829076
PE
525};
526
e2aaf4c4
AD
527static struct option const long_options[] =
528{
529 /* Operation modes. */
7b42569e
AD
530 { "help", no_argument, 0, 'h' },
531 { "version", no_argument, 0, 'V' },
532 { "print-localedir", no_argument, 0, PRINT_LOCALEDIR_OPTION },
d4bd2295 533 { "print-datadir", no_argument, 0, PRINT_DATADIR_OPTION },
7b42569e 534 { "warnings", optional_argument, 0, 'W' },
e2aaf4c4
AD
535
536 /* Parser. */
537 { "name-prefix", required_argument, 0, 'p' },
538 { "include", required_argument, 0, 'I' },
539
540 /* Output. */
541 { "file-prefix", required_argument, 0, 'b' },
542 { "output", required_argument, 0, 'o' },
543 { "output-file", required_argument, 0, 'o' },
544 { "graph", optional_argument, 0, 'g' },
41d7a5f2 545 { "xml", optional_argument, 0, 'x' },
e2aaf4c4 546 { "report", required_argument, 0, 'r' },
1bb2bd75 547 { "report-file", required_argument, 0, REPORT_FILE_OPTION },
e2aaf4c4
AD
548 { "verbose", no_argument, 0, 'v' },
549
550 /* Hidden. */
273a74fa 551 { "trace", optional_argument, 0, 'T' },
e2aaf4c4 552
e2aaf4c4
AD
553 /* Output. */
554 { "defines", optional_argument, 0, 'd' },
0db26489 555 { "flag", optional_argument, 0, 'f' },
e2aaf4c4
AD
556
557 /* Operation modes. */
558 { "fixed-output-files", no_argument, 0, 'y' },
559 { "yacc", no_argument, 0, 'y' },
560
561 /* Parser. */
562 { "debug", no_argument, 0, 't' },
e14c6831 563 { "define", required_argument, 0, 'D' },
34d41938 564 { "force-define", required_argument, 0, 'F' },
d0829076 565 { "locations", no_argument, 0, LOCATIONS_OPTION },
e2aaf4c4 566 { "no-lines", no_argument, 0, 'l' },
e2aaf4c4
AD
567 { "raw", no_argument, 0, 0 },
568 { "skeleton", required_argument, 0, 'S' },
0e021770 569 { "language", required_argument, 0, 'L' },
e2aaf4c4
AD
570 { "token-table", no_argument, 0, 'k' },
571
572 {0, 0, 0, 0}
573};
574
ae404801
AD
575/* Under DOS, there is no difference on the case. This can be
576 troublesome when looking for `.tab' etc. */
577#ifdef MSDOS
578# define AS_FILE_NAME(File) (strlwr (File), (File))
579#else
580# define AS_FILE_NAME(File) (File)
581#endif
582
e14c6831
AD
583/* Build a location for the current command line argument. */
584static
585location
6f5be1ab 586command_line_location (void)
e14c6831
AD
587{
588 location res;
589 /* "<command line>" is used in GCC's messages about -D. */
a37131cc 590 boundary_set (&res.start, uniqstr_new ("<command line>"), optind - 1, -1);
e14c6831
AD
591 res.end = res.start;
592 return res;
593}
594
595
3d8fc6ca 596void
d2729d44 597getargs (int argc, char *argv[])
3d8fc6ca 598{
1916f98e 599 int c;
3d8fc6ca 600
08721544
PE
601 while ((c = getopt_long (argc, argv, short_options, long_options, NULL))
602 != -1)
cd5bd6ac
AD
603 switch (c)
604 {
e14c6831
AD
605 /* ASCII Sorting for short options (i.e., upper case then
606 lower case), and then long-only options. */
607
cd5bd6ac
AD
608 case 0:
609 /* Certain long options cause getopt_long to return 0. */
610 break;
611
e14c6831 612 case 'D': /* -DNAME[=VALUE]. */
34d41938 613 case 'F': /* -FNAME[=VALUE]. */
e14c6831
AD
614 {
615 char* name = optarg;
d143e9c3 616 char* value = mbschr (optarg, '=');
e14c6831 617 if (value)
c4eb1e84 618 *value++ = 0;
10fa0146 619 muscle_percent_define_insert (name, command_line_location (),
34d41938
JD
620 value ? value : "",
621 c == 'D' ? MUSCLE_PERCENT_DEFINE_D
622 : MUSCLE_PERCENT_DEFINE_F);
e14c6831 623 }
22c2cbc0
AD
624 break;
625
8e55b3aa
JD
626 case 'I':
627 include = AS_FILE_NAME (optarg);
41d7a5f2
PE
628 break;
629
0e021770 630 case 'L':
e186a284
AD
631 language_argmatch (optarg, command_line_prio,
632 command_line_location ());
0e021770
PE
633 break;
634
cd5bd6ac 635 case 'S':
e186a284
AD
636 skeleton_arg (AS_FILE_NAME (optarg), command_line_prio,
637 command_line_location ());
cd5bd6ac
AD
638 break;
639
8e55b3aa
JD
640 case 'T':
641 FLAGS_ARGMATCH (trace, optarg);
f6bd5427
MA
642 break;
643
8e55b3aa
JD
644 case 'V':
645 version ();
646 exit (EXIT_SUCCESS);
647
0db26489
TR
648 case 'f':
649 FLAGS_ARGMATCH (flag, optarg);
650 break;
651
8e55b3aa 652 case 'W':
dab96632 653 FLAGS_ARGMATCH (warnings, optarg);
8e55b3aa
JD
654 break;
655
656 case 'b':
657 spec_file_prefix = AS_FILE_NAME (optarg);
658 break;
659
e14c6831
AD
660 case 'd':
661 /* Here, the -d and --defines options are differentiated. */
662 defines_flag = true;
663 if (optarg)
0b7fba13
AD
664 {
665 free (spec_defines_file);
666 spec_defines_file = xstrdup (AS_FILE_NAME (optarg));
667 }
e14c6831
AD
668 break;
669
8e55b3aa
JD
670 case 'g':
671 graph_flag = true;
672 if (optarg)
0b7fba13
AD
673 {
674 free (spec_graph_file);
675 spec_graph_file = xstrdup (AS_FILE_NAME (optarg));
676 }
cd5bd6ac
AD
677 break;
678
8e55b3aa
JD
679 case 'h':
680 usage (EXIT_SUCCESS);
681
7b42569e
AD
682 case 'k':
683 token_table_flag = true;
684 break;
685
cd5bd6ac 686 case 'l':
d0829076
PE
687 no_lines_flag = true;
688 break;
689
7b42569e
AD
690 case 'o':
691 spec_outfile = AS_FILE_NAME (optarg);
cd5bd6ac
AD
692 break;
693
7b42569e
AD
694 case 'p':
695 spec_name_prefix = optarg;
696 break;
697
698 case 'r':
699 FLAGS_ARGMATCH (report, optarg);
700 break;
701
cd5bd6ac 702 case 't':
e0992e54 703 debug = true;
cd5bd6ac
AD
704 break;
705
7b42569e
AD
706 case 'v':
707 report_flag |= report_states;
cd5bd6ac
AD
708 break;
709
8e55b3aa
JD
710 case 'x':
711 xml_flag = true;
712 if (optarg)
0b7fba13
AD
713 {
714 free (spec_xml_file);
715 spec_xml_file = xstrdup (AS_FILE_NAME (optarg));
716 }
cd5bd6ac
AD
717 break;
718
8e55b3aa
JD
719 case 'y':
720 yacc_flag = true;
ec3bc396
AD
721 break;
722
7b42569e
AD
723 case LOCATIONS_OPTION:
724 locations_flag = true;
273a74fa
AD
725 break;
726
7b42569e
AD
727 case PRINT_LOCALEDIR_OPTION:
728 printf ("%s\n", LOCALEDIR);
729 exit (EXIT_SUCCESS);
730
d4bd2295
JD
731 case PRINT_DATADIR_OPTION:
732 printf ("%s\n", compute_pkgdatadir ());
733 exit (EXIT_SUCCESS);
734
8e55b3aa 735 case REPORT_FILE_OPTION:
0b7fba13 736 free (spec_verbose_file);
8e55b3aa
JD
737 spec_verbose_file = xstrdup (AS_FILE_NAME (optarg));
738 break;
739
cd5bd6ac 740 default:
0df27e8b 741 usage (EXIT_FAILURE);
cd5bd6ac 742 }
3d8fc6ca 743
a4b6efd4 744 if (argc - optind != 1)
3d8fc6ca 745 {
a4b6efd4 746 if (argc - optind < 1)
4c787a31 747 error (0, 0, _("%s: missing operand"), quotearg_colon (argv[argc - 1]));
a4b6efd4 748 else
4c787a31 749 error (0, 0, _("extra operand %s"), quote (argv[optind + 1]));
0e575721 750 usage (EXIT_FAILURE);
3d8fc6ca 751 }
3d8fc6ca 752
d38a11a6 753 current_file = grammar_file = uniqstr_new (argv[optind]);
75c21b61 754 MUSCLE_INSERT_C_STRING ("file_name", grammar_file);
3d8fc6ca 755}
812775a0
JD
756
757void
758tr (char *s, char from, char to)
759{
760 for (; *s; s++)
761 if (*s == from)
762 *s = to;
763}