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