]> git.saurik.com Git - bison.git/blame - src/getargs.c
Makefile: introduce $(BISON).
[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"
9fe5a457 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",
273a74fa
AD
189 "all - all of the above",
190 0
191};
192
193static const int trace_types[] =
194{
195 trace_none,
473d0a75
AD
196 trace_scan,
197 trace_parse,
273a74fa
AD
198 trace_automaton,
199 trace_bitsets,
200 trace_grammar,
201 trace_resource,
202 trace_sets,
5263bea9 203 trace_muscles,
273a74fa 204 trace_tools,
327afc7c 205 trace_m4,
c5e3e510
AD
206 trace_skeleton,
207 trace_time,
273a74fa
AD
208 trace_all
209};
210
8a6f72f3 211ARGMATCH_VERIFY (trace_args, trace_types);
273a74fa 212
7b42569e
AD
213
214/*------------------------.
215| --warnings's handling. |
216`------------------------*/
217
218static const char * const warnings_args[] =
273a74fa 219{
7b42569e
AD
220 /* In a series of synonyms, present the most meaningful first, so
221 that argmatch_valid be more readable. */
17bd8a73
JD
222 "none - no warnings",
223 "midrule-values - unset or unused midrule values",
224 "yacc - incompatibilities with POSIX YACC",
225 "all - all of the above",
226 "error - warnings are errors",
7b42569e
AD
227 0
228};
229
230static const int warnings_types[] =
231{
232 warnings_none,
17bd8a73 233 warnings_midrule_values,
7b42569e 234 warnings_yacc,
89eb3c76
JD
235 warnings_all,
236 warnings_error
7b42569e
AD
237};
238
239ARGMATCH_VERIFY (warnings_args, warnings_types);
273a74fa
AD
240
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
AD
251 if (status != 0)
252 fprintf (stderr, _("Try `%s --help' for more information.\n"),
253 program_name);
254 else
255 {
a7c09cba
DJ
256 /* For ../build-aux/cross-options.pl to work, use the format:
257 ^ -S, --long[=ARGS] (whitespace)
258 A --long option is required.
259 Otherwise, add exceptions to ../build-aux/cross-options.pl. */
260
a92be413 261 printf (_("Usage: %s [OPTION]... FILE\n"), program_name);
0e575721 262 fputs (_("\
a92be413
PE
263Generate LALR(1) and GLR parsers.\n\
264\n\
265"), stdout);
9f306f2a 266
0e575721 267 fputs (_("\
a92be413 268Mandatory arguments to long options are mandatory for short options too.\n\
8e55b3aa
JD
269"), stdout);
270 fputs (_("\
271The same is true for optional arguments.\n\
a92be413 272"), stdout);
9f306f2a 273
0e575721 274 fputs (_("\
a92be413 275\n\
9f306f2a 276Operation modes:\n\
f7ab6a50
PE
277 -h, --help display this help and exit\n\
278 -V, --version output version information and exit\n\
279 --print-localedir output directory containing locale-dependent data\n\
d4bd2295 280 --print-datadir output directory containing skeletons and XSLT\n\
a92be413 281 -y, --yacc emulate POSIX Yacc\n\
9b9e0a7d 282 -W, --warnings[=CATEGORY] report the warnings falling in CATEGORY\n\
a92be413
PE
283\n\
284"), stdout);
9f306f2a 285
0e575721 286 fputs (_("\
9f306f2a 287Parser:\n\
59da312b 288 -L, --language=LANGUAGE specify the output programming language\n\
ed4d67dc 289 (this is an experimental feature)\n\
cd5bd6ac 290 -S, --skeleton=FILE specify the skeleton to use\n\
9f306f2a 291 -t, --debug instrument the parser for debugging\n\
58697c6d
AD
292 --locations enable location support\n\
293 -D, --define=NAME[=VALUE] same as `%define NAME \"VALUE\"'\n\
9f306f2a
AD
294 -p, --name-prefix=PREFIX prepend PREFIX to the external symbols\n\
295 -l, --no-lines don't generate `#line' directives\n\
9f306f2a 296 -k, --token-table include a table of token names\n\
a92be413 297\n\
0e575721 298"), stdout);
9f306f2a 299
8e55b3aa
JD
300 /* Keep -d and --defines separate so that ../build-aux/cross-options.pl
301 * won't assume that -d also takes an argument. */
0e575721 302 fputs (_("\
9f306f2a 303Output:\n\
8e55b3aa
JD
304 --defines[=FILE] also produce a header file\n\
305 -d likewise but cannot specify FILE (for POSIX Yacc)\n\
ec3bc396 306 -r, --report=THINGS also produce details on the automaton\n\
1bb2bd75 307 --report-file=FILE write report to FILE\n\
ec3bc396 308 -v, --verbose same as `--report=state'\n\
9f306f2a 309 -b, --file-prefix=PREFIX specify a PREFIX for output files\n\
951366c1 310 -o, --output=FILE leave output to FILE\n\
6aeb9c57
AD
311 -g, --graph[=FILE] also output a graph of the automaton\n\
312 -x, --xml[=FILE] also output an XML report of the automaton\n\
59da312b 313 (the XML schema is experimental)\n\
a92be413 314\n\
0e575721 315"), stdout);
86eff183 316
6aeb9c57
AD
317 fputs (_("\
318Warning categories include:\n\
319 `midrule-values' unset or unused midrule values\n\
320 `yacc' incompatibilities with POSIX YACC\n\
321 `all' all the warnings\n\
322 `no-CATEGORY' turn off warnings in CATEGORY\n\
323 `none' turn off all the warnings\n\
324 `error' treat warnings as errors\n\
66f0441d 325\n\
6aeb9c57
AD
326"), stdout);
327
0e575721 328 fputs (_("\
ec3bc396
AD
329THINGS is a list of comma separated words that can include:\n\
330 `state' describe the states\n\
331 `itemset' complete the core item sets with their closure\n\
742e4900 332 `lookahead' explicitly associate lookahead tokens to items\n\
b408954b 333 `solved' describe shift/reduce conflicts solving\n\
ec3bc396
AD
334 `all' include all the above information\n\
335 `none' disable the report\n\
0e575721 336"), stdout);
9f306f2a 337
a92be413 338 printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
0e575721
AD
339 }
340
341 exit (status);
cbd8ffc5
DM
342}
343
e79137ac
AD
344
345/*------------------------------.
346| Display the version message. |
347`------------------------------*/
348
349static void
0e575721 350version (void)
e79137ac
AD
351{
352 /* Some efforts were made to ease the translators' task, please
353 continue. */
0e575721
AD
354 printf (_("bison (GNU Bison) %s"), VERSION);
355 putc ('\n', stdout);
356 fputs (_("Written by Robert Corbett and Richard Stallman.\n"), stdout);
357 putc ('\n', stdout);
e79137ac 358
0e575721 359 fprintf (stdout,
a005a9c4
AD
360 _("Copyright (C) %d Free Software Foundation, Inc.\n"),
361 PACKAGE_COPYRIGHT_YEAR);
e79137ac
AD
362
363 fputs (_("\
364This is free software; see the source for copying conditions. There is NO\n\
365warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
366"),
0e575721 367 stdout);
e79137ac
AD
368}
369
370
0e021770
PE
371/*-------------------------------------.
372| --skeleton and --language handling. |
373`--------------------------------------*/
374
375void
5a893c2b 376skeleton_arg (char const *arg, int prio, location loc)
0e021770
PE
377{
378 if (prio < skeleton_prio)
379 {
380 skeleton_prio = prio;
381 skeleton = arg;
382 }
383 else if (prio == skeleton_prio)
384 {
385 char const *msg =
386 _("multiple skeleton declarations are invalid");
5a893c2b 387 complain_at (loc, msg);
0e021770
PE
388 }
389}
390
391void
5a893c2b 392language_argmatch (char const *arg, int prio, location loc)
0e021770
PE
393{
394 char const *msg;
395
396 if (prio < language_prio)
397 {
398 int i;
399 for (i = 0; valid_languages[i].language[0]; i++)
d7e0a1a7 400 if (c_strcasecmp (arg, valid_languages[i].language) == 0)
0e021770
PE
401 {
402 language_prio = prio;
403 language = &valid_languages[i];
404 return;
405 }
406 msg = _("invalid language `%s'");
407 }
408 else if (language_prio == prio)
409 msg = _("multiple language declarations are invalid");
410 else
411 return;
412
5a893c2b 413 complain_at (loc, msg, arg);
0e021770
PE
414}
415
e79137ac
AD
416/*----------------------.
417| Process the options. |
418`----------------------*/
419
7020f1e9
AD
420/* Shorts options.
421 Should be computed from long_options. */
422static char const short_options[] =
58697c6d 423 "D:"
7020f1e9
AD
424 "L:"
425 "S:"
426 "T::"
427 "V"
8e55b3aa 428 "W::"
7020f1e9
AD
429 "b:"
430 "d"
431 "e"
432 "g::"
433 "h"
434 "k"
435 "l"
436 "n"
437 "o:"
438 "p:"
439 "r:"
440 "t"
441 "v"
442 "x::"
443 "y"
444 ;
e2aaf4c4 445
d0829076
PE
446/* Values for long options that do not have single-letter equivalents. */
447enum
448{
f7ab6a50 449 LOCATIONS_OPTION = CHAR_MAX + 1,
d4bd2295 450 PRINT_LOCALEDIR_OPTION,
1bb2bd75
JD
451 PRINT_DATADIR_OPTION,
452 REPORT_FILE_OPTION
d0829076
PE
453};
454
e2aaf4c4
AD
455static struct option const long_options[] =
456{
457 /* Operation modes. */
7b42569e
AD
458 { "help", no_argument, 0, 'h' },
459 { "version", no_argument, 0, 'V' },
460 { "print-localedir", no_argument, 0, PRINT_LOCALEDIR_OPTION },
d4bd2295 461 { "print-datadir", no_argument, 0, PRINT_DATADIR_OPTION },
7b42569e 462 { "warnings", optional_argument, 0, 'W' },
e2aaf4c4
AD
463
464 /* Parser. */
465 { "name-prefix", required_argument, 0, 'p' },
466 { "include", required_argument, 0, 'I' },
467
468 /* Output. */
469 { "file-prefix", required_argument, 0, 'b' },
470 { "output", required_argument, 0, 'o' },
471 { "output-file", required_argument, 0, 'o' },
472 { "graph", optional_argument, 0, 'g' },
41d7a5f2 473 { "xml", optional_argument, 0, 'x' },
e2aaf4c4 474 { "report", required_argument, 0, 'r' },
1bb2bd75 475 { "report-file", required_argument, 0, REPORT_FILE_OPTION },
e2aaf4c4
AD
476 { "verbose", no_argument, 0, 'v' },
477
478 /* Hidden. */
273a74fa 479 { "trace", optional_argument, 0, 'T' },
e2aaf4c4 480
e2aaf4c4
AD
481 /* Output. */
482 { "defines", optional_argument, 0, 'd' },
483
484 /* Operation modes. */
485 { "fixed-output-files", no_argument, 0, 'y' },
486 { "yacc", no_argument, 0, 'y' },
487
488 /* Parser. */
489 { "debug", no_argument, 0, 't' },
58697c6d 490 { "define", required_argument, 0, 'D' },
d0829076 491 { "locations", no_argument, 0, LOCATIONS_OPTION },
e2aaf4c4 492 { "no-lines", no_argument, 0, 'l' },
e2aaf4c4
AD
493 { "raw", no_argument, 0, 0 },
494 { "skeleton", required_argument, 0, 'S' },
0e021770 495 { "language", required_argument, 0, 'L' },
e2aaf4c4
AD
496 { "token-table", no_argument, 0, 'k' },
497
498 {0, 0, 0, 0}
499};
500
ae404801
AD
501/* Under DOS, there is no difference on the case. This can be
502 troublesome when looking for `.tab' etc. */
503#ifdef MSDOS
504# define AS_FILE_NAME(File) (strlwr (File), (File))
505#else
506# define AS_FILE_NAME(File) (File)
507#endif
508
58697c6d
AD
509/* Build a location for the current command line argument. */
510static
511location
d73e55e0 512command_line_location (void)
58697c6d
AD
513{
514 location res;
515 /* "<command line>" is used in GCC's messages about -D. */
516 boundary_set (&res.start, uniqstr_new ("<command line>"), optind, -1);
517 res.end = res.start;
518 return res;
519}
520
521
3d8fc6ca 522void
d2729d44 523getargs (int argc, char *argv[])
3d8fc6ca 524{
1916f98e 525 int c;
3d8fc6ca 526
08721544
PE
527 while ((c = getopt_long (argc, argv, short_options, long_options, NULL))
528 != -1)
cd5bd6ac
AD
529 switch (c)
530 {
58697c6d
AD
531 /* ASCII Sorting for short options (i.e., upper case then
532 lower case), and then long-only options. */
533
cd5bd6ac
AD
534 case 0:
535 /* Certain long options cause getopt_long to return 0. */
536 break;
537
58697c6d
AD
538 case 'D': /* -DNAME[=VALUE]. */
539 {
540 char* name = optarg;
541 char* value = strchr (optarg, '=');
542 if (value)
9ce405ce 543 *value++ = 0;
a8beef7e 544 muscle_percent_define_insert (name, command_line_location (),
9ce405ce 545 value ? value : "");
58697c6d 546 }
22c2cbc0
AD
547 break;
548
8e55b3aa
JD
549 case 'I':
550 include = AS_FILE_NAME (optarg);
41d7a5f2
PE
551 break;
552
0e021770 553 case 'L':
51365192
JD
554 language_argmatch (optarg, command_line_prio,
555 command_line_location ());
0e021770
PE
556 break;
557
cd5bd6ac 558 case 'S':
51365192
JD
559 skeleton_arg (AS_FILE_NAME (optarg), command_line_prio,
560 command_line_location ());
cd5bd6ac
AD
561 break;
562
8e55b3aa
JD
563 case 'T':
564 FLAGS_ARGMATCH (trace, optarg);
f6bd5427
MA
565 break;
566
8e55b3aa
JD
567 case 'V':
568 version ();
569 exit (EXIT_SUCCESS);
570
571 case 'W':
ae404801 572 if (optarg)
8e55b3aa
JD
573 FLAGS_ARGMATCH (warnings, optarg);
574 else
575 warnings_flag |= warnings_all;
576 break;
577
578 case 'b':
579 spec_file_prefix = AS_FILE_NAME (optarg);
580 break;
581
58697c6d
AD
582 case 'd':
583 /* Here, the -d and --defines options are differentiated. */
584 defines_flag = true;
585 if (optarg)
586 spec_defines_file = xstrdup (AS_FILE_NAME (optarg));
587 break;
588
8e55b3aa
JD
589 case 'g':
590 graph_flag = true;
591 if (optarg)
592 spec_graph_file = xstrdup (AS_FILE_NAME (optarg));
cd5bd6ac
AD
593 break;
594
8e55b3aa
JD
595 case 'h':
596 usage (EXIT_SUCCESS);
597
7b42569e
AD
598 case 'k':
599 token_table_flag = true;
600 break;
601
cd5bd6ac 602 case 'l':
d0829076
PE
603 no_lines_flag = true;
604 break;
605
7b42569e
AD
606 case 'o':
607 spec_outfile = AS_FILE_NAME (optarg);
cd5bd6ac
AD
608 break;
609
7b42569e
AD
610 case 'p':
611 spec_name_prefix = optarg;
612 break;
613
614 case 'r':
615 FLAGS_ARGMATCH (report, optarg);
616 break;
617
cd5bd6ac 618 case 't':
0ce61575 619 muscle_percent_define_insert ("debug", command_line_location (), "");
cd5bd6ac
AD
620 break;
621
7b42569e
AD
622 case 'v':
623 report_flag |= report_states;
cd5bd6ac
AD
624 break;
625
8e55b3aa
JD
626 case 'x':
627 xml_flag = true;
628 if (optarg)
629 spec_xml_file = xstrdup (AS_FILE_NAME (optarg));
cd5bd6ac
AD
630 break;
631
8e55b3aa
JD
632 case 'y':
633 yacc_flag = true;
ec3bc396
AD
634 break;
635
7b42569e 636 case LOCATIONS_OPTION:
bc0f5737
AD
637 muscle_percent_define_ensure ("locations",
638 command_line_location (), true);
273a74fa
AD
639 break;
640
7b42569e
AD
641 case PRINT_LOCALEDIR_OPTION:
642 printf ("%s\n", LOCALEDIR);
643 exit (EXIT_SUCCESS);
644
d4bd2295
JD
645 case PRINT_DATADIR_OPTION:
646 printf ("%s\n", compute_pkgdatadir ());
647 exit (EXIT_SUCCESS);
648
8e55b3aa
JD
649 case REPORT_FILE_OPTION:
650 spec_verbose_file = xstrdup (AS_FILE_NAME (optarg));
651 break;
652
cd5bd6ac 653 default:
0df27e8b 654 usage (EXIT_FAILURE);
cd5bd6ac 655 }
3d8fc6ca 656
a4b6efd4 657 if (argc - optind != 1)
3d8fc6ca 658 {
a4b6efd4
PE
659 if (argc - optind < 1)
660 error (0, 0, _("missing operand after `%s'"), argv[argc - 1]);
661 else
662 error (0, 0, _("extra operand `%s'"), argv[optind + 1]);
0e575721 663 usage (EXIT_FAILURE);
3d8fc6ca 664 }
3d8fc6ca 665
d38a11a6 666 current_file = grammar_file = uniqstr_new (argv[optind]);
9fe5a457 667 MUSCLE_INSERT_C_STRING ("file_name", grammar_file);
3d8fc6ca 668}