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