]> git.saurik.com Git - bison.git/blame - src/getargs.c
(print_core): Remove item set redundancy.
[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,
8405b70c 4 2005, 2006, 2007 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"
7891a7c4 23#include "revision.h"
d4bd2295 24#include "output.h"
d38a11a6
PE
25
26#include <argmatch.h>
d7e0a1a7 27#include <c-strcase.h>
3b2942e6 28#include <configmake.h>
d38a11a6 29#include <error.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
PE
46#include "getargs.h"
47#include "uniqstr.h"
3d8fc6ca 48
d0829076
PE
49bool debug_flag;
50bool defines_flag;
4e83ea15 51bool graph_flag;
41d7a5f2 52bool xml_flag;
d0829076
PE
53bool locations_flag;
54bool no_lines_flag;
d0829076
PE
55bool token_table_flag;
56bool yacc_flag; /* for -y */
4e83ea15
AD
57
58bool error_verbose = false;
d2729d44 59
916708d5
AD
60bool nondeterministic_parser = false;
61bool glr_parser = false;
62bool pure_parser = false;
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
75static int skeleton_prio = 2;
b0ce6046 76const char *skeleton = NULL;
0e021770
PE
77static int language_prio = 2;
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.",
327afc7c
AD
179 "tools - m4 invocation",
180 "m4 - m4 traces",
c5e3e510
AD
181 "skeleton - skeleton postprocessing",
182 "time - time consumption",
273a74fa
AD
183 "all - all of the above",
184 0
185};
186
187static const int trace_types[] =
188{
189 trace_none,
473d0a75
AD
190 trace_scan,
191 trace_parse,
273a74fa
AD
192 trace_automaton,
193 trace_bitsets,
194 trace_grammar,
195 trace_resource,
196 trace_sets,
197 trace_tools,
327afc7c 198 trace_m4,
c5e3e510
AD
199 trace_skeleton,
200 trace_time,
273a74fa
AD
201 trace_all
202};
203
8a6f72f3 204ARGMATCH_VERIFY (trace_args, trace_types);
273a74fa 205
7b42569e
AD
206
207/*------------------------.
208| --warnings's handling. |
209`------------------------*/
210
211static const char * const warnings_args[] =
273a74fa 212{
7b42569e
AD
213 /* In a series of synonyms, present the most meaningful first, so
214 that argmatch_valid be more readable. */
17bd8a73
JD
215 "none - no warnings",
216 "midrule-values - unset or unused midrule values",
217 "yacc - incompatibilities with POSIX YACC",
218 "all - all of the above",
219 "error - warnings are errors",
7b42569e
AD
220 0
221};
222
223static const int warnings_types[] =
224{
225 warnings_none,
17bd8a73 226 warnings_midrule_values,
7b42569e 227 warnings_yacc,
89eb3c76
JD
228 warnings_all,
229 warnings_error
7b42569e
AD
230};
231
232ARGMATCH_VERIFY (warnings_args, warnings_types);
273a74fa
AD
233
234
0e575721
AD
235/*-------------------------------------------.
236| Display the help message and exit STATUS. |
237`-------------------------------------------*/
e79137ac 238
0df27e8b
PE
239static void usage (int) ATTRIBUTE_NORETURN;
240
4a120d45 241static void
0e575721 242usage (int status)
cbd8ffc5 243{
0e575721
AD
244 if (status != 0)
245 fprintf (stderr, _("Try `%s --help' for more information.\n"),
246 program_name);
247 else
248 {
a92be413 249 printf (_("Usage: %s [OPTION]... FILE\n"), program_name);
0e575721 250 fputs (_("\
a92be413
PE
251Generate LALR(1) and GLR parsers.\n\
252\n\
253"), stdout);
9f306f2a 254
0e575721 255 fputs (_("\
a92be413
PE
256Mandatory arguments to long options are mandatory for short options too.\n\
257"), stdout);
9f306f2a 258
0e575721 259 fputs (_("\
a92be413 260\n\
9f306f2a 261Operation modes:\n\
f7ab6a50
PE
262 -h, --help display this help and exit\n\
263 -V, --version output version information and exit\n\
264 --print-localedir output directory containing locale-dependent data\n\
d4bd2295 265 --print-datadir output directory containing skeletons and XSLT\n\
a92be413
PE
266 -y, --yacc emulate POSIX Yacc\n\
267\n\
268"), stdout);
9f306f2a 269
0e575721 270 fputs (_("\
9f306f2a 271Parser:\n\
cd5bd6ac 272 -S, --skeleton=FILE specify the skeleton to use\n\
9f306f2a 273 -t, --debug instrument the parser for debugging\n\
89cab50d 274 --locations enable locations computation\n\
9f306f2a
AD
275 -p, --name-prefix=PREFIX prepend PREFIX to the external symbols\n\
276 -l, --no-lines don't generate `#line' directives\n\
9f306f2a 277 -k, --token-table include a table of token names\n\
a92be413 278\n\
0e575721 279"), stdout);
9f306f2a 280
0e575721 281 fputs (_("\
9f306f2a
AD
282Output:\n\
283 -d, --defines also produce a header file\n\
ec3bc396
AD
284 -r, --report=THINGS also produce details on the automaton\n\
285 -v, --verbose same as `--report=state'\n\
9f306f2a 286 -b, --file-prefix=PREFIX specify a PREFIX for output files\n\
951366c1 287 -o, --output=FILE leave output to FILE\n\
35fe0834 288 -g, --graph also output a graph of the automaton\n\
41d7a5f2 289 -x, --xml also output an xml of the automaton\n\
a92be413 290\n\
0e575721 291"), stdout);
86eff183 292
0e575721 293 fputs (_("\
ec3bc396
AD
294THINGS is a list of comma separated words that can include:\n\
295 `state' describe the states\n\
296 `itemset' complete the core item sets with their closure\n\
742e4900 297 `lookahead' explicitly associate lookahead tokens to items\n\
b408954b 298 `solved' describe shift/reduce conflicts solving\n\
ec3bc396
AD
299 `all' include all the above information\n\
300 `none' disable the report\n\
0e575721 301"), stdout);
9f306f2a 302
a92be413 303 printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
0e575721
AD
304 }
305
306 exit (status);
cbd8ffc5
DM
307}
308
e79137ac
AD
309
310/*------------------------------.
311| Display the version message. |
312`------------------------------*/
313
314static void
0e575721 315version (void)
e79137ac
AD
316{
317 /* Some efforts were made to ease the translators' task, please
318 continue. */
0e575721
AD
319 printf (_("bison (GNU Bison) %s"), VERSION);
320 putc ('\n', stdout);
7891a7c4 321 printf ("%s", revision);
0e575721
AD
322 fputs (_("Written by Robert Corbett and Richard Stallman.\n"), stdout);
323 putc ('\n', stdout);
e79137ac 324
0e575721 325 fprintf (stdout,
f506ad1c 326 _("Copyright (C) %d Free Software Foundation, Inc.\n"), 2007);
e79137ac
AD
327
328 fputs (_("\
329This is free software; see the source for copying conditions. There is NO\n\
330warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
331"),
0e575721 332 stdout);
e79137ac
AD
333}
334
335
0e021770
PE
336/*-------------------------------------.
337| --skeleton and --language handling. |
338`--------------------------------------*/
339
340void
341skeleton_arg (char const *arg, int prio, location const *loc)
342{
343 if (prio < skeleton_prio)
344 {
345 skeleton_prio = prio;
346 skeleton = arg;
347 }
348 else if (prio == skeleton_prio)
349 {
350 char const *msg =
351 _("multiple skeleton declarations are invalid");
352 if (loc)
353 complain_at (*loc, msg);
354 else
355 complain (msg);
356 }
357}
358
359void
360language_argmatch (char const *arg, int prio, location const *loc)
361{
362 char const *msg;
363
364 if (prio < language_prio)
365 {
366 int i;
367 for (i = 0; valid_languages[i].language[0]; i++)
d7e0a1a7 368 if (c_strcasecmp (arg, valid_languages[i].language) == 0)
0e021770
PE
369 {
370 language_prio = prio;
371 language = &valid_languages[i];
372 return;
373 }
374 msg = _("invalid language `%s'");
375 }
376 else if (language_prio == prio)
377 msg = _("multiple language declarations are invalid");
378 else
379 return;
380
381 if (loc)
382 complain_at (*loc, msg, arg);
383 else
384 complain (msg, arg);
385}
386
e79137ac
AD
387/*----------------------.
388| Process the options. |
389`----------------------*/
390
e2aaf4c4 391/* Shorts options. */
41d7a5f2 392static char const short_options[] = "yvegxdhr:L:ltknVo:b:p:S:T::W";
e2aaf4c4 393
d0829076
PE
394/* Values for long options that do not have single-letter equivalents. */
395enum
396{
f7ab6a50 397 LOCATIONS_OPTION = CHAR_MAX + 1,
d4bd2295
JD
398 PRINT_LOCALEDIR_OPTION,
399 PRINT_DATADIR_OPTION
d0829076
PE
400};
401
e2aaf4c4
AD
402static struct option const long_options[] =
403{
404 /* Operation modes. */
7b42569e
AD
405 { "help", no_argument, 0, 'h' },
406 { "version", no_argument, 0, 'V' },
407 { "print-localedir", no_argument, 0, PRINT_LOCALEDIR_OPTION },
d4bd2295 408 { "print-datadir", no_argument, 0, PRINT_DATADIR_OPTION },
7b42569e 409 { "warnings", optional_argument, 0, 'W' },
e2aaf4c4
AD
410
411 /* Parser. */
412 { "name-prefix", required_argument, 0, 'p' },
413 { "include", required_argument, 0, 'I' },
414
415 /* Output. */
416 { "file-prefix", required_argument, 0, 'b' },
417 { "output", required_argument, 0, 'o' },
418 { "output-file", required_argument, 0, 'o' },
419 { "graph", optional_argument, 0, 'g' },
41d7a5f2 420 { "xml", optional_argument, 0, 'x' },
e2aaf4c4
AD
421 { "report", required_argument, 0, 'r' },
422 { "verbose", no_argument, 0, 'v' },
423
424 /* Hidden. */
273a74fa 425 { "trace", optional_argument, 0, 'T' },
e2aaf4c4 426
e2aaf4c4
AD
427 /* Output. */
428 { "defines", optional_argument, 0, 'd' },
429
430 /* Operation modes. */
431 { "fixed-output-files", no_argument, 0, 'y' },
432 { "yacc", no_argument, 0, 'y' },
433
434 /* Parser. */
435 { "debug", no_argument, 0, 't' },
d0829076 436 { "locations", no_argument, 0, LOCATIONS_OPTION },
e2aaf4c4 437 { "no-lines", no_argument, 0, 'l' },
e2aaf4c4
AD
438 { "raw", no_argument, 0, 0 },
439 { "skeleton", required_argument, 0, 'S' },
0e021770 440 { "language", required_argument, 0, 'L' },
e2aaf4c4
AD
441 { "token-table", no_argument, 0, 'k' },
442
443 {0, 0, 0, 0}
444};
445
ae404801
AD
446/* Under DOS, there is no difference on the case. This can be
447 troublesome when looking for `.tab' etc. */
448#ifdef MSDOS
449# define AS_FILE_NAME(File) (strlwr (File), (File))
450#else
451# define AS_FILE_NAME(File) (File)
452#endif
453
3d8fc6ca 454void
d2729d44 455getargs (int argc, char *argv[])
3d8fc6ca 456{
1916f98e 457 int c;
3d8fc6ca 458
08721544
PE
459 while ((c = getopt_long (argc, argv, short_options, long_options, NULL))
460 != -1)
cd5bd6ac
AD
461 switch (c)
462 {
463 case 0:
464 /* Certain long options cause getopt_long to return 0. */
465 break;
466
7b42569e
AD
467 case 'b':
468 spec_file_prefix = AS_FILE_NAME (optarg);
cd5bd6ac
AD
469 break;
470
22c2cbc0 471 case 'g':
342b8b6e 472 /* Here, the -g and --graph=FILE options are differentiated. */
d0829076 473 graph_flag = true;
fcbfa6b0 474 if (optarg)
eb095650 475 spec_graph_file = xstrdup (AS_FILE_NAME (optarg));
22c2cbc0
AD
476 break;
477
41d7a5f2
PE
478 case 'x':
479 /* Here, the -x and --xml=FILE options are differentiated. */
480 xml_flag = true;
481 if (optarg)
482 spec_xml_file = xstrdup (AS_FILE_NAME (optarg));
483 break;
484
7b42569e
AD
485 case 'h':
486 usage (EXIT_SUCCESS);
cd5bd6ac 487
0e021770
PE
488 case 'L':
489 language_argmatch (optarg, 0, NULL);
490 break;
491
cd5bd6ac 492 case 'S':
0e021770 493 skeleton_arg (AS_FILE_NAME (optarg), 0, NULL);
cd5bd6ac
AD
494 break;
495
f6bd5427 496 case 'I':
ae404801 497 include = AS_FILE_NAME (optarg);
f6bd5427
MA
498 break;
499
cd5bd6ac 500 case 'd':
342b8b6e 501 /* Here, the -d and --defines options are differentiated. */
d0829076 502 defines_flag = true;
ae404801 503 if (optarg)
eb095650 504 spec_defines_file = xstrdup (AS_FILE_NAME (optarg));
cd5bd6ac
AD
505 break;
506
7b42569e
AD
507 case 'k':
508 token_table_flag = true;
509 break;
510
cd5bd6ac 511 case 'l':
d0829076
PE
512 no_lines_flag = true;
513 break;
514
7b42569e
AD
515 case 'o':
516 spec_outfile = AS_FILE_NAME (optarg);
cd5bd6ac
AD
517 break;
518
7b42569e
AD
519 case 'p':
520 spec_name_prefix = optarg;
521 break;
522
523 case 'r':
524 FLAGS_ARGMATCH (report, optarg);
525 break;
526
527 case 'T':
528 FLAGS_ARGMATCH (trace, optarg);
cd5bd6ac
AD
529 break;
530
531 case 't':
d0829076 532 debug_flag = true;
cd5bd6ac
AD
533 break;
534
7b42569e
AD
535 case 'V':
536 version ();
537 exit (EXIT_SUCCESS);
cd5bd6ac 538
7b42569e
AD
539 case 'v':
540 report_flag |= report_states;
cd5bd6ac
AD
541 break;
542
7b42569e
AD
543 case 'y':
544 yacc_flag = true;
cd5bd6ac
AD
545 break;
546
7b42569e 547 case 'W':
89eb3c76
JD
548 if (optarg)
549 FLAGS_ARGMATCH (warnings, optarg);
550 else
551 warnings_flag |= warnings_all;
ec3bc396
AD
552 break;
553
7b42569e
AD
554 case LOCATIONS_OPTION:
555 locations_flag = true;
273a74fa
AD
556 break;
557
7b42569e
AD
558 case PRINT_LOCALEDIR_OPTION:
559 printf ("%s\n", LOCALEDIR);
560 exit (EXIT_SUCCESS);
561
d4bd2295
JD
562 case PRINT_DATADIR_OPTION:
563 printf ("%s\n", compute_pkgdatadir ());
564 exit (EXIT_SUCCESS);
565
cd5bd6ac 566 default:
0df27e8b 567 usage (EXIT_FAILURE);
cd5bd6ac 568 }
3d8fc6ca 569
a4b6efd4 570 if (argc - optind != 1)
3d8fc6ca 571 {
a4b6efd4
PE
572 if (argc - optind < 1)
573 error (0, 0, _("missing operand after `%s'"), argv[argc - 1]);
574 else
575 error (0, 0, _("extra operand `%s'"), argv[optind + 1]);
0e575721 576 usage (EXIT_FAILURE);
3d8fc6ca 577 }
3d8fc6ca 578
d38a11a6 579 current_file = grammar_file = uniqstr_new (argv[optind]);
3d8fc6ca 580}