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