]> git.saurik.com Git - bison.git/blame - src/getargs.c
* GNUmakefile: Switch to coreutils's version.
[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"
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;
d0829076
PE
51bool locations_flag;
52bool no_lines_flag;
d0829076
PE
53bool token_table_flag;
54bool yacc_flag; /* for -y */
4e83ea15
AD
55
56bool error_verbose = false;
d2729d44 57
916708d5
AD
58bool nondeterministic_parser = false;
59bool glr_parser = false;
7172e23e 60bool pull_parser = true;
916708d5 61bool pure_parser = false;
31c10e38 62bool push_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
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\
a92be413
PE
265 -y, --yacc emulate POSIX Yacc\n\
266\n\
267"), stdout);
9f306f2a 268
0e575721 269 fputs (_("\
9f306f2a 270Parser:\n\
cd5bd6ac 271 -S, --skeleton=FILE specify the skeleton to use\n\
9f306f2a 272 -t, --debug instrument the parser for debugging\n\
89cab50d 273 --locations enable locations computation\n\
9f306f2a
AD
274 -p, --name-prefix=PREFIX prepend PREFIX to the external symbols\n\
275 -l, --no-lines don't generate `#line' directives\n\
9f306f2a 276 -k, --token-table include a table of token names\n\
a92be413 277\n\
0e575721 278"), stdout);
9f306f2a 279
0e575721 280 fputs (_("\
9f306f2a
AD
281Output:\n\
282 -d, --defines also produce a header file\n\
ec3bc396
AD
283 -r, --report=THINGS also produce details on the automaton\n\
284 -v, --verbose same as `--report=state'\n\
9f306f2a 285 -b, --file-prefix=PREFIX specify a PREFIX for output files\n\
951366c1 286 -o, --output=FILE leave output to FILE\n\
35fe0834 287 -g, --graph also output a graph of the automaton\n\
a92be413 288\n\
0e575721 289"), stdout);
86eff183 290
0e575721 291 fputs (_("\
ec3bc396
AD
292THINGS is a list of comma separated words that can include:\n\
293 `state' describe the states\n\
294 `itemset' complete the core item sets with their closure\n\
742e4900 295 `lookahead' explicitly associate lookahead tokens to items\n\
b408954b 296 `solved' describe shift/reduce conflicts solving\n\
ec3bc396
AD
297 `all' include all the above information\n\
298 `none' disable the report\n\
0e575721 299"), stdout);
9f306f2a 300
a92be413 301 printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
0e575721
AD
302 }
303
304 exit (status);
cbd8ffc5
DM
305}
306
e79137ac
AD
307
308/*------------------------------.
309| Display the version message. |
310`------------------------------*/
311
312static void
0e575721 313version (void)
e79137ac
AD
314{
315 /* Some efforts were made to ease the translators' task, please
316 continue. */
0e575721
AD
317 printf (_("bison (GNU Bison) %s"), VERSION);
318 putc ('\n', stdout);
7891a7c4 319 printf ("%s", revision);
0e575721
AD
320 fputs (_("Written by Robert Corbett and Richard Stallman.\n"), stdout);
321 putc ('\n', stdout);
e79137ac 322
0e575721 323 fprintf (stdout,
e2a21b6f 324 _("Copyright (C) %d Free Software Foundation, Inc.\n"), 2006);
e79137ac
AD
325
326 fputs (_("\
327This is free software; see the source for copying conditions. There is NO\n\
328warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
329"),
0e575721 330 stdout);
e79137ac
AD
331}
332
333
0e021770
PE
334/*-------------------------------------.
335| --skeleton and --language handling. |
336`--------------------------------------*/
337
338void
339skeleton_arg (char const *arg, int prio, location const *loc)
340{
341 if (prio < skeleton_prio)
342 {
343 skeleton_prio = prio;
344 skeleton = arg;
345 }
346 else if (prio == skeleton_prio)
347 {
348 char const *msg =
349 _("multiple skeleton declarations are invalid");
350 if (loc)
351 complain_at (*loc, msg);
352 else
353 complain (msg);
354 }
355}
356
357void
358language_argmatch (char const *arg, int prio, location const *loc)
359{
360 char const *msg;
361
362 if (prio < language_prio)
363 {
364 int i;
365 for (i = 0; valid_languages[i].language[0]; i++)
d7e0a1a7 366 if (c_strcasecmp (arg, valid_languages[i].language) == 0)
0e021770
PE
367 {
368 language_prio = prio;
369 language = &valid_languages[i];
370 return;
371 }
372 msg = _("invalid language `%s'");
373 }
374 else if (language_prio == prio)
375 msg = _("multiple language declarations are invalid");
376 else
377 return;
378
379 if (loc)
380 complain_at (*loc, msg, arg);
381 else
382 complain (msg, arg);
383}
384
e79137ac
AD
385/*----------------------.
386| Process the options. |
387`----------------------*/
388
e2aaf4c4 389/* Shorts options. */
0e021770 390static char const short_options[] = "yvegdhr:L:ltknVo:b:p:S:T::W";
e2aaf4c4 391
d0829076
PE
392/* Values for long options that do not have single-letter equivalents. */
393enum
394{
f7ab6a50
PE
395 LOCATIONS_OPTION = CHAR_MAX + 1,
396 PRINT_LOCALEDIR_OPTION
d0829076
PE
397};
398
e2aaf4c4
AD
399static struct option const long_options[] =
400{
401 /* Operation modes. */
7b42569e
AD
402 { "help", no_argument, 0, 'h' },
403 { "version", no_argument, 0, 'V' },
404 { "print-localedir", no_argument, 0, PRINT_LOCALEDIR_OPTION },
405 { "warnings", optional_argument, 0, 'W' },
e2aaf4c4
AD
406
407 /* Parser. */
408 { "name-prefix", required_argument, 0, 'p' },
409 { "include", required_argument, 0, 'I' },
410
411 /* Output. */
412 { "file-prefix", required_argument, 0, 'b' },
413 { "output", required_argument, 0, 'o' },
414 { "output-file", required_argument, 0, 'o' },
415 { "graph", optional_argument, 0, 'g' },
416 { "report", required_argument, 0, 'r' },
417 { "verbose", no_argument, 0, 'v' },
418
419 /* Hidden. */
273a74fa 420 { "trace", optional_argument, 0, 'T' },
e2aaf4c4 421
e2aaf4c4
AD
422 /* Output. */
423 { "defines", optional_argument, 0, 'd' },
424
425 /* Operation modes. */
426 { "fixed-output-files", no_argument, 0, 'y' },
427 { "yacc", no_argument, 0, 'y' },
428
429 /* Parser. */
430 { "debug", no_argument, 0, 't' },
d0829076 431 { "locations", no_argument, 0, LOCATIONS_OPTION },
e2aaf4c4 432 { "no-lines", no_argument, 0, 'l' },
e2aaf4c4
AD
433 { "raw", no_argument, 0, 0 },
434 { "skeleton", required_argument, 0, 'S' },
0e021770 435 { "language", required_argument, 0, 'L' },
e2aaf4c4
AD
436 { "token-table", no_argument, 0, 'k' },
437
438 {0, 0, 0, 0}
439};
440
ae404801
AD
441/* Under DOS, there is no difference on the case. This can be
442 troublesome when looking for `.tab' etc. */
443#ifdef MSDOS
444# define AS_FILE_NAME(File) (strlwr (File), (File))
445#else
446# define AS_FILE_NAME(File) (File)
447#endif
448
3d8fc6ca 449void
d2729d44 450getargs (int argc, char *argv[])
3d8fc6ca 451{
1916f98e 452 int c;
3d8fc6ca 453
08721544
PE
454 while ((c = getopt_long (argc, argv, short_options, long_options, NULL))
455 != -1)
cd5bd6ac
AD
456 switch (c)
457 {
458 case 0:
459 /* Certain long options cause getopt_long to return 0. */
460 break;
461
7b42569e
AD
462 case 'b':
463 spec_file_prefix = AS_FILE_NAME (optarg);
cd5bd6ac
AD
464 break;
465
22c2cbc0 466 case 'g':
342b8b6e 467 /* Here, the -g and --graph=FILE options are differentiated. */
d0829076 468 graph_flag = true;
fcbfa6b0 469 if (optarg)
eb095650 470 spec_graph_file = xstrdup (AS_FILE_NAME (optarg));
22c2cbc0
AD
471 break;
472
7b42569e
AD
473 case 'h':
474 usage (EXIT_SUCCESS);
cd5bd6ac 475
0e021770
PE
476 case 'L':
477 language_argmatch (optarg, 0, NULL);
478 break;
479
cd5bd6ac 480 case 'S':
0e021770 481 skeleton_arg (AS_FILE_NAME (optarg), 0, NULL);
cd5bd6ac
AD
482 break;
483
f6bd5427 484 case 'I':
ae404801 485 include = AS_FILE_NAME (optarg);
f6bd5427
MA
486 break;
487
cd5bd6ac 488 case 'd':
342b8b6e 489 /* Here, the -d and --defines options are differentiated. */
d0829076 490 defines_flag = true;
ae404801 491 if (optarg)
eb095650 492 spec_defines_file = xstrdup (AS_FILE_NAME (optarg));
cd5bd6ac
AD
493 break;
494
7b42569e
AD
495 case 'k':
496 token_table_flag = true;
497 break;
498
cd5bd6ac 499 case 'l':
d0829076
PE
500 no_lines_flag = true;
501 break;
502
7b42569e
AD
503 case 'o':
504 spec_outfile = AS_FILE_NAME (optarg);
cd5bd6ac
AD
505 break;
506
7b42569e
AD
507 case 'p':
508 spec_name_prefix = optarg;
509 break;
510
511 case 'r':
512 FLAGS_ARGMATCH (report, optarg);
513 break;
514
515 case 'T':
516 FLAGS_ARGMATCH (trace, optarg);
cd5bd6ac
AD
517 break;
518
519 case 't':
d0829076 520 debug_flag = true;
cd5bd6ac
AD
521 break;
522
7b42569e
AD
523 case 'V':
524 version ();
525 exit (EXIT_SUCCESS);
cd5bd6ac 526
7b42569e
AD
527 case 'v':
528 report_flag |= report_states;
cd5bd6ac
AD
529 break;
530
7b42569e
AD
531 case 'y':
532 yacc_flag = true;
cd5bd6ac
AD
533 break;
534
7b42569e 535 case 'W':
89eb3c76
JD
536 if (optarg)
537 FLAGS_ARGMATCH (warnings, optarg);
538 else
539 warnings_flag |= warnings_all;
ec3bc396
AD
540 break;
541
7b42569e
AD
542 case LOCATIONS_OPTION:
543 locations_flag = true;
273a74fa
AD
544 break;
545
7b42569e
AD
546 case PRINT_LOCALEDIR_OPTION:
547 printf ("%s\n", LOCALEDIR);
548 exit (EXIT_SUCCESS);
549
cd5bd6ac 550 default:
0df27e8b 551 usage (EXIT_FAILURE);
cd5bd6ac 552 }
3d8fc6ca 553
a4b6efd4 554 if (argc - optind != 1)
3d8fc6ca 555 {
a4b6efd4
PE
556 if (argc - optind < 1)
557 error (0, 0, _("missing operand after `%s'"), argv[argc - 1]);
558 else
559 error (0, 0, _("extra operand `%s'"), argv[optind + 1]);
0e575721 560 usage (EXIT_FAILURE);
3d8fc6ca 561 }
3d8fc6ca 562
d38a11a6 563 current_file = grammar_file = uniqstr_new (argv[optind]);
3d8fc6ca 564}