]> git.saurik.com Git - bison.git/blame - src/getargs.c
java: finish fixing parser stack popping bug.
[bison.git] / src / getargs.c
CommitLineData
08721544
PE
1/* Parse command line arguments for Bison.
2
ea0a7676
JD
3 Copyright (C) 1984, 1986, 1989, 1992, 2000-2011 Free Software
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>
75c21b61 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"
23ec25b7 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
4b1ebc49 75int skeleton_prio = default_prio;
b0ce6046 76const char *skeleton = NULL;
4b1ebc49 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
7b42569e
AD
90 * \param args colon separated list of effective subarguments to decode.
91 * If 0, then activate all the flags.
92 *
93 * The special value 0 resets the flags to 0.
94 */
80ac75bc
PE
95static void
96flags_argmatch (const char *option,
7b42569e
AD
97 const char * const keys[], const int values[],
98 int *flags, char *args)
99{
100 if (args)
101 {
102 args = strtok (args, ",");
ba7560e2 103 while (args)
7b42569e
AD
104 {
105 int value = XARGMATCH (option, args, keys, values);
106 if (value == 0)
107 *flags = 0;
108 else
109 *flags |= value;
eb095650 110 args = strtok (NULL, ",");
7b42569e 111 }
7b42569e
AD
112 }
113 else
114 *flags = ~0;
115}
116
80ac75bc 117/** Decode a set of sub arguments.
7b42569e
AD
118 *
119 * \param FlagName the flag familly to update.
07c39ae9 120 * \param Args the effective sub arguments to decode.
7b42569e
AD
121 *
122 * \arg FlagName_args the list of keys.
123 * \arg FlagName_types the list of values.
124 * \arg FlagName_flag the flag to update.
125 */
126#define FLAGS_ARGMATCH(FlagName, Args) \
127 flags_argmatch ("--" #FlagName, FlagName ## _args, FlagName ## _types, \
128 &FlagName ## _flag, Args)
129
130
b8a41559
AD
131/*----------------------.
132| --report's handling. |
133`----------------------*/
134
135static const char * const report_args[] =
136{
137 /* In a series of synonyms, present the most meaningful first, so
138 that argmatch_valid be more readable. */
139 "none",
140 "state", "states",
141 "itemset", "itemsets",
142 "lookahead", "lookaheads", "look-ahead",
143 "solved",
144 "all",
145 0
146};
147
148static const int report_types[] =
149{
150 report_none,
151 report_states, report_states,
152 report_states | report_itemsets, report_states | report_itemsets,
153 report_states | report_lookahead_tokens,
154 report_states | report_lookahead_tokens,
155 report_states | report_lookahead_tokens,
156 report_states | report_solved_conflicts,
157 report_all
158};
159
160ARGMATCH_VERIFY (report_args, report_types);
161
b8a41559 162
273a74fa
AD
163/*---------------------.
164| --trace's handling. |
165`---------------------*/
166
167static const char * const trace_args[] =
168{
169 /* In a series of synonyms, present the most meaningful first, so
170 that argmatch_valid be more readable. */
b8a41559 171 "none - no traces",
c5e3e510
AD
172 "scan - grammar scanner traces",
173 "parse - grammar parser traces",
b8a41559 174 "automaton - construction of the automaton",
273a74fa 175 "bitsets - use of bitsets",
b8a41559 176 "grammar - reading, reducing the grammar",
1509d42f 177 "resource - memory consumption (where available)",
273a74fa 178 "sets - grammar sets: firsts, nullable etc.",
c65e5292 179 "muscles - m4 definitions passed to the skeleton",
327afc7c
AD
180 "tools - m4 invocation",
181 "m4 - m4 traces",
c5e3e510
AD
182 "skeleton - skeleton postprocessing",
183 "time - time consumption",
f805dfcb 184 "ielr - IELR conversion",
273a74fa
AD
185 "all - all of the above",
186 0
187};
188
189static const int trace_types[] =
190{
191 trace_none,
473d0a75
AD
192 trace_scan,
193 trace_parse,
273a74fa
AD
194 trace_automaton,
195 trace_bitsets,
196 trace_grammar,
197 trace_resource,
198 trace_sets,
c65e5292 199 trace_muscles,
273a74fa 200 trace_tools,
327afc7c 201 trace_m4,
c5e3e510
AD
202 trace_skeleton,
203 trace_time,
f805dfcb 204 trace_ielr,
273a74fa
AD
205 trace_all
206};
207
8a6f72f3 208ARGMATCH_VERIFY (trace_args, trace_types);
273a74fa 209
7b42569e
AD
210
211/*------------------------.
212| --warnings's handling. |
213`------------------------*/
214
215static const char * const warnings_args[] =
273a74fa 216{
7b42569e
AD
217 /* In a series of synonyms, present the most meaningful first, so
218 that argmatch_valid be more readable. */
17bd8a73
JD
219 "none - no warnings",
220 "midrule-values - unset or unused midrule values",
44c124a3 221 "yacc - incompatibilities with POSIX Yacc",
17bd8a73
JD
222 "all - all of the above",
223 "error - warnings are errors",
7b42569e
AD
224 0
225};
226
227static const int warnings_types[] =
228{
229 warnings_none,
17bd8a73 230 warnings_midrule_values,
7b42569e 231 warnings_yacc,
89eb3c76
JD
232 warnings_all,
233 warnings_error
7b42569e
AD
234};
235
236ARGMATCH_VERIFY (warnings_args, warnings_types);
273a74fa
AD
237
238
0e575721
AD
239/*-------------------------------------------.
240| Display the help message and exit STATUS. |
241`-------------------------------------------*/
e79137ac 242
0df27e8b
PE
243static void usage (int) ATTRIBUTE_NORETURN;
244
4a120d45 245static void
0e575721 246usage (int status)
cbd8ffc5 247{
0e575721
AD
248 if (status != 0)
249 fprintf (stderr, _("Try `%s --help' for more information.\n"),
250 program_name);
251 else
252 {
72183df4
DJ
253 /* For ../build-aux/cross-options.pl to work, use the format:
254 ^ -S, --long[=ARGS] (whitespace)
255 A --long option is required.
256 Otherwise, add exceptions to ../build-aux/cross-options.pl. */
257
a92be413 258 printf (_("Usage: %s [OPTION]... FILE\n"), program_name);
0e575721 259 fputs (_("\
51c7ca01 260Generate a deterministic LR or generalized LR (GLR) parser employing\n\
d89e48b3
JD
261LALR(1), IELR(1), or canonical LR(1) parser tables. IELR(1) and\n\
262canonical LR(1) support is experimental.\n\
a92be413
PE
263\n\
264"), stdout);
9f306f2a 265
0e575721 266 fputs (_("\
a92be413 267Mandatory arguments to long options are mandatory for short options too.\n\
8e55b3aa
JD
268"), stdout);
269 fputs (_("\
270The same is true for optional arguments.\n\
a92be413 271"), stdout);
9f306f2a 272
0e575721 273 fputs (_("\
a92be413 274\n\
9f306f2a 275Operation modes:\n\
620b2e36
JD
276 -h, --help display this help and exit\n\
277 -V, --version output version information and exit\n\
278 --print-localedir output directory containing locale-dependent data\n\
279 --print-datadir output directory containing skeletons and XSLT\n\
280 -y, --yacc emulate POSIX Yacc\n\
281 -W, --warnings[=CATEGORY] report the warnings falling in CATEGORY\n\
a92be413
PE
282\n\
283"), stdout);
9f306f2a 284
0e575721 285 fputs (_("\
9f306f2a 286Parser:\n\
34d41938
JD
287 -L, --language=LANGUAGE specify the output programming language\n\
288 (this is an experimental feature)\n\
289 -S, --skeleton=FILE specify the skeleton to use\n\
290 -t, --debug instrument the parser for debugging\n\
291 --locations enable location support\n\
292 -D, --define=NAME[=VALUE] similar to `%define NAME \"VALUE\"'\n\
293 -F, --force-define=NAME[=VALUE] override `%define NAME \"VALUE\"'\n\
294 -p, --name-prefix=PREFIX prepend PREFIX to the external symbols\n\
295 -l, --no-lines don't generate `#line' directives\n\
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\
620b2e36
JD
304 --defines[=FILE] also produce a header file\n\
305 -d likewise but cannot specify FILE (for POSIX Yacc)\n\
306 -r, --report=THINGS also produce details on the automaton\n\
307 --report-file=FILE write report to FILE\n\
308 -v, --verbose same as `--report=state'\n\
309 -b, --file-prefix=PREFIX specify a PREFIX for output files\n\
310 -o, --output=FILE leave output to FILE\n\
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\
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\
44c124a3 320 `yacc' incompatibilities with POSIX Yacc\n\
6aeb9c57
AD
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
e186a284 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)
c8bf65f0 384 complain_at (loc, _("multiple skeleton declarations are invalid"));
0e021770
PE
385}
386
387void
e186a284 388language_argmatch (char const *arg, int prio, location loc)
0e021770
PE
389{
390 char const *msg;
391
392 if (prio < language_prio)
393 {
394 int i;
395 for (i = 0; valid_languages[i].language[0]; i++)
d7e0a1a7 396 if (c_strcasecmp (arg, valid_languages[i].language) == 0)
0e021770
PE
397 {
398 language_prio = prio;
399 language = &valid_languages[i];
400 return;
401 }
402 msg = _("invalid language `%s'");
403 }
404 else if (language_prio == prio)
405 msg = _("multiple language declarations are invalid");
406 else
407 return;
408
e186a284 409 complain_at (loc, msg, arg);
0e021770
PE
410}
411
e79137ac
AD
412/*----------------------.
413| Process the options. |
414`----------------------*/
415
7020f1e9
AD
416/* Shorts options.
417 Should be computed from long_options. */
418static char const short_options[] =
e14c6831 419 "D:"
34d41938 420 "F:"
7020f1e9
AD
421 "L:"
422 "S:"
423 "T::"
424 "V"
8e55b3aa 425 "W::"
7020f1e9
AD
426 "b:"
427 "d"
428 "e"
429 "g::"
430 "h"
431 "k"
432 "l"
433 "n"
434 "o:"
435 "p:"
436 "r:"
437 "t"
438 "v"
439 "x::"
440 "y"
441 ;
e2aaf4c4 442
d0829076
PE
443/* Values for long options that do not have single-letter equivalents. */
444enum
445{
f7ab6a50 446 LOCATIONS_OPTION = CHAR_MAX + 1,
d4bd2295 447 PRINT_LOCALEDIR_OPTION,
1bb2bd75
JD
448 PRINT_DATADIR_OPTION,
449 REPORT_FILE_OPTION
d0829076
PE
450};
451
e2aaf4c4
AD
452static struct option const long_options[] =
453{
454 /* Operation modes. */
7b42569e
AD
455 { "help", no_argument, 0, 'h' },
456 { "version", no_argument, 0, 'V' },
457 { "print-localedir", no_argument, 0, PRINT_LOCALEDIR_OPTION },
d4bd2295 458 { "print-datadir", no_argument, 0, PRINT_DATADIR_OPTION },
7b42569e 459 { "warnings", optional_argument, 0, 'W' },
e2aaf4c4
AD
460
461 /* Parser. */
462 { "name-prefix", required_argument, 0, 'p' },
463 { "include", required_argument, 0, 'I' },
464
465 /* Output. */
466 { "file-prefix", required_argument, 0, 'b' },
467 { "output", required_argument, 0, 'o' },
468 { "output-file", required_argument, 0, 'o' },
469 { "graph", optional_argument, 0, 'g' },
41d7a5f2 470 { "xml", optional_argument, 0, 'x' },
e2aaf4c4 471 { "report", required_argument, 0, 'r' },
1bb2bd75 472 { "report-file", required_argument, 0, REPORT_FILE_OPTION },
e2aaf4c4
AD
473 { "verbose", no_argument, 0, 'v' },
474
475 /* Hidden. */
273a74fa 476 { "trace", optional_argument, 0, 'T' },
e2aaf4c4 477
e2aaf4c4
AD
478 /* Output. */
479 { "defines", optional_argument, 0, 'd' },
480
481 /* Operation modes. */
482 { "fixed-output-files", no_argument, 0, 'y' },
483 { "yacc", no_argument, 0, 'y' },
484
485 /* Parser. */
486 { "debug", no_argument, 0, 't' },
e14c6831 487 { "define", required_argument, 0, 'D' },
34d41938 488 { "force-define", required_argument, 0, 'F' },
d0829076 489 { "locations", no_argument, 0, LOCATIONS_OPTION },
e2aaf4c4 490 { "no-lines", no_argument, 0, 'l' },
e2aaf4c4
AD
491 { "raw", no_argument, 0, 0 },
492 { "skeleton", required_argument, 0, 'S' },
0e021770 493 { "language", required_argument, 0, 'L' },
e2aaf4c4
AD
494 { "token-table", no_argument, 0, 'k' },
495
496 {0, 0, 0, 0}
497};
498
ae404801
AD
499/* Under DOS, there is no difference on the case. This can be
500 troublesome when looking for `.tab' etc. */
501#ifdef MSDOS
502# define AS_FILE_NAME(File) (strlwr (File), (File))
503#else
504# define AS_FILE_NAME(File) (File)
505#endif
506
e14c6831
AD
507/* Build a location for the current command line argument. */
508static
509location
6f5be1ab 510command_line_location (void)
e14c6831
AD
511{
512 location res;
513 /* "<command line>" is used in GCC's messages about -D. */
514 boundary_set (&res.start, uniqstr_new ("<command line>"), optind, -1);
515 res.end = res.start;
516 return res;
517}
518
519
3d8fc6ca 520void
d2729d44 521getargs (int argc, char *argv[])
3d8fc6ca 522{
1916f98e 523 int c;
3d8fc6ca 524
08721544
PE
525 while ((c = getopt_long (argc, argv, short_options, long_options, NULL))
526 != -1)
cd5bd6ac
AD
527 switch (c)
528 {
e14c6831
AD
529 /* ASCII Sorting for short options (i.e., upper case then
530 lower case), and then long-only options. */
531
cd5bd6ac
AD
532 case 0:
533 /* Certain long options cause getopt_long to return 0. */
534 break;
535
e14c6831 536 case 'D': /* -DNAME[=VALUE]. */
34d41938 537 case 'F': /* -FNAME[=VALUE]. */
e14c6831
AD
538 {
539 char* name = optarg;
540 char* value = strchr (optarg, '=');
541 if (value)
c4eb1e84 542 *value++ = 0;
10fa0146 543 muscle_percent_define_insert (name, command_line_location (),
34d41938
JD
544 value ? value : "",
545 c == 'D' ? MUSCLE_PERCENT_DEFINE_D
546 : MUSCLE_PERCENT_DEFINE_F);
e14c6831 547 }
22c2cbc0
AD
548 break;
549
8e55b3aa
JD
550 case 'I':
551 include = AS_FILE_NAME (optarg);
41d7a5f2
PE
552 break;
553
0e021770 554 case 'L':
e186a284
AD
555 language_argmatch (optarg, command_line_prio,
556 command_line_location ());
0e021770
PE
557 break;
558
cd5bd6ac 559 case 'S':
e186a284
AD
560 skeleton_arg (AS_FILE_NAME (optarg), command_line_prio,
561 command_line_location ());
cd5bd6ac
AD
562 break;
563
8e55b3aa
JD
564 case 'T':
565 FLAGS_ARGMATCH (trace, optarg);
f6bd5427
MA
566 break;
567
8e55b3aa
JD
568 case 'V':
569 version ();
570 exit (EXIT_SUCCESS);
571
572 case 'W':
ae404801 573 if (optarg)
8e55b3aa
JD
574 FLAGS_ARGMATCH (warnings, optarg);
575 else
576 warnings_flag |= warnings_all;
577 break;
578
579 case 'b':
580 spec_file_prefix = AS_FILE_NAME (optarg);
581 break;
582
e14c6831
AD
583 case 'd':
584 /* Here, the -d and --defines options are differentiated. */
585 defines_flag = true;
586 if (optarg)
587 spec_defines_file = xstrdup (AS_FILE_NAME (optarg));
588 break;
589
8e55b3aa
JD
590 case 'g':
591 graph_flag = true;
592 if (optarg)
593 spec_graph_file = xstrdup (AS_FILE_NAME (optarg));
cd5bd6ac
AD
594 break;
595
8e55b3aa
JD
596 case 'h':
597 usage (EXIT_SUCCESS);
598
7b42569e
AD
599 case 'k':
600 token_table_flag = true;
601 break;
602
cd5bd6ac 603 case 'l':
d0829076
PE
604 no_lines_flag = true;
605 break;
606
7b42569e
AD
607 case 'o':
608 spec_outfile = AS_FILE_NAME (optarg);
cd5bd6ac
AD
609 break;
610
7b42569e
AD
611 case 'p':
612 spec_name_prefix = optarg;
613 break;
614
615 case 'r':
616 FLAGS_ARGMATCH (report, optarg);
617 break;
618
cd5bd6ac 619 case 't':
d0829076 620 debug_flag = true;
cd5bd6ac
AD
621 break;
622
7b42569e
AD
623 case 'v':
624 report_flag |= report_states;
cd5bd6ac
AD
625 break;
626
8e55b3aa
JD
627 case 'x':
628 xml_flag = true;
629 if (optarg)
630 spec_xml_file = xstrdup (AS_FILE_NAME (optarg));
cd5bd6ac
AD
631 break;
632
8e55b3aa
JD
633 case 'y':
634 yacc_flag = true;
ec3bc396
AD
635 break;
636
7b42569e
AD
637 case LOCATIONS_OPTION:
638 locations_flag = 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]);
75c21b61 667 MUSCLE_INSERT_C_STRING ("file_name", grammar_file);
3d8fc6ca 668}
812775a0
JD
669
670void
671tr (char *s, char from, char to)
672{
673 for (; *s; s++)
674 if (*s == from)
675 *s = to;
676}