Home | History | Annotate | Download | only in src
      1 /* Parse command line arguments for Bison.
      2 
      3    Copyright (C) 1984, 1986, 1989, 1992, 2000-2012 Free Software
      4    Foundation, Inc.
      5 
      6    This file is part of Bison, the GNU Compiler Compiler.
      7 
      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.
     12 
     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.
     17 
     18    You should have received a copy of the GNU General Public License
     19    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     20 
     21 #include <config.h>
     22 #include "system.h"
     23 #include "output.h"
     24 
     25 #include <argmatch.h>
     26 #include <c-strcase.h>
     27 #include <configmake.h>
     28 #include <error.h>
     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 
     36 #include <getopt.h>
     37 
     38 #ifdef HACK_FOR___GNU_LIBRARY___PROTOTYPE
     39 # undef __GNU_LIBRARY__
     40 # undef HACK_FOR___GNU_LIBRARY___PROTOTYPE
     41 #endif
     42 
     43 #include <progname.h>
     44 
     45 #include "complain.h"
     46 #include "files.h"
     47 #include "getargs.h"
     48 #include "muscle-tab.h"
     49 #include "quote.h"
     50 #include "uniqstr.h"
     51 
     52 bool debug;
     53 bool defines_flag;
     54 bool graph_flag;
     55 bool xml_flag;
     56 bool locations_flag;
     57 bool no_lines_flag;
     58 bool token_table_flag;
     59 bool yacc_flag;	/* for -y */
     60 
     61 bool error_verbose = false;
     62 
     63 bool nondeterministic_parser = false;
     64 bool glr_parser = false;
     65 
     66 int feature_flag = feature_none;
     67 int report_flag = report_none;
     68 int trace_flag = trace_none;
     69 int warnings_flag = warnings_conflicts_sr | warnings_conflicts_rr
     70                     | warnings_other;
     71 
     72 static struct bison_language const valid_languages[] = {
     73   { "c", "c-skel.m4", ".c", ".h", true },
     74   { "c++", "c++-skel.m4", ".cc", ".hh", true },
     75   { "java", "java-skel.m4", ".java", ".java", false },
     76   { "", "", "", "", false }
     77 };
     78 
     79 int skeleton_prio = default_prio;
     80 const char *skeleton = NULL;
     81 int language_prio = default_prio;
     82 struct bison_language const *language = &valid_languages[0];
     83 const char *include = NULL;
     84 
     85 
     86 /** Decode an option's set of keys.
     87  *
     88  *  \param option   option being decoded.
     89  *  \param keys     array of valid subarguments.
     90  *  \param values   array of corresponding (int) values.
     91  *  \param all      the all value.
     92  *  \param flags    the flags to update
     93  *  \param args     comma separated list of effective subarguments to decode.
     94  *                  If 0, then activate all the flags.
     95  *
     96  *  If VALUE != 0 then KEY sets flags and no-KEY clears them.
     97  *  If VALUE == 0 then KEY clears all flags from \c all and no-KEY sets all
     98  *  flags from \c all.  Thus no-none = all and no-all = none.
     99  */
    100 static void
    101 flags_argmatch (const char *option,
    102 		const char * const keys[], const int values[],
    103 		int all, int *flags, char *args)
    104 {
    105   if (args)
    106     {
    107       args = strtok (args, ",");
    108       while (args)
    109 	{
    110 	  int no = strncmp (args, "no-", 3) == 0 ? 3 : 0;
    111 	  int value = XARGMATCH (option, args + no, keys, values);
    112 	  if (value == 0)
    113 	    {
    114 	      if (no)
    115 		*flags |= all;
    116 	      else
    117 		*flags &= ~all;
    118 	    }
    119 	  else
    120 	    {
    121 	      if (no)
    122 		*flags &= ~value;
    123 	      else
    124 		*flags |= value;
    125 	    }
    126 	  args = strtok (NULL, ",");
    127 	}
    128     }
    129   else
    130     *flags |= all;
    131 }
    132 
    133 /** Decode a set of sub arguments.
    134  *
    135  *  \param FlagName  the flag familly to update.
    136  *  \param Args      the effective sub arguments to decode.
    137  *
    138  *  \arg FlagName_args   the list of keys.
    139  *  \arg FlagName_types  the list of values.
    140  *  \arg FlagName_all    the all value.
    141  *  \arg FlagName_flag   the flag to update.
    142  */
    143 #define FLAGS_ARGMATCH(FlagName, Args)					\
    144   flags_argmatch ("--" #FlagName, FlagName ## _args, FlagName ## _types, \
    145 		  FlagName ## _all, &FlagName ## _flag, Args)
    146 
    147 
    148 /*----------------------.
    149 | --report's handling.  |
    150 `----------------------*/
    151 
    152 static 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 
    165 static 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 
    177 ARGMATCH_VERIFY (report_args, report_types);
    178 
    179 
    180 /*---------------------.
    181 | --trace's handling.  |
    182 `---------------------*/
    183 
    184 static const char * const trace_args[] =
    185 {
    186   /* In a series of synonyms, present the most meaningful first, so
    187      that argmatch_valid be more readable.  */
    188   "none       - no traces",
    189   "scan       - grammar scanner traces",
    190   "parse      - grammar parser traces",
    191   "automaton  - construction of the automaton",
    192   "bitsets    - use of bitsets",
    193   "grammar    - reading, reducing the grammar",
    194   "resource   - memory consumption (where available)",
    195   "sets       - grammar sets: firsts, nullable etc.",
    196   "muscles    - m4 definitions passed to the skeleton",
    197   "tools      - m4 invocation",
    198   "m4         - m4 traces",
    199   "skeleton   - skeleton postprocessing",
    200   "time       - time consumption",
    201   "ielr       - IELR conversion",
    202   "all        - all of the above",
    203   0
    204 };
    205 
    206 static const int trace_types[] =
    207 {
    208   trace_none,
    209   trace_scan,
    210   trace_parse,
    211   trace_automaton,
    212   trace_bitsets,
    213   trace_grammar,
    214   trace_resource,
    215   trace_sets,
    216   trace_muscles,
    217   trace_tools,
    218   trace_m4,
    219   trace_skeleton,
    220   trace_time,
    221   trace_ielr,
    222   trace_all
    223 };
    224 
    225 ARGMATCH_VERIFY (trace_args, trace_types);
    226 
    227 
    228 /*------------------------.
    229 | --warnings's handling.  |
    230 `------------------------*/
    231 
    232 static const char * const warnings_args[] =
    233 {
    234   /* In a series of synonyms, present the most meaningful first, so
    235      that argmatch_valid be more readable.  */
    236   "none            - no warnings",
    237   "midrule-values  - unset or unused midrule values",
    238   "yacc            - incompatibilities with POSIX Yacc",
    239   "conflicts-sr    - S/R conflicts",
    240   "conflicts-rr    - R/R conflicts",
    241   "other           - all other warnings",
    242   "all             - all of the above",
    243   "error           - warnings are errors",
    244   0
    245 };
    246 
    247 static const int warnings_types[] =
    248 {
    249   warnings_none,
    250   warnings_midrule_values,
    251   warnings_yacc,
    252   warnings_conflicts_sr,
    253   warnings_conflicts_rr,
    254   warnings_other,
    255   warnings_all,
    256   warnings_error
    257 };
    258 
    259 ARGMATCH_VERIFY (warnings_args, warnings_types);
    260 
    261 /*-----------------------.
    262 | --feature's handling.  |
    263 `-----------------------*/
    264 
    265 static const char * const feature_args[] =
    266 {
    267   "none",
    268   "caret", "diagnostics-show-caret",
    269   "all",
    270   0
    271 };
    272 
    273 static const int feature_types[] =
    274 {
    275   feature_none,
    276   feature_caret, feature_caret,
    277   feature_all
    278 };
    279 
    280 ARGMATCH_VERIFY (feature_args, feature_types);
    281 
    282 /*-------------------------------------------.
    283 | Display the help message and exit STATUS.  |
    284 `-------------------------------------------*/
    285 
    286 static void usage (int) ATTRIBUTE_NORETURN;
    287 
    288 static void
    289 usage (int status)
    290 {
    291   if (status != 0)
    292     fprintf (stderr, _("Try `%s --help' for more information.\n"),
    293 	     program_name);
    294   else
    295     {
    296       /* For ../build-aux/cross-options.pl to work, use the format:
    297 		^  -S, --long[=ARGS] (whitespace)
    298 	 A --long option is required.
    299 	 Otherwise, add exceptions to ../build-aux/cross-options.pl.  */
    300 
    301       printf (_("Usage: %s [OPTION]... FILE\n"), program_name);
    302       fputs (_("\
    303 Generate a deterministic LR or generalized LR (GLR) parser employing\n\
    304 LALR(1), IELR(1), or canonical LR(1) parser tables.  IELR(1) and\n\
    305 canonical LR(1) support is experimental.\n\
    306 \n\
    307 "), stdout);
    308 
    309       fputs (_("\
    310 Mandatory arguments to long options are mandatory for short options too.\n\
    311 "), stdout);
    312       fputs (_("\
    313 The same is true for optional arguments.\n\
    314 "), stdout);
    315 
    316       fputs (_("\
    317 \n\
    318 Operation modes:\n\
    319   -h, --help                 display this help and exit\n\
    320   -V, --version              output version information and exit\n\
    321       --print-localedir      output directory containing locale-dependent data\n\
    322       --print-datadir        output directory containing skeletons and XSLT\n\
    323   -y, --yacc                 emulate POSIX Yacc\n\
    324   -W, --warnings[=CATEGORY]  report the warnings falling in CATEGORY\n\
    325   -f, --feature[=FEATURE]    activate miscellaneous features\n\
    326 \n\
    327 "), stdout);
    328 
    329       fputs (_("\
    330 Parser:\n\
    331   -L, --language=LANGUAGE          specify the output programming language\n\
    332   -S, --skeleton=FILE              specify the skeleton to use\n\
    333   -t, --debug                      instrument the parser for debugging\n\
    334       --locations                  enable location support\n\
    335   -D, --define=NAME[=VALUE]        similar to '%define NAME \"VALUE\"'\n\
    336   -F, --force-define=NAME[=VALUE]  override '%define NAME \"VALUE\"'\n\
    337   -p, --name-prefix=PREFIX         prepend PREFIX to the external symbols\n\
    338                                    deprecated by '-Dapi.prefix=PREFIX'\n\
    339   -l, --no-lines                   don't generate '#line' directives\n\
    340   -k, --token-table                include a table of token names\n\
    341 "), stdout);
    342       putc ('\n', stdout);
    343 
    344       /* Keep -d and --defines separate so that ../build-aux/cross-options.pl
    345        * won't assume that -d also takes an argument.  */
    346       fputs (_("\
    347 Output:\n\
    348       --defines[=FILE]       also produce a header file\n\
    349   -d                         likewise but cannot specify FILE (for POSIX Yacc)\n\
    350   -r, --report=THINGS        also produce details on the automaton\n\
    351       --report-file=FILE     write report to FILE\n\
    352   -v, --verbose              same as `--report=state'\n\
    353   -b, --file-prefix=PREFIX   specify a PREFIX for output files\n\
    354   -o, --output=FILE          leave output to FILE\n\
    355   -g, --graph[=FILE]         also output a graph of the automaton\n\
    356   -x, --xml[=FILE]           also output an XML report of the automaton\n\
    357                              (the XML schema is experimental)\n\
    358 "), stdout);
    359       putc ('\n', stdout);
    360 
    361       fputs (_("\
    362 Warning categories include:\n\
    363   `midrule-values'  unset or unused midrule values\n\
    364   `yacc'            incompatibilities with POSIX Yacc\n\
    365   `conflicts-sr'    S/R conflicts (enabled by default)\n\
    366   `conflicts-rr'    R/R conflicts (enabled by default)\n\
    367   `deprecated'      obsolete constructs\n\
    368   `other'           all other warnings (enabled by default)\n\
    369   `all'             all the warnings\n\
    370   `no-CATEGORY'     turn off warnings in CATEGORY\n\
    371   `none'            turn off all the warnings\n\
    372   `error'           treat warnings as errors\n\
    373 "), stdout);
    374       putc ('\n', stdout);
    375 
    376       fputs (_("\
    377 THINGS is a list of comma separated words that can include:\n\
    378   `state'        describe the states\n\
    379   `itemset'      complete the core item sets with their closure\n\
    380   `lookahead'    explicitly associate lookahead tokens to items\n\
    381   `solved'       describe shift/reduce conflicts solving\n\
    382   `all'          include all the above information\n\
    383   `none'         disable the report\n\
    384 "), stdout);
    385       putc ('\n', stdout);
    386 
    387       fputs (_("\
    388 FEATURE is a list of comma separated words that can include:\n\
    389   `caret'        show errors with carets\n\
    390   `all'          all of the above\n\
    391   `none'         disable all of the above\n\
    392   "), stdout);
    393 
    394       putc ('\n', stdout);
    395       printf (_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT);
    396       printf (_("%s home page: <%s>.\n"), PACKAGE_NAME, PACKAGE_URL);
    397       fputs (_("General help using GNU software: "
    398                "<http://www.gnu.org/gethelp/>.\n"),
    399              stdout);
    400       /* Don't output this redundant message for English locales.
    401          Note we still output for 'C' so that it gets included in the
    402          man page.  */
    403       const char *lc_messages = setlocale (LC_MESSAGES, NULL);
    404       if (lc_messages && strcmp (lc_messages, "en_"))
    405         /* TRANSLATORS: Replace LANG_CODE in this URL with your language
    406            code <http://translationproject.org/team/LANG_CODE.html> to
    407            form one of the URLs at http://translationproject.org/team/.
    408            Otherwise, replace the entire URL with your translation team's
    409            email address.  */
    410         fputs (_("Report translation bugs to "
    411                  "<http://translationproject.org/team/>.\n"), stdout);
    412       fputs (_("For complete documentation, run: info bison.\n"), stdout);
    413     }
    414 
    415   exit (status);
    416 }
    417 
    418 
    419 /*------------------------------.
    420 | Display the version message.  |
    421 `------------------------------*/
    422 
    423 static void
    424 version (void)
    425 {
    426   /* Some efforts were made to ease the translators' task, please
    427      continue.  */
    428   printf (_("bison (GNU Bison) %s"), VERSION);
    429   putc ('\n', stdout);
    430   fputs (_("Written by Robert Corbett and Richard Stallman.\n"), stdout);
    431   putc ('\n', stdout);
    432 
    433   fprintf (stdout,
    434 	   _("Copyright (C) %d Free Software Foundation, Inc.\n"),
    435 	   PACKAGE_COPYRIGHT_YEAR);
    436 
    437   fputs (_("\
    438 This is free software; see the source for copying conditions.  There is NO\n\
    439 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
    440 "),
    441 	 stdout);
    442 }
    443 
    444 
    445 /*-------------------------------------.
    446 | --skeleton and --language handling.  |
    447 `--------------------------------------*/
    448 
    449 void
    450 skeleton_arg (char const *arg, int prio, location loc)
    451 {
    452   if (prio < skeleton_prio)
    453     {
    454       skeleton_prio = prio;
    455       skeleton = arg;
    456     }
    457   else if (prio == skeleton_prio)
    458     complain_at (loc, _("multiple skeleton declarations are invalid"));
    459 }
    460 
    461 void
    462 language_argmatch (char const *arg, int prio, location loc)
    463 {
    464   char const *msg;
    465 
    466   if (prio < language_prio)
    467     {
    468       int i;
    469       for (i = 0; valid_languages[i].language[0]; i++)
    470         if (c_strcasecmp (arg, valid_languages[i].language) == 0)
    471           {
    472             language_prio = prio;
    473             language = &valid_languages[i];
    474             return;
    475           }
    476       msg = _("%s: invalid language");
    477     }
    478   else if (language_prio == prio)
    479     msg = _("multiple language declarations are invalid");
    480   else
    481     return;
    482 
    483   complain_at (loc, msg, quotearg_colon (arg));
    484 }
    485 
    486 /*----------------------.
    487 | Process the options.  |
    488 `----------------------*/
    489 
    490 /* Shorts options.
    491    Should be computed from long_options.  */
    492 static char const short_options[] =
    493   "D:"
    494   "F:"
    495   "L:"
    496   "S:"
    497   "T::"
    498   "V"
    499   "W::"
    500   "b:"
    501   "d"
    502   "f::"
    503   "e"
    504   "g::"
    505   "h"
    506   "k"
    507   "l"
    508   "n"
    509   "o:"
    510   "p:"
    511   "r:"
    512   "t"
    513   "v"
    514   "x::"
    515   "y"
    516   ;
    517 
    518 /* Values for long options that do not have single-letter equivalents.  */
    519 enum
    520 {
    521   LOCATIONS_OPTION = CHAR_MAX + 1,
    522   PRINT_LOCALEDIR_OPTION,
    523   PRINT_DATADIR_OPTION,
    524   REPORT_FILE_OPTION
    525 };
    526 
    527 static struct option const long_options[] =
    528 {
    529   /* Operation modes. */
    530   { "help",            no_argument,	  0,   'h' },
    531   { "version",         no_argument,	  0,   'V' },
    532   { "print-localedir", no_argument,	  0,   PRINT_LOCALEDIR_OPTION },
    533   { "print-datadir",   no_argument,	  0,   PRINT_DATADIR_OPTION   },
    534   { "warnings",        optional_argument, 0,   'W' },
    535 
    536   /* Parser. */
    537   { "name-prefix",   required_argument,	  0,   'p' },
    538   { "include",       required_argument,   0,   'I' },
    539 
    540   /* Output. */
    541   { "file-prefix", required_argument,	0,   'b' },
    542   { "output",	   required_argument,	0,   'o' },
    543   { "output-file", required_argument,	0,   'o' },
    544   { "graph",	   optional_argument,	0,   'g' },
    545   { "xml",         optional_argument,   0,   'x' },
    546   { "report",	   required_argument,   0,   'r' },
    547   { "report-file", required_argument,   0,   REPORT_FILE_OPTION },
    548   { "verbose",	   no_argument,	        0,   'v' },
    549 
    550   /* Hidden. */
    551   { "trace",         optional_argument,   0,     'T' },
    552 
    553   /* Output.  */
    554   { "defines",     optional_argument,   0,   'd' },
    555   { "feature",     optional_argument,   0,   'f' },
    556 
    557   /* Operation modes.  */
    558   { "fixed-output-files", no_argument,  0,   'y' },
    559   { "yacc",	          no_argument,  0,   'y' },
    560 
    561   /* Parser.  */
    562   { "debug",	      no_argument,               0,   't' },
    563   { "define",	      required_argument,         0,   'D' },
    564   { "force-define",   required_argument,         0,   'F' },
    565   { "locations",      no_argument,		 0, LOCATIONS_OPTION },
    566   { "no-lines",       no_argument,               0,   'l' },
    567   { "raw",            no_argument,               0,     0 },
    568   { "skeleton",       required_argument,         0,   'S' },
    569   { "language",       required_argument,         0,   'L' },
    570   { "token-table",    no_argument,               0,   'k' },
    571 
    572   {0, 0, 0, 0}
    573 };
    574 
    575 /* Under DOS, there is no difference on the case.  This can be
    576    troublesome when looking for `.tab' etc.  */
    577 #ifdef MSDOS
    578 # define AS_FILE_NAME(File) (strlwr (File), (File))
    579 #else
    580 # define AS_FILE_NAME(File) (File)
    581 #endif
    582 
    583 /* Build a location for the current command line argument. */
    584 static
    585 location
    586 command_line_location (void)
    587 {
    588   location res;
    589   /* "<command line>" is used in GCC's messages about -D. */
    590   boundary_set (&res.start, uniqstr_new ("<command line>"), optind - 1, -1);
    591   res.end = res.start;
    592   return res;
    593 }
    594 
    595 
    596 void
    597 getargs (int argc, char *argv[])
    598 {
    599   int c;
    600 
    601   while ((c = getopt_long (argc, argv, short_options, long_options, NULL))
    602 	 != -1)
    603     switch (c)
    604       {
    605         /* ASCII Sorting for short options (i.e., upper case then
    606            lower case), and then long-only options.  */
    607 
    608       case 0:
    609 	/* Certain long options cause getopt_long to return 0.  */
    610 	break;
    611 
    612       case 'D': /* -DNAME[=VALUE]. */
    613       case 'F': /* -FNAME[=VALUE]. */
    614         {
    615           char* name = optarg;
    616           char* value = mbschr (optarg, '=');
    617           if (value)
    618             *value++ = 0;
    619           muscle_percent_define_insert (name, command_line_location (),
    620                                         value ? value : "",
    621                                         c == 'D' ? MUSCLE_PERCENT_DEFINE_D
    622                                                  : MUSCLE_PERCENT_DEFINE_F);
    623         }
    624 	break;
    625 
    626       case 'I':
    627 	include = AS_FILE_NAME (optarg);
    628 	break;
    629 
    630       case 'L':
    631 	language_argmatch (optarg, command_line_prio,
    632 			   command_line_location ());
    633 	break;
    634 
    635       case 'S':
    636 	skeleton_arg (AS_FILE_NAME (optarg), command_line_prio,
    637 		      command_line_location ());
    638 	break;
    639 
    640       case 'T':
    641 	FLAGS_ARGMATCH (trace, optarg);
    642 	break;
    643 
    644       case 'V':
    645 	version ();
    646 	exit (EXIT_SUCCESS);
    647 
    648       case 'f':
    649         FLAGS_ARGMATCH (feature, optarg);
    650         break;
    651 
    652       case 'W':
    653 	FLAGS_ARGMATCH (warnings, optarg);
    654 	break;
    655 
    656       case 'b':
    657 	spec_file_prefix = AS_FILE_NAME (optarg);
    658 	break;
    659 
    660       case 'd':
    661         /* Here, the -d and --defines options are differentiated.  */
    662         defines_flag = true;
    663         if (optarg)
    664           {
    665             free (spec_defines_file);
    666             spec_defines_file = xstrdup (AS_FILE_NAME (optarg));
    667           }
    668         break;
    669 
    670       case 'g':
    671 	graph_flag = true;
    672 	if (optarg)
    673           {
    674             free (spec_graph_file);
    675             spec_graph_file = xstrdup (AS_FILE_NAME (optarg));
    676           }
    677 	break;
    678 
    679       case 'h':
    680 	usage (EXIT_SUCCESS);
    681 
    682       case 'k':
    683 	token_table_flag = true;
    684 	break;
    685 
    686       case 'l':
    687 	no_lines_flag = true;
    688 	break;
    689 
    690       case 'o':
    691 	spec_outfile = AS_FILE_NAME (optarg);
    692 	break;
    693 
    694       case 'p':
    695 	spec_name_prefix = optarg;
    696 	break;
    697 
    698       case 'r':
    699 	FLAGS_ARGMATCH (report, optarg);
    700 	break;
    701 
    702       case 't':
    703 	debug = true;
    704 	break;
    705 
    706       case 'v':
    707 	report_flag |= report_states;
    708 	break;
    709 
    710       case 'x':
    711 	xml_flag = true;
    712 	if (optarg)
    713           {
    714             free (spec_xml_file);
    715             spec_xml_file = xstrdup (AS_FILE_NAME (optarg));
    716           }
    717 	break;
    718 
    719       case 'y':
    720 	yacc_flag = true;
    721 	break;
    722 
    723       case LOCATIONS_OPTION:
    724 	locations_flag = true;
    725 	break;
    726 
    727       case PRINT_LOCALEDIR_OPTION:
    728 	printf ("%s\n", LOCALEDIR);
    729 	exit (EXIT_SUCCESS);
    730 
    731       case PRINT_DATADIR_OPTION:
    732 	printf ("%s\n", compute_pkgdatadir ());
    733 	exit (EXIT_SUCCESS);
    734 
    735       case REPORT_FILE_OPTION:
    736         free (spec_verbose_file);
    737 	spec_verbose_file = xstrdup (AS_FILE_NAME (optarg));
    738 	break;
    739 
    740       default:
    741 	usage (EXIT_FAILURE);
    742       }
    743 
    744   if (argc - optind != 1)
    745     {
    746       if (argc - optind < 1)
    747         error (0, 0, _("%s: missing operand"), quotearg_colon (argv[argc - 1]));
    748       else
    749         error (0, 0, _("extra operand %s"), quote (argv[optind + 1]));
    750       usage (EXIT_FAILURE);
    751     }
    752 
    753   current_file = grammar_file = uniqstr_new (argv[optind]);
    754   MUSCLE_INSERT_C_STRING ("file_name", grammar_file);
    755 }
    756 
    757 void
    758 tr (char *s, char from, char to)
    759 {
    760   for (; *s; s++)
    761     if (*s == from)
    762       *s = to;
    763 }
    764