]> git.saurik.com Git - bison.git/blame - src/getargs.c
(getargs) [MSDOS]: Don't assume optarg != NULL
[bison.git] / src / getargs.c
CommitLineData
08721544
PE
1/* Parse command line arguments for Bison.
2
a4b6efd4 3 Copyright (C) 1984, 1986, 1989, 1992, 2000, 2001, 2002
06b00abc 4 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
20 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21 02111-1307, USA. */
3d8fc6ca 22
3d8fc6ca 23#include "system.h"
d38a11a6
PE
24
25#include <argmatch.h>
26#include <error.h>
f47dbf6b
PE
27
28/* Hack to get <getopt.h> to declare getopt with a prototype. */
29#if lint && ! defined __GNU_LIBRARY__
30# define __GNU_LIBRARY__
31# define HACK_FOR___GNU_LIBRARY___PROTOTYPE 1
32#endif
33
d38a11a6
PE
34#include <getopt.h>
35
f47dbf6b
PE
36#ifdef HACK_FOR___GNU_LIBRARY___PROTOTYPE
37# undef __GNU_LIBRARY__
38# undef HACK_FOR___GNU_LIBRARY___PROTOTYPE
39#endif
40
b0ce6046 41#include "complain.h"
ec3bc396 42#include "files.h"
d38a11a6
PE
43#include "getargs.h"
44#include "uniqstr.h"
3d8fc6ca 45
89cab50d
AD
46int debug_flag = 0;
47int defines_flag = 0;
48int locations_flag = 0;
49int no_lines_flag = 0;
50int no_parser_flag = 0;
273a74fa 51int report_flag = report_none;
89cab50d 52int token_table_flag = 0;
89cab50d 53int yacc_flag = 0; /* for -y */
22c2cbc0 54int graph_flag = 0;
273a74fa 55int trace_flag = trace_none;
d2729d44 56
b0ce6046 57const char *skeleton = NULL;
f6bd5427 58const char *include = NULL;
b0ce6046 59
cbd8ffc5 60extern char *program_name;
3d8fc6ca 61
273a74fa
AD
62
63/*---------------------.
64| --trace's handling. |
65`---------------------*/
66
67static const char * const trace_args[] =
68{
69 /* In a series of synonyms, present the most meaningful first, so
70 that argmatch_valid be more readable. */
71 "none - no report",
c5e3e510
AD
72 "scan - grammar scanner traces",
73 "parse - grammar parser traces",
273a74fa
AD
74 "automaton - contruction of the automaton",
75 "bitsets - use of bitsets",
76 "grammar - reading, reducing of the grammar",
1509d42f 77 "resource - memory consumption (where available)",
273a74fa
AD
78 "sets - grammar sets: firsts, nullable etc.",
79 "tools - m4 invocation and preserve the temporary file",
c5e3e510
AD
80 "skeleton - skeleton postprocessing",
81 "time - time consumption",
273a74fa
AD
82 "all - all of the above",
83 0
84};
85
86static const int trace_types[] =
87{
88 trace_none,
473d0a75
AD
89 trace_scan,
90 trace_parse,
273a74fa
AD
91 trace_automaton,
92 trace_bitsets,
93 trace_grammar,
94 trace_resource,
95 trace_sets,
96 trace_tools,
c5e3e510
AD
97 trace_skeleton,
98 trace_time,
273a74fa
AD
99 trace_all
100};
101
102
103static void
104trace_argmatch (char *args)
105{
7223426a 106 verify (trace_constraint, ARGMATCH_CONSTRAINT (trace_args, trace_types));
273a74fa
AD
107 if (args)
108 {
109 args = strtok (args, ",");
110 do
111 {
112 int trace = XARGMATCH ("--trace", args,
113 trace_args, trace_types);
114 if (trace == trace_none)
115 trace_flag = trace_none;
116 else
117 trace_flag |= trace;
118 }
119 while ((args = strtok (NULL, ",")));
120 }
121 else
122 trace_flag = trace_all;
123}
124
125
ec3bc396
AD
126/*----------------------.
127| --report's handling. |
128`----------------------*/
129
130static const char * const report_args[] =
131{
132 /* In a series of synonyms, present the most meaningful first, so
133 that argmatch_valid be more readable. */
134 "none",
135 "state", "states",
136 "itemset", "itemsets",
137 "lookahead", "lookaheads",
b408954b 138 "solved",
ec3bc396
AD
139 "all",
140 0
141};
142
143static const int report_types[] =
144{
145 report_none,
146 report_states, report_states,
147 report_states | report_itemsets, report_states | report_itemsets,
148 report_states | report_lookaheads, report_states | report_lookaheads,
b408954b 149 report_states | report_solved_conflicts,
ec3bc396
AD
150 report_all
151};
152
153
154static void
155report_argmatch (char *args)
156{
7223426a 157 verify (report_constraint, ARGMATCH_CONSTRAINT (report_args, report_types));
9be0c25b 158 args = strtok (args, ",");
ec3bc396
AD
159 do
160 {
161 int report = XARGMATCH ("--report", args,
162 report_args, report_types);
163 if (report == report_none)
164 report_flag = report_none;
165 else
166 report_flag |= report;
167 }
168 while ((args = strtok (NULL, ",")));
169}
170
0e575721
AD
171
172/*-------------------------------------------.
173| Display the help message and exit STATUS. |
174`-------------------------------------------*/
e79137ac 175
0df27e8b
PE
176static void usage (int) ATTRIBUTE_NORETURN;
177
4a120d45 178static void
0e575721 179usage (int status)
cbd8ffc5 180{
0e575721
AD
181 if (status != 0)
182 fprintf (stderr, _("Try `%s --help' for more information.\n"),
183 program_name);
184 else
185 {
186 /* Some efforts were made to ease the translators' task, please
187 continue. */
188 fputs (_("\
189GNU bison generates parsers for LALR(1) grammars.\n"), stdout);
190 putc ('\n', stdout);
9f306f2a 191
0e575721 192 fprintf (stdout, _("\
9f306f2a 193Usage: %s [OPTION]... FILE\n"), program_name);
0e575721 194 putc ('\n', stdout);
9f306f2a 195
0e575721 196 fputs (_("\
9f306f2a
AD
197If a long option shows an argument as mandatory, then it is mandatory\n\
198for the equivalent short option also. Similarly for optional arguments.\n"),
0e575721
AD
199 stdout);
200 putc ('\n', stdout);
9f306f2a 201
0e575721 202 fputs (_("\
9f306f2a
AD
203Operation modes:\n\
204 -h, --help display this help and exit\n\
205 -V, --version output version information and exit\n\
0e575721
AD
206 -y, --yacc emulate POSIX yacc\n"), stdout);
207 putc ('\n', stdout);
9f306f2a 208
0e575721 209 fputs (_("\
9f306f2a 210Parser:\n\
cd5bd6ac 211 -S, --skeleton=FILE specify the skeleton to use\n\
9f306f2a 212 -t, --debug instrument the parser for debugging\n\
89cab50d 213 --locations enable locations computation\n\
9f306f2a
AD
214 -p, --name-prefix=PREFIX prepend PREFIX to the external symbols\n\
215 -l, --no-lines don't generate `#line' directives\n\
216 -n, --no-parser generate the tables only\n\
9f306f2a 217 -k, --token-table include a table of token names\n\
0e575721
AD
218"), stdout);
219 putc ('\n', stdout);
9f306f2a 220
0e575721 221 fputs (_("\
9f306f2a
AD
222Output:\n\
223 -d, --defines also produce a header file\n\
ec3bc396
AD
224 -r, --report=THINGS also produce details on the automaton\n\
225 -v, --verbose same as `--report=state'\n\
9f306f2a 226 -b, --file-prefix=PREFIX specify a PREFIX for output files\n\
951366c1
AD
227 -o, --output=FILE leave output to FILE\n\
228 -g, --graph also produce a VCG description of the automaton\n\
0e575721
AD
229"), stdout);
230 putc ('\n', stdout);
86eff183 231
0e575721 232 fputs (_("\
ec3bc396
AD
233THINGS is a list of comma separated words that can include:\n\
234 `state' describe the states\n\
235 `itemset' complete the core item sets with their closure\n\
236 `lookahead' explicitly associate lookaheads to items\n\
b408954b 237 `solved' describe shift/reduce conflicts solving\n\
ec3bc396
AD
238 `all' include all the above information\n\
239 `none' disable the report\n\
0e575721
AD
240"), stdout);
241 putc ('\n', stdout);
9f306f2a 242
0e575721
AD
243 fputs (_("\
244Report bugs to <bug-bison@gnu.org>.\n"), stdout);
245 }
246
247 exit (status);
cbd8ffc5
DM
248}
249
e79137ac
AD
250
251/*------------------------------.
252| Display the version message. |
253`------------------------------*/
254
255static void
0e575721 256version (void)
e79137ac
AD
257{
258 /* Some efforts were made to ease the translators' task, please
259 continue. */
0e575721
AD
260 printf (_("bison (GNU Bison) %s"), VERSION);
261 putc ('\n', stdout);
262 fputs (_("Written by Robert Corbett and Richard Stallman.\n"), stdout);
263 putc ('\n', stdout);
e79137ac 264
0e575721 265 fprintf (stdout,
06b00abc 266 _("Copyright (C) %d Free Software Foundation, Inc.\n"), 2002);
e79137ac
AD
267
268 fputs (_("\
269This is free software; see the source for copying conditions. There is NO\n\
270warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
271"),
0e575721 272 stdout);
e79137ac
AD
273}
274
275
276/*----------------------.
277| Process the options. |
278`----------------------*/
279
e2aaf4c4 280/* Shorts options. */
273a74fa 281const char *short_options = "yvegdhr:ltknVo:b:p:S:T::";
e2aaf4c4
AD
282
283static struct option const long_options[] =
284{
285 /* Operation modes. */
286 { "help", no_argument, 0, 'h' },
287 { "version", no_argument, 0, 'V' },
288
289 /* Parser. */
290 { "name-prefix", required_argument, 0, 'p' },
291 { "include", required_argument, 0, 'I' },
292
293 /* Output. */
294 { "file-prefix", required_argument, 0, 'b' },
295 { "output", required_argument, 0, 'o' },
296 { "output-file", required_argument, 0, 'o' },
297 { "graph", optional_argument, 0, 'g' },
298 { "report", required_argument, 0, 'r' },
299 { "verbose", no_argument, 0, 'v' },
300
301 /* Hidden. */
273a74fa 302 { "trace", optional_argument, 0, 'T' },
e2aaf4c4 303
e2aaf4c4
AD
304 /* Output. */
305 { "defines", optional_argument, 0, 'd' },
306
307 /* Operation modes. */
308 { "fixed-output-files", no_argument, 0, 'y' },
309 { "yacc", no_argument, 0, 'y' },
310
311 /* Parser. */
312 { "debug", no_argument, 0, 't' },
313 { "locations", no_argument, &locations_flag, 1 },
314 { "no-lines", no_argument, 0, 'l' },
315 { "no-parser", no_argument, 0, 'n' },
316 { "raw", no_argument, 0, 0 },
317 { "skeleton", required_argument, 0, 'S' },
318 { "token-table", no_argument, 0, 'k' },
319
320 {0, 0, 0, 0}
321};
322
ae404801
AD
323/* Under DOS, there is no difference on the case. This can be
324 troublesome when looking for `.tab' etc. */
325#ifdef MSDOS
326# define AS_FILE_NAME(File) (strlwr (File), (File))
327#else
328# define AS_FILE_NAME(File) (File)
329#endif
330
3d8fc6ca 331void
d2729d44 332getargs (int argc, char *argv[])
3d8fc6ca 333{
1916f98e 334 int c;
3d8fc6ca 335
08721544
PE
336 while ((c = getopt_long (argc, argv, short_options, long_options, NULL))
337 != -1)
cd5bd6ac
AD
338 switch (c)
339 {
340 case 0:
341 /* Certain long options cause getopt_long to return 0. */
342 break;
343
344 case 'y':
345 yacc_flag = 1;
346 break;
347
348 case 'h':
0df27e8b 349 usage (EXIT_SUCCESS);
cd5bd6ac
AD
350
351 case 'V':
0e575721 352 version ();
0df27e8b 353 exit (EXIT_SUCCESS);
cd5bd6ac 354
22c2cbc0 355 case 'g':
342b8b6e 356 /* Here, the -g and --graph=FILE options are differentiated. */
22c2cbc0 357 graph_flag = 1;
fcbfa6b0
PE
358 if (optarg)
359 spec_graph_file = AS_FILE_NAME (optarg);
22c2cbc0
AD
360 break;
361
cd5bd6ac 362 case 'v':
ec3bc396 363 report_flag |= report_states;
cd5bd6ac
AD
364 break;
365
366 case 'S':
ae404801 367 skeleton = AS_FILE_NAME (optarg);
cd5bd6ac
AD
368 break;
369
f6bd5427 370 case 'I':
ae404801 371 include = AS_FILE_NAME (optarg);
f6bd5427
MA
372 break;
373
cd5bd6ac 374 case 'd':
342b8b6e 375 /* Here, the -d and --defines options are differentiated. */
cd5bd6ac 376 defines_flag = 1;
ae404801
AD
377 if (optarg)
378 spec_defines_file = AS_FILE_NAME (optarg);
cd5bd6ac
AD
379 break;
380
381 case 'l':
382 no_lines_flag = 1;
383 break;
384
385 case 'k':
386 token_table_flag = 1;
387 break;
388
cd5bd6ac
AD
389 case 'n':
390 no_parser_flag = 1;
391 break;
392
393 case 't':
394 debug_flag = 1;
395 break;
396
397 case 'o':
ae404801 398 spec_outfile = AS_FILE_NAME (optarg);
cd5bd6ac
AD
399 break;
400
401 case 'b':
ae404801 402 spec_file_prefix = AS_FILE_NAME (optarg);
cd5bd6ac
AD
403 break;
404
405 case 'p':
406 spec_name_prefix = optarg;
407 break;
408
ec3bc396
AD
409 case 'r':
410 report_argmatch (optarg);
411 break;
412
273a74fa
AD
413 case 'T':
414 trace_argmatch (optarg);
415 break;
416
cd5bd6ac 417 default:
0df27e8b 418 usage (EXIT_FAILURE);
cd5bd6ac 419 }
3d8fc6ca 420
a4b6efd4 421 if (argc - optind != 1)
3d8fc6ca 422 {
a4b6efd4
PE
423 if (argc - optind < 1)
424 error (0, 0, _("missing operand after `%s'"), argv[argc - 1]);
425 else
426 error (0, 0, _("extra operand `%s'"), argv[optind + 1]);
0e575721 427 usage (EXIT_FAILURE);
3d8fc6ca 428 }
3d8fc6ca 429
d38a11a6 430 current_file = grammar_file = uniqstr_new (argv[optind]);
3d8fc6ca 431}