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