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