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