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