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