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