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