]> git.saurik.com Git - bison.git/blobdiff - src/getargs.c
* src/getargs.c (flags_argmatch): Don't cause segmentation fault for
[bison.git] / src / getargs.c
index 93d9c3bf029d19cdf2bb5fbc9c39007da95fea58..94d24329d716cdd0ea167be3135f96f30a20a2ec 100644 (file)
 
 #include <config.h>
 #include "system.h"
+#include "revision.h"
 
 #include <argmatch.h>
+#include <configmake.h>
 #include <error.h>
 
 /* Hack to get <getopt.h> to declare getopt with a prototype.  */
@@ -58,9 +60,11 @@ bool error_verbose = false;
 bool nondeterministic_parser = false;
 bool glr_parser = false;
 bool pure_parser = false;
+bool push_parser = false;
 
 int report_flag = report_none;
 int trace_flag = trace_none;
+int warnings_flag = warnings_none;
 
 const char *skeleton = NULL;
 const char *include = NULL;
@@ -68,6 +72,85 @@ const char *include = NULL;
 extern char *program_name;
 
 
+/** Decode an option's set of keys.
+ *
+ *  \param option   option being decoded.
+ *  \paran keys     array of valid subarguments.
+ *  \param values   array of corresponding (int) values.
+ *  \param flag     the flags to update
+ *  \param args     colon separated list of effective subarguments to decode.
+ *                  If 0, then activate all the flags.
+ *
+ *  The special value 0 resets the flags to 0.
+ */
+static void
+flags_argmatch (const char *option,
+               const char * const keys[], const int values[],
+               int *flags, char *args)
+{
+  if (args)
+    {
+      args = strtok (args, ",");
+      while (args)
+       {
+         int value = XARGMATCH (option, args, keys, values);
+         if (value == 0)
+           *flags = 0;
+         else
+           *flags |= value;
+          args = strtok (NULL, ",");
+       }
+    }
+  else
+    *flags = ~0;
+}
+
+/** Decode a set of sub arguments.
+ *
+ *  \param FlagName  the flag familly to update.
+ *  \param args      the effective sub arguments to decode.
+ *
+ *  \arg FlagName_args   the list of keys.
+ *  \arg FlagName_types  the list of values.
+ *  \arg FlagName_flag   the flag to update.
+ */
+#define FLAGS_ARGMATCH(FlagName, Args)                                 \
+  flags_argmatch ("--" #FlagName, FlagName ## _args, FlagName ## _types, \
+                 &FlagName ## _flag, Args)
+
+
+/*----------------------.
+| --report's handling.  |
+`----------------------*/
+
+static const char * const report_args[] =
+{
+  /* In a series of synonyms, present the most meaningful first, so
+     that argmatch_valid be more readable.  */
+  "none",
+  "state", "states",
+  "itemset", "itemsets",
+  "lookahead", "lookaheads", "look-ahead",
+  "solved",
+  "all",
+  0
+};
+
+static const int report_types[] =
+{
+  report_none,
+  report_states, report_states,
+  report_states | report_itemsets, report_states | report_itemsets,
+  report_states | report_lookahead_tokens,
+  report_states | report_lookahead_tokens,
+  report_states | report_lookahead_tokens,
+  report_states | report_solved_conflicts,
+  report_all
+};
+
+ARGMATCH_VERIFY (report_args, report_types);
+
+
 /*---------------------.
 | --trace's handling.  |
 `---------------------*/
@@ -76,15 +159,16 @@ static const char * const trace_args[] =
 {
   /* In a series of synonyms, present the most meaningful first, so
      that argmatch_valid be more readable.  */
-  "none       - no report",
+  "none       - no traces",
   "scan       - grammar scanner traces",
   "parse      - grammar parser traces",
-  "automaton  - contruction of the automaton",
+  "automaton  - construction of the automaton",
   "bitsets    - use of bitsets",
-  "grammar    - reading, reducing of the grammar",
+  "grammar    - reading, reducing the grammar",
   "resource   - memory consumption (where available)",
   "sets       - grammar sets: firsts, nullable etc.",
-  "tools      - m4 invocation and preserve the temporary file",
+  "tools      - m4 invocation",
+  "m4         - m4 traces",
   "skeleton   - skeleton postprocessing",
   "time       - time consumption",
   "all        - all of the above",
@@ -102,6 +186,7 @@ static const int trace_types[] =
   trace_resource,
   trace_sets,
   trace_tools,
+  trace_m4,
   trace_skeleton,
   trace_time,
   trace_all
@@ -109,74 +194,31 @@ static const int trace_types[] =
 
 ARGMATCH_VERIFY (trace_args, trace_types);
 
-static void
-trace_argmatch (char *args)
-{
-  if (args)
-    {
-      args = strtok (args, ",");
-      do
-       {
-         int trace = XARGMATCH ("--trace", args,
-                                trace_args, trace_types);
-         if (trace == trace_none)
-           trace_flag = trace_none;
-         else
-           trace_flag |= trace;
-       }
-      while ((args = strtok (NULL, ",")));
-    }
-  else
-    trace_flag = trace_all;
-}
 
+/*------------------------.
+| --warnings's handling.  |
+`------------------------*/
 
-/*----------------------.
-| --report's handling.  |
-`----------------------*/
-
-static const char * const report_args[] =
+static const char * const warnings_args[] =
 {
   /* In a series of synonyms, present the most meaningful first, so
      that argmatch_valid be more readable.  */
-  "none",
-  "state", "states",
-  "itemset", "itemsets",
-  "look-ahead", "lookahead", "lookaheads",
-  "solved",
-  "all",
+  "none       - no warnings",
+  "error      - warnings are errors",
+  "yacc       - incompatibilities with POSIX YACC",
+  "all        - all of the above",
   0
 };
 
-static const int report_types[] =
+static const int warnings_types[] =
 {
-  report_none,
-  report_states, report_states,
-  report_states | report_itemsets, report_states | report_itemsets,
-  report_states | report_look_ahead_tokens,
-  report_states | report_look_ahead_tokens,
-  report_states | report_look_ahead_tokens,
-  report_states | report_solved_conflicts,
-  report_all
+  warnings_none,
+  warnings_error,
+  warnings_yacc,
+  warnings_all
 };
 
-ARGMATCH_VERIFY (report_args, report_types);
-
-static void
-report_argmatch (char *args)
-{
-  args = strtok (args, ",");
-  do
-    {
-      int report = XARGMATCH ("--report", args,
-                             report_args, report_types);
-      if (report == report_none)
-       report_flag = report_none;
-      else
-       report_flag |= report;
-    }
-  while ((args = strtok (NULL, ",")));
-}
+ARGMATCH_VERIFY (warnings_args, warnings_types);
 
 
 /*-------------------------------------------.
@@ -193,29 +235,25 @@ usage (int status)
             program_name);
   else
     {
-      /* Some efforts were made to ease the translators' task, please
-        continue.  */
+      printf (_("Usage: %s [OPTION]... FILE\n"), program_name);
       fputs (_("\
-GNU bison generates parsers for LALR(1) grammars.\n"), stdout);
-      putc ('\n', stdout);
-
-      fprintf (stdout, _("\
-Usage: %s [OPTION]... FILE\n"), program_name);
-      putc ('\n', stdout);
+Generate LALR(1) and GLR parsers.\n\
+\n\
+"), stdout);
 
       fputs (_("\
-If a long option shows an argument as mandatory, then it is mandatory\n\
-for the equivalent short option also.  Similarly for optional arguments.\n"),
-            stdout);
-      putc ('\n', stdout);
+Mandatory arguments to long options are mandatory for short options too.\n\
+"), stdout);
 
       fputs (_("\
+\n\
 Operation modes:\n\
   -h, --help                 display this help and exit\n\
   -V, --version              output version information and exit\n\
       --print-localedir      output directory containing locale-dependent data\n\
-  -y, --yacc                 emulate POSIX yacc\n"), stdout);
-      putc ('\n', stdout);
+  -y, --yacc                 emulate POSIX Yacc\n\
+\n\
+"), stdout);
 
       fputs (_("\
 Parser:\n\
@@ -226,8 +264,8 @@ Parser:\n\
   -l, --no-lines             don't generate `#line' directives\n\
   -n, --no-parser            generate the tables only\n\
   -k, --token-table          include a table of token names\n\
+\n\
 "), stdout);
-      putc ('\n', stdout);
 
       fputs (_("\
 Output:\n\
@@ -236,23 +274,21 @@ Output:\n\
   -v, --verbose              same as `--report=state'\n\
   -b, --file-prefix=PREFIX   specify a PREFIX for output files\n\
   -o, --output=FILE          leave output to FILE\n\
-  -g, --graph                also produce a VCG description of the automaton\n\
+  -g, --graph                also output a graph of the automaton\n\
+\n\
 "), stdout);
-      putc ('\n', stdout);
 
       fputs (_("\
 THINGS is a list of comma separated words that can include:\n\
   `state'        describe the states\n\
   `itemset'      complete the core item sets with their closure\n\
-  `look-ahead'   explicitly associate look-ahead tokens to items\n\
+  `lookahead'    explicitly associate lookahead tokens to items\n\
   `solved'       describe shift/reduce conflicts solving\n\
   `all'          include all the above information\n\
   `none'         disable the report\n\
 "), stdout);
-      putc ('\n', stdout);
 
-      fputs (_("\
-Report bugs to <bug-bison@gnu.org>.\n"), stdout);
+      printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
     }
 
   exit (status);
@@ -270,6 +306,7 @@ version (void)
      continue.  */
   printf (_("bison (GNU Bison) %s"), VERSION);
   putc ('\n', stdout);
+  printf ("%s", revision);
   fputs (_("Written by Robert Corbett and Richard Stallman.\n"), stdout);
   putc ('\n', stdout);
 
@@ -289,7 +326,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
 `----------------------*/
 
 /* Shorts options.  */
-static char const short_options[] = "yvegdhr:ltknVo:b:p:S:T::";
+static char const short_options[] = "yvegdhr:ltknVo:b:p:S:T::W";
 
 /* Values for long options that do not have single-letter equivalents.  */
 enum
@@ -301,9 +338,10 @@ enum
 static struct option const long_options[] =
 {
   /* Operation modes. */
-  { "help",            no_argument,    0,   'h' },
-  { "version",         no_argument,    0,   'V' },
-  { "print-localedir", no_argument,    0,   PRINT_LOCALEDIR_OPTION },
+  { "help",            no_argument,      0,   'h' },
+  { "version",         no_argument,      0,   'V' },
+  { "print-localedir", no_argument,      0,   PRINT_LOCALEDIR_OPTION },
+  { "warnings",        optional_argument, 0,   'W' },
 
   /* Parser. */
   { "name-prefix",   required_argument,          0,   'p' },
@@ -360,21 +398,10 @@ getargs (int argc, char *argv[])
        /* Certain long options cause getopt_long to return 0.  */
        break;
 
-      case 'y':
-       yacc_flag = true;
+      case 'b':
+       spec_file_prefix = AS_FILE_NAME (optarg);
        break;
 
-      case 'h':
-       usage (EXIT_SUCCESS);
-
-      case 'V':
-       version ();
-       exit (EXIT_SUCCESS);
-
-      case PRINT_LOCALEDIR_OPTION:
-       printf ("%s\n", LOCALEDIR);
-       exit (EXIT_SUCCESS);
-
       case 'g':
        /* Here, the -g and --graph=FILE options are differentiated.  */
        graph_flag = true;
@@ -382,9 +409,8 @@ getargs (int argc, char *argv[])
          spec_graph_file = AS_FILE_NAME (optarg);
        break;
 
-      case 'v':
-       report_flag |= report_states;
-       break;
+      case 'h':
+       usage (EXIT_SUCCESS);
 
       case 'S':
        skeleton = AS_FILE_NAME (optarg);
@@ -401,46 +427,62 @@ getargs (int argc, char *argv[])
          spec_defines_file = AS_FILE_NAME (optarg);
        break;
 
+      case 'k':
+       token_table_flag = true;
+       break;
+
       case 'l':
        no_lines_flag = true;
        break;
 
-      case LOCATIONS_OPTION:
-       locations_flag = true;
+      case 'n':
+       no_parser_flag = true;
        break;
 
-      case 'k':
-       token_table_flag = true;
+      case 'o':
+       spec_outfile = AS_FILE_NAME (optarg);
        break;
 
-      case 'n':
-       no_parser_flag = true;
+      case 'p':
+       spec_name_prefix = optarg;
+       break;
+
+      case 'r':
+       FLAGS_ARGMATCH (report, optarg);
+       break;
+
+      case 'T':
+       FLAGS_ARGMATCH (trace, optarg);
        break;
 
       case 't':
        debug_flag = true;
        break;
 
-      case 'o':
-       spec_outfile = AS_FILE_NAME (optarg);
-       break;
+      case 'V':
+       version ();
+       exit (EXIT_SUCCESS);
 
-      case 'b':
-       spec_file_prefix = AS_FILE_NAME (optarg);
+      case 'v':
+       report_flag |= report_states;
        break;
 
-      case 'p':
-       spec_name_prefix = optarg;
+      case 'y':
+       yacc_flag = true;
        break;
 
-      case 'r':
-       report_argmatch (optarg);
+      case 'W':
+       FLAGS_ARGMATCH (warnings, optarg);
        break;
 
-      case 'T':
-       trace_argmatch (optarg);
+      case LOCATIONS_OPTION:
+       locations_flag = true;
        break;
 
+      case PRINT_LOCALEDIR_OPTION:
+       printf ("%s\n", LOCALEDIR);
+       exit (EXIT_SUCCESS);
+
       default:
        usage (EXIT_FAILURE);
       }