]> git.saurik.com Git - bison.git/blame - src/getargs.c
diagnostics: revamp the handling of -Werror
[bison.git] / src / getargs.c
CommitLineData
08721544
PE
1/* Parse command line arguments for Bison.
2
7d6bad19 3 Copyright (C) 1984, 1986, 1989, 1992, 2000-2013 Free Software
575619af 4 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"
d4bd2295 23#include "output.h"
d38a11a6
PE
24
25#include <argmatch.h>
d7e0a1a7 26#include <c-strcase.h>
3b2942e6 27#include <configmake.h>
d38a11a6
PE
28#include <error.h>
29#include <getopt.h>
4d699f44
AD
30#include <progname.h>
31
b0ce6046 32#include "complain.h"
ec3bc396 33#include "files.h"
d38a11a6 34#include "getargs.h"
00f5d575 35#include "muscle-tab.h"
4a9cd8f2 36#include "quote.h"
d38a11a6 37#include "uniqstr.h"
3d8fc6ca 38
d0829076 39bool defines_flag;
4e83ea15 40bool graph_flag;
41d7a5f2 41bool xml_flag;
d0829076 42bool no_lines_flag;
d0829076 43bool token_table_flag;
e9690142 44bool yacc_flag; /* for -y */
4e83ea15 45
916708d5
AD
46bool nondeterministic_parser = false;
47bool glr_parser = false;
916708d5 48
9c4788b7 49int feature_flag = feature_caret;
4e83ea15
AD
50int report_flag = report_none;
51int trace_flag = trace_none;
52
0e021770
PE
53static struct bison_language const valid_languages[] = {
54 { "c", "c-skel.m4", ".c", ".h", true },
55 { "c++", "c++-skel.m4", ".cc", ".hh", true },
8405b70c 56 { "java", "java-skel.m4", ".java", ".java", false },
0e021770
PE
57 { "", "", "", "", false }
58};
59
51365192 60int skeleton_prio = default_prio;
b0ce6046 61const char *skeleton = NULL;
51365192 62int language_prio = default_prio;
0e021770 63struct bison_language const *language = &valid_languages[0];
f6bd5427 64const char *include = NULL;
b0ce6046 65
20964c33 66/** Decode an option's key.
7b42569e
AD
67 *
68 * \param option option being decoded.
07c39ae9 69 * \param keys array of valid subarguments.
7b42569e 70 * \param values array of corresponding (int) values.
bf0e44e8 71 * \param all the all value.
07c39ae9 72 * \param flags the flags to update
20964c33
TR
73 * \param arg the subarguments to decode.
74 * If null, then activate all the flags.
75 * \param no length of the potential "no-" prefix.
76 * Can be 0 or 3. If 3, negate the action of the subargument.
7b42569e 77 *
4182a0a1 78 * If VALUE != 0 then KEY sets flags and no-KEY clears them.
bf0e44e8
JD
79 * If VALUE == 0 then KEY clears all flags from \c all and no-KEY sets all
80 * flags from \c all. Thus no-none = all and no-all = none.
7b42569e 81 */
80ac75bc 82static void
20964c33
TR
83flag_argmatch (const char *option,
84 const char * const keys[], const int values[],
c017f88f 85 int all, int *flags, char *arg, size_t no)
7b42569e 86{
20964c33 87 int value = 0;
c017f88f 88 value = XARGMATCH (option, arg + no, keys, values);
20964c33
TR
89
90 if (value)
7b42569e 91 {
20964c33
TR
92 if (no)
93 *flags &= ~value;
94 else
c017f88f 95 *flags |= value;
7b42569e 96 }
20964c33
TR
97 else
98 {
c017f88f 99 if (no)
20964c33
TR
100 *flags |= all;
101 else
102 *flags &= ~all;
103 }
104}
c017f88f 105
20964c33
TR
106/** Decode an option's set of keys.
107 *
108 * \param option option being decoded.
109 * \param keys array of valid subarguments.
110 * \param values array of corresponding (int) values.
111 * \param all the all value.
112 * \param flags the flags to update
113 * \param args comma separated list of effective subarguments to decode.
114 * If 0, then activate all the flags.
115 */
116static void
117flags_argmatch (const char *option,
118 const char * const keys[], const int values[],
119 int all, int *flags, char *args)
120{
121 if (args)
122 for (args = strtok (args, ","); args; args = strtok (NULL, ","))
123 {
124 size_t no = STRPREFIX_LIT ("no-", args) ? 3 : 0;
20964c33 125 flag_argmatch (option, keys,
c017f88f 126 values, all, flags, args, no);
20964c33 127 }
0d43e605
AD
128 else
129 *flags |= all;
7b42569e
AD
130}
131
c017f88f 132
80ac75bc 133/** Decode a set of sub arguments.
7b42569e
AD
134 *
135 * \param FlagName the flag familly to update.
07c39ae9 136 * \param Args the effective sub arguments to decode.
327db05b 137 * \param All the "all" value.
7b42569e
AD
138 *
139 * \arg FlagName_args the list of keys.
140 * \arg FlagName_types the list of values.
141 * \arg FlagName_flag the flag to update.
142 */
327db05b 143#define FLAGS_ARGMATCH(FlagName, Args, All) \
7b42569e 144 flags_argmatch ("--" #FlagName, FlagName ## _args, FlagName ## _types, \
327db05b 145 All, &FlagName ## _flag, Args)
7b42569e
AD
146
147
b8a41559
AD
148/*----------------------.
149| --report's handling. |
150`----------------------*/
151
152static const char * const report_args[] =
153{
154 /* In a series of synonyms, present the most meaningful first, so
155 that argmatch_valid be more readable. */
156 "none",
157 "state", "states",
158 "itemset", "itemsets",
159 "lookahead", "lookaheads", "look-ahead",
160 "solved",
161 "all",
162 0
163};
164
165static const int report_types[] =
166{
167 report_none,
168 report_states, report_states,
169 report_states | report_itemsets, report_states | report_itemsets,
170 report_states | report_lookahead_tokens,
171 report_states | report_lookahead_tokens,
172 report_states | report_lookahead_tokens,
173 report_states | report_solved_conflicts,
174 report_all
175};
176
177ARGMATCH_VERIFY (report_args, report_types);
178
b8a41559 179
273a74fa
AD
180/*---------------------.
181| --trace's handling. |
182`---------------------*/
183
184static const char * const trace_args[] =
185{
b8a41559 186 "none - no traces",
c5e3e510
AD
187 "scan - grammar scanner traces",
188 "parse - grammar parser traces",
b8a41559 189 "automaton - construction of the automaton",
273a74fa 190 "bitsets - use of bitsets",
b8a41559 191 "grammar - reading, reducing the grammar",
1509d42f 192 "resource - memory consumption (where available)",
273a74fa 193 "sets - grammar sets: firsts, nullable etc.",
5263bea9 194 "muscles - m4 definitions passed to the skeleton",
327afc7c
AD
195 "tools - m4 invocation",
196 "m4 - m4 traces",
c5e3e510
AD
197 "skeleton - skeleton postprocessing",
198 "time - time consumption",
db34f798 199 "ielr - IELR conversion",
273a74fa
AD
200 "all - all of the above",
201 0
202};
203
204static const int trace_types[] =
205{
206 trace_none,
473d0a75
AD
207 trace_scan,
208 trace_parse,
273a74fa
AD
209 trace_automaton,
210 trace_bitsets,
211 trace_grammar,
212 trace_resource,
213 trace_sets,
5263bea9 214 trace_muscles,
273a74fa 215 trace_tools,
327afc7c 216 trace_m4,
c5e3e510
AD
217 trace_skeleton,
218 trace_time,
db34f798 219 trace_ielr,
273a74fa
AD
220 trace_all
221};
222
8a6f72f3 223ARGMATCH_VERIFY (trace_args, trace_types);
273a74fa 224
7b42569e
AD
225
226/*------------------------.
227| --warnings's handling. |
228`------------------------*/
229
c017f88f
AD
230/** Decode a single argument from -W.
231 *
c017f88f
AD
232 * \param arg the subarguments to decode.
233 * If null, then activate all the flags.
234 * \param no length of the potential "no-" prefix.
235 * Can be 0 or 3. If 3, negate the action of the subargument.
236 * \param err length of a potential "error=".
808e523d 237 * Can be 0 or 6. If 6, treat the subargument as a CATEGORY.
c017f88f
AD
238 *
239 * If VALUE != 0 then KEY sets flags and no-KEY clears them.
240 * If VALUE == 0 then KEY clears all flags from \c all and no-KEY sets all
241 * flags from \c all. Thus no-none = all and no-all = none.
242 */
243static void
808e523d 244warning_argmatch (char const *arg, size_t no, size_t err)
c017f88f 245{
808e523d
AD
246 int value = XARGMATCH ("--warning", arg + no + err,
247 warnings_args, warnings_types);
c017f88f 248
808e523d
AD
249 /* -Wnone == -Wno-all, and -Wno-none == -Wall. */
250 if (!value)
c017f88f 251 {
808e523d
AD
252 value = Wall;
253 no = !no;
254 }
255
256 if (no)
257 {
258 size_t b;
259 for (b = 0; b < warnings_size; ++b)
260 if (value & 1 << b)
261 {
262 if (err)
263 {
264 /* -Wno-error=foo: if foo enabled as an error,
265 make it a warning. */
266 if (warnings_flag[b] == severity_error)
267 warnings_flag[b] = severity_warning;
268 }
269 else
270 /* -Wno-foo. */
271 warnings_flag[b] = severity_disabled;
272 }
c017f88f
AD
273 }
274 else
275 {
808e523d
AD
276 size_t b;
277 for (b = 0; b < warnings_size; ++b)
278 if (value & 1 << b)
279 /* -Wfoo and -Werror=foo. */
280 warnings_flag[b] = err ? severity_error : severity_warning;
c017f88f
AD
281 }
282}
283
284/** Decode a comma-separated list of arguments from -W.
285 *
c017f88f
AD
286 * \param args comma separated list of effective subarguments to decode.
287 * If 0, then activate all the flags.
288 */
289static void
4a3c55cf 290warnings_argmatch (char *args)
c017f88f
AD
291{
292 if (args)
293 for (args = strtok (args, ","); args; args = strtok (NULL, ","))
808e523d
AD
294 if (STREQ (args, "error"))
295 warnings_are_errors = true;
296 else if (STREQ (args, "no-error"))
297 {
298 warnings_are_errors = false;
299 warning_argmatch ("no-error=all", 3, 6);
300 }
301 else
302 {
303 size_t no = STRPREFIX_LIT ("no-", args) ? 3 : 0;
304 size_t err = STRPREFIX_LIT ("error=", args + no) ? 6 : 0;
c017f88f 305
808e523d
AD
306 warning_argmatch (args, no, err);
307 }
c017f88f 308 else
808e523d 309 warning_argmatch ("all", 0, 0);
c017f88f
AD
310}
311
219458e2 312const char * const warnings_args[] =
273a74fa 313{
9a9130f2
AD
314 "none",
315 "midrule-values",
316 "yacc",
317 "conflicts-sr",
318 "conflicts-rr",
319 "deprecated",
320 "precedence",
321 "other",
322 "all",
323 "error",
7b42569e
AD
324 0
325};
326
219458e2 327const int warnings_types[] =
7b42569e 328{
327db05b
VS
329 Wnone,
330 Wmidrule_values,
331 Wyacc,
332 Wconflicts_sr,
333 Wconflicts_rr,
518e8830 334 Wdeprecated,
cc2235ac 335 Wprecedence,
327db05b
VS
336 Wother,
337 Wall,
338 Werror
7b42569e
AD
339};
340
341ARGMATCH_VERIFY (warnings_args, warnings_types);
273a74fa 342
0db26489
TR
343/*-----------------------.
344| --feature's handling. |
345`-----------------------*/
346
347static const char * const feature_args[] =
348{
349 "none",
350 "caret", "diagnostics-show-caret",
351 "all",
352 0
353};
354
355static const int feature_types[] =
356{
357 feature_none,
358 feature_caret, feature_caret,
359 feature_all
360};
361
362ARGMATCH_VERIFY (feature_args, feature_types);
273a74fa 363
0e575721
AD
364/*-------------------------------------------.
365| Display the help message and exit STATUS. |
366`-------------------------------------------*/
e79137ac 367
0df27e8b
PE
368static void usage (int) ATTRIBUTE_NORETURN;
369
4a120d45 370static void
0e575721 371usage (int status)
cbd8ffc5 372{
0e575721
AD
373 if (status != 0)
374 fprintf (stderr, _("Try `%s --help' for more information.\n"),
e9690142 375 program_name);
0e575721
AD
376 else
377 {
a7c09cba 378 /* For ../build-aux/cross-options.pl to work, use the format:
e9690142
JD
379 ^ -S, --long[=ARGS] (whitespace)
380 A --long option is required.
381 Otherwise, add exceptions to ../build-aux/cross-options.pl. */
a7c09cba 382
a92be413 383 printf (_("Usage: %s [OPTION]... FILE\n"), program_name);
0e575721 384 fputs (_("\
9dc3ee6d 385Generate a deterministic LR or generalized LR (GLR) parser employing\n\
af28d414
JD
386LALR(1), IELR(1), or canonical LR(1) parser tables. IELR(1) and\n\
387canonical LR(1) support is experimental.\n\
a92be413
PE
388\n\
389"), stdout);
9f306f2a 390
0e575721 391 fputs (_("\
a92be413 392Mandatory arguments to long options are mandatory for short options too.\n\
8e55b3aa
JD
393"), stdout);
394 fputs (_("\
395The same is true for optional arguments.\n\
a92be413 396"), stdout);
9f306f2a 397
0e575721 398 fputs (_("\
a92be413 399\n\
9f306f2a 400Operation modes:\n\
feeb56cd
JD
401 -h, --help display this help and exit\n\
402 -V, --version output version information and exit\n\
403 --print-localedir output directory containing locale-dependent data\n\
404 --print-datadir output directory containing skeletons and XSLT\n\
405 -y, --yacc emulate POSIX Yacc\n\
406 -W, --warnings[=CATEGORY] report the warnings falling in CATEGORY\n\
0db26489 407 -f, --feature[=FEATURE] activate miscellaneous features\n\
a92be413
PE
408\n\
409"), stdout);
9f306f2a 410
0e575721 411 fputs (_("\
9f306f2a 412Parser:\n\
de5ab940 413 -L, --language=LANGUAGE specify the output programming language\n\
de5ab940
JD
414 -S, --skeleton=FILE specify the skeleton to use\n\
415 -t, --debug instrument the parser for tracing\n\
416 same as `-Dparse.trace'\n\
417 --locations enable location support\n\
4b3847c3
AD
418 -D, --define=NAME[=VALUE] similar to '%define NAME \"VALUE\"'\n\
419 -F, --force-define=NAME[=VALUE] override '%define NAME \"VALUE\"'\n\
de5ab940 420 -p, --name-prefix=PREFIX prepend PREFIX to the external symbols\n\
4b3847c3
AD
421 deprecated by '-Dapi.prefix=PREFIX'\n\
422 -l, --no-lines don't generate '#line' directives\n\
de5ab940 423 -k, --token-table include a table of token names\n\
0e575721 424"), stdout);
0db26489 425 putc ('\n', stdout);
9f306f2a 426
8e55b3aa
JD
427 /* Keep -d and --defines separate so that ../build-aux/cross-options.pl
428 * won't assume that -d also takes an argument. */
0e575721 429 fputs (_("\
9f306f2a 430Output:\n\
feeb56cd
JD
431 --defines[=FILE] also produce a header file\n\
432 -d likewise but cannot specify FILE (for POSIX Yacc)\n\
433 -r, --report=THINGS also produce details on the automaton\n\
434 --report-file=FILE write report to FILE\n\
435 -v, --verbose same as `--report=state'\n\
436 -b, --file-prefix=PREFIX specify a PREFIX for output files\n\
437 -o, --output=FILE leave output to FILE\n\
438 -g, --graph[=FILE] also output a graph of the automaton\n\
439 -x, --xml[=FILE] also output an XML report of the automaton\n\
440 (the XML schema is experimental)\n\
0e575721 441"), stdout);
0db26489 442 putc ('\n', stdout);
86eff183 443
6aeb9c57
AD
444 fputs (_("\
445Warning categories include:\n\
9503b0a4
TR
446 `midrule-values' unset or unused midrule values\n\
447 `yacc' incompatibilities with POSIX Yacc\n\
448 `conflicts-sr' S/R conflicts (enabled by default)\n\
449 `conflicts-rr' R/R conflicts (enabled by default)\n\
450 `deprecated' obsolete constructs\n\
cc2235ac 451 `precedence' useless precedence and associativity\n\
9503b0a4
TR
452 `other' all other warnings (enabled by default)\n\
453 `all' all the warnings\n\
454 `no-CATEGORY' turn off warnings in CATEGORY\n\
455 `none' turn off all the warnings\n\
456 `error[=CATEGORY]' treat warnings as errors\n\
6aeb9c57 457"), stdout);
bd526380 458 putc ('\n', stdout);
6aeb9c57 459
0e575721 460 fputs (_("\
ec3bc396
AD
461THINGS is a list of comma separated words that can include:\n\
462 `state' describe the states\n\
463 `itemset' complete the core item sets with their closure\n\
742e4900 464 `lookahead' explicitly associate lookahead tokens to items\n\
b408954b 465 `solved' describe shift/reduce conflicts solving\n\
ec3bc396
AD
466 `all' include all the above information\n\
467 `none' disable the report\n\
0e575721 468"), stdout);
0db26489
TR
469 putc ('\n', stdout);
470
471 fputs (_("\
472FEATURE is a list of comma separated words that can include:\n\
473 `caret' show errors with carets\n\
474 `all' all of the above\n\
475 `none' disable all of the above\n\
476 "), stdout);
9f306f2a 477
d740d2b5
AD
478 putc ('\n', stdout);
479 printf (_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT);
480 printf (_("%s home page: <%s>.\n"), PACKAGE_NAME, PACKAGE_URL);
481 fputs (_("General help using GNU software: "
482 "<http://www.gnu.org/gethelp/>.\n"),
483 stdout);
484 /* Don't output this redundant message for English locales.
485 Note we still output for 'C' so that it gets included in the
486 man page. */
487 const char *lc_messages = setlocale (LC_MESSAGES, NULL);
6b5a7489 488 if (lc_messages && !STREQ (lc_messages, "en_"))
d740d2b5
AD
489 /* TRANSLATORS: Replace LANG_CODE in this URL with your language
490 code <http://translationproject.org/team/LANG_CODE.html> to
491 form one of the URLs at http://translationproject.org/team/.
492 Otherwise, replace the entire URL with your translation team's
493 email address. */
494 fputs (_("Report translation bugs to "
495 "<http://translationproject.org/team/>.\n"), stdout);
496 fputs (_("For complete documentation, run: info bison.\n"), stdout);
0e575721
AD
497 }
498
499 exit (status);
cbd8ffc5
DM
500}
501
e79137ac
AD
502
503/*------------------------------.
504| Display the version message. |
505`------------------------------*/
506
507static void
0e575721 508version (void)
e79137ac
AD
509{
510 /* Some efforts were made to ease the translators' task, please
511 continue. */
0e575721
AD
512 printf (_("bison (GNU Bison) %s"), VERSION);
513 putc ('\n', stdout);
514 fputs (_("Written by Robert Corbett and Richard Stallman.\n"), stdout);
515 putc ('\n', stdout);
e79137ac 516
0e575721 517 fprintf (stdout,
e9690142
JD
518 _("Copyright (C) %d Free Software Foundation, Inc.\n"),
519 PACKAGE_COPYRIGHT_YEAR);
e79137ac
AD
520
521 fputs (_("\
522This is free software; see the source for copying conditions. There is NO\n\
523warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
524"),
e9690142 525 stdout);
e79137ac
AD
526}
527
528
0e021770
PE
529/*-------------------------------------.
530| --skeleton and --language handling. |
531`--------------------------------------*/
532
533void
5a893c2b 534skeleton_arg (char const *arg, int prio, location loc)
0e021770
PE
535{
536 if (prio < skeleton_prio)
537 {
538 skeleton_prio = prio;
539 skeleton = arg;
540 }
541 else if (prio == skeleton_prio)
bb8e56ff
TR
542 complain (&loc, complaint,
543 _("multiple skeleton declarations are invalid"));
0e021770
PE
544}
545
546void
5a893c2b 547language_argmatch (char const *arg, int prio, location loc)
0e021770
PE
548{
549 char const *msg;
550
551 if (prio < language_prio)
552 {
553 int i;
554 for (i = 0; valid_languages[i].language[0]; i++)
e9690142
JD
555 if (c_strcasecmp (arg, valid_languages[i].language) == 0)
556 {
557 language_prio = prio;
558 language = &valid_languages[i];
559 return;
560 }
4a9cd8f2 561 msg = _("%s: invalid language");
0e021770
PE
562 }
563 else if (language_prio == prio)
564 msg = _("multiple language declarations are invalid");
565 else
566 return;
567
bb8e56ff 568 complain (&loc, complaint, msg, quotearg_colon (arg));
0e021770
PE
569}
570
e79137ac
AD
571/*----------------------.
572| Process the options. |
573`----------------------*/
574
7020f1e9
AD
575/* Shorts options.
576 Should be computed from long_options. */
577static char const short_options[] =
58697c6d 578 "D:"
de5ab940 579 "F:"
7020f1e9
AD
580 "L:"
581 "S:"
582 "T::"
583 "V"
8e55b3aa 584 "W::"
7020f1e9
AD
585 "b:"
586 "d"
0db26489 587 "f::"
7020f1e9
AD
588 "e"
589 "g::"
590 "h"
591 "k"
592 "l"
593 "n"
594 "o:"
595 "p:"
596 "r:"
597 "t"
598 "v"
599 "x::"
600 "y"
601 ;
e2aaf4c4 602
d0829076
PE
603/* Values for long options that do not have single-letter equivalents. */
604enum
605{
f7ab6a50 606 LOCATIONS_OPTION = CHAR_MAX + 1,
d4bd2295 607 PRINT_LOCALEDIR_OPTION,
1bb2bd75
JD
608 PRINT_DATADIR_OPTION,
609 REPORT_FILE_OPTION
d0829076
PE
610};
611
e2aaf4c4
AD
612static struct option const long_options[] =
613{
614 /* Operation modes. */
e9690142
JD
615 { "help", no_argument, 0, 'h' },
616 { "version", no_argument, 0, 'V' },
617 { "print-localedir", no_argument, 0, PRINT_LOCALEDIR_OPTION },
618 { "print-datadir", no_argument, 0, PRINT_DATADIR_OPTION },
7b42569e 619 { "warnings", optional_argument, 0, 'W' },
e2aaf4c4
AD
620
621 /* Parser. */
e9690142 622 { "name-prefix", required_argument, 0, 'p' },
e2aaf4c4
AD
623 { "include", required_argument, 0, 'I' },
624
625 /* Output. */
e9690142
JD
626 { "file-prefix", required_argument, 0, 'b' },
627 { "output", required_argument, 0, 'o' },
628 { "output-file", required_argument, 0, 'o' },
629 { "graph", optional_argument, 0, 'g' },
41d7a5f2 630 { "xml", optional_argument, 0, 'x' },
e9690142 631 { "report", required_argument, 0, 'r' },
1bb2bd75 632 { "report-file", required_argument, 0, REPORT_FILE_OPTION },
e9690142 633 { "verbose", no_argument, 0, 'v' },
e2aaf4c4
AD
634
635 /* Hidden. */
273a74fa 636 { "trace", optional_argument, 0, 'T' },
e2aaf4c4 637
e2aaf4c4
AD
638 /* Output. */
639 { "defines", optional_argument, 0, 'd' },
e35cd6de 640 { "feature", optional_argument, 0, 'f' },
e2aaf4c4
AD
641
642 /* Operation modes. */
643 { "fixed-output-files", no_argument, 0, 'y' },
e9690142 644 { "yacc", no_argument, 0, 'y' },
e2aaf4c4
AD
645
646 /* Parser. */
e9690142
JD
647 { "debug", no_argument, 0, 't' },
648 { "define", required_argument, 0, 'D' },
de5ab940 649 { "force-define", required_argument, 0, 'F' },
e9690142 650 { "locations", no_argument, 0, LOCATIONS_OPTION },
e2aaf4c4 651 { "no-lines", no_argument, 0, 'l' },
e2aaf4c4
AD
652 { "raw", no_argument, 0, 0 },
653 { "skeleton", required_argument, 0, 'S' },
0e021770 654 { "language", required_argument, 0, 'L' },
e2aaf4c4
AD
655 { "token-table", no_argument, 0, 'k' },
656
657 {0, 0, 0, 0}
658};
659
ae404801
AD
660/* Under DOS, there is no difference on the case. This can be
661 troublesome when looking for `.tab' etc. */
662#ifdef MSDOS
663# define AS_FILE_NAME(File) (strlwr (File), (File))
664#else
665# define AS_FILE_NAME(File) (File)
666#endif
667
58697c6d
AD
668/* Build a location for the current command line argument. */
669static
670location
d73e55e0 671command_line_location (void)
58697c6d
AD
672{
673 location res;
674 /* "<command line>" is used in GCC's messages about -D. */
a37131cc 675 boundary_set (&res.start, uniqstr_new ("<command line>"), optind - 1, -1);
58697c6d
AD
676 res.end = res.start;
677 return res;
678}
679
680
3d8fc6ca 681void
d2729d44 682getargs (int argc, char *argv[])
3d8fc6ca 683{
1916f98e 684 int c;
3d8fc6ca 685
08721544 686 while ((c = getopt_long (argc, argv, short_options, long_options, NULL))
e9690142 687 != -1)
cd5bd6ac
AD
688 switch (c)
689 {
58697c6d
AD
690 /* ASCII Sorting for short options (i.e., upper case then
691 lower case), and then long-only options. */
692
cd5bd6ac 693 case 0:
e9690142
JD
694 /* Certain long options cause getopt_long to return 0. */
695 break;
cd5bd6ac 696
58697c6d 697 case 'D': /* -DNAME[=VALUE]. */
de5ab940 698 case 'F': /* -FNAME[=VALUE]. */
58697c6d
AD
699 {
700 char* name = optarg;
84526bf3 701 char* value = strchr (optarg, '=');
58697c6d 702 if (value)
9ce405ce 703 *value++ = 0;
a8beef7e 704 muscle_percent_define_insert (name, command_line_location (),
de5ab940
JD
705 value ? value : "",
706 c == 'D' ? MUSCLE_PERCENT_DEFINE_D
707 : MUSCLE_PERCENT_DEFINE_F);
58697c6d 708 }
e9690142 709 break;
22c2cbc0 710
8e55b3aa 711 case 'I':
e9690142
JD
712 include = AS_FILE_NAME (optarg);
713 break;
41d7a5f2 714
0e021770 715 case 'L':
e9690142
JD
716 language_argmatch (optarg, command_line_prio,
717 command_line_location ());
718 break;
0e021770 719
cd5bd6ac 720 case 'S':
e9690142
JD
721 skeleton_arg (AS_FILE_NAME (optarg), command_line_prio,
722 command_line_location ());
723 break;
cd5bd6ac 724
8e55b3aa 725 case 'T':
327db05b 726 FLAGS_ARGMATCH (trace, optarg, trace_all);
e9690142 727 break;
f6bd5427 728
8e55b3aa 729 case 'V':
e9690142
JD
730 version ();
731 exit (EXIT_SUCCESS);
8e55b3aa 732
0db26489 733 case 'f':
f3ead217 734 FLAGS_ARGMATCH (feature, optarg, feature_all);
0db26489
TR
735 break;
736
8e55b3aa 737 case 'W':
4a3c55cf 738 warnings_argmatch (optarg);
e9690142 739 break;
8e55b3aa
JD
740
741 case 'b':
e9690142
JD
742 spec_file_prefix = AS_FILE_NAME (optarg);
743 break;
8e55b3aa 744
58697c6d
AD
745 case 'd':
746 /* Here, the -d and --defines options are differentiated. */
747 defines_flag = true;
748 if (optarg)
0b7fba13
AD
749 {
750 free (spec_defines_file);
751 spec_defines_file = xstrdup (AS_FILE_NAME (optarg));
752 }
58697c6d
AD
753 break;
754
8e55b3aa 755 case 'g':
e9690142
JD
756 graph_flag = true;
757 if (optarg)
0b7fba13
AD
758 {
759 free (spec_graph_file);
760 spec_graph_file = xstrdup (AS_FILE_NAME (optarg));
761 }
e9690142 762 break;
cd5bd6ac 763
8e55b3aa 764 case 'h':
e9690142 765 usage (EXIT_SUCCESS);
8e55b3aa 766
7b42569e 767 case 'k':
e9690142
JD
768 token_table_flag = true;
769 break;
7b42569e 770
cd5bd6ac 771 case 'l':
e9690142
JD
772 no_lines_flag = true;
773 break;
d0829076 774
7b42569e 775 case 'o':
e9690142
JD
776 spec_outfile = AS_FILE_NAME (optarg);
777 break;
cd5bd6ac 778
7b42569e 779 case 'p':
e9690142
JD
780 spec_name_prefix = optarg;
781 break;
7b42569e
AD
782
783 case 'r':
327db05b 784 FLAGS_ARGMATCH (report, optarg, report_all);
e9690142 785 break;
7b42569e 786
cd5bd6ac 787 case 't':
fa819509 788 muscle_percent_define_insert ("parse.trace",
de5ab940
JD
789 command_line_location (), "",
790 MUSCLE_PERCENT_DEFINE_D);
e9690142 791 break;
cd5bd6ac 792
7b42569e 793 case 'v':
e9690142
JD
794 report_flag |= report_states;
795 break;
cd5bd6ac 796
8e55b3aa 797 case 'x':
e9690142
JD
798 xml_flag = true;
799 if (optarg)
0b7fba13
AD
800 {
801 free (spec_xml_file);
802 spec_xml_file = xstrdup (AS_FILE_NAME (optarg));
803 }
e9690142 804 break;
cd5bd6ac 805
8e55b3aa 806 case 'y':
808e523d 807 warnings_flag[warning_yacc] = severity_error;
e9690142
JD
808 yacc_flag = true;
809 break;
ec3bc396 810
7b42569e 811 case LOCATIONS_OPTION:
bc0f5737
AD
812 muscle_percent_define_ensure ("locations",
813 command_line_location (), true);
e9690142 814 break;
273a74fa 815
7b42569e 816 case PRINT_LOCALEDIR_OPTION:
e9690142
JD
817 printf ("%s\n", LOCALEDIR);
818 exit (EXIT_SUCCESS);
7b42569e 819
d4bd2295 820 case PRINT_DATADIR_OPTION:
d9a7c07c 821 printf ("%s\n", pkgdatadir ());
e9690142 822 exit (EXIT_SUCCESS);
d4bd2295 823
8e55b3aa 824 case REPORT_FILE_OPTION:
0b7fba13 825 free (spec_verbose_file);
e9690142
JD
826 spec_verbose_file = xstrdup (AS_FILE_NAME (optarg));
827 break;
8e55b3aa 828
cd5bd6ac 829 default:
e9690142 830 usage (EXIT_FAILURE);
cd5bd6ac 831 }
3d8fc6ca 832
a4b6efd4 833 if (argc - optind != 1)
3d8fc6ca 834 {
a4b6efd4 835 if (argc - optind < 1)
4a9cd8f2 836 error (0, 0, _("%s: missing operand"), quotearg_colon (argv[argc - 1]));
a4b6efd4 837 else
4a9cd8f2 838 error (0, 0, _("extra operand %s"), quote (argv[optind + 1]));
0e575721 839 usage (EXIT_FAILURE);
3d8fc6ca 840 }
3d8fc6ca 841
d38a11a6 842 current_file = grammar_file = uniqstr_new (argv[optind]);
9fe5a457 843 MUSCLE_INSERT_C_STRING ("file_name", grammar_file);
3d8fc6ca 844}
67212941
JD
845
846void
847tr (char *s, char from, char to)
848{
849 for (; *s; s++)
850 if (*s == from)
851 *s = to;
852}