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