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