-int verboseflag;
-int definesflag;
-int debugflag;
-int nolinesflag;
-int noparserflag = 0;
-int toknumflag = 0;
-int rawtoknumflag = 0;
-char *spec_name_prefix; /* for -p. */
-char *spec_file_prefix; /* for -b. */
-extern int fixed_outfiles;/* for -y */
-
-extern char *program_name;
-extern char *version_string;
-
-extern void warns(); /* main.c */
-
-struct option longopts[] =
-{
- {"debug", 0, &debugflag, 1},
- {"defines", 0, &definesflag, 1},
- {"file-prefix", 1, 0, 'b'},
- {"fixed-output-files", 0, &fixed_outfiles, 1},
- {"help", 0, 0, 'h'},
- {"name-prefix", 1, 0, 'p'}, /* was 'a'; apparently unused -wjh */
- {"no-lines", 0, &nolinesflag, 1},
- {"no-parser", 0, &noparserflag, 1},
- {"output", 1, 0, 'o'},
- {"output-file", 1, 0, 'o'},
- {"raw", 0, &rawtoknumflag, 1},
- {"token-table", 0, &toknumflag, 1},
- {"verbose", 0, &verboseflag, 1},
- {"version", 0, 0, 'V'},
- {"yacc", 0, &fixed_outfiles, 1},
- {0, 0, 0, 0}
+bool defines_flag;
+bool graph_flag;
+bool xml_flag;
+bool no_lines_flag;
+bool token_table_flag;
+bool yacc_flag; /* for -y */
+
+bool nondeterministic_parser = false;
+bool glr_parser = false;
+
+int report_flag = report_none;
+int trace_flag = trace_none;
+int warnings_flag = warnings_none;
+
+static struct bison_language const valid_languages[] = {
+ { "c", "c-skel.m4", ".c", ".h", true },
+ { "c++", "c++-skel.m4", ".cc", ".hh", true },
+ { "java", "java-skel.m4", ".java", ".java", false },
+ { "", "", "", "", false }
+};
+
+int skeleton_prio = default_prio;
+const char *skeleton = NULL;
+int language_prio = default_prio;
+struct bison_language const *language = &valid_languages[0];
+const char *include = NULL;
+
+char *program_name;
+
+
+/** Decode an option's set of keys.
+ *
+ * \param option option being decoded.
+ * \param keys array of valid subarguments.
+ * \param values array of corresponding (int) values.
+ * \param flags the flags to update
+ * \param args comma separated list of effective subarguments to decode.
+ * If 0, then activate all the flags.
+ *
+ * If VALUE != 0 then KEY sets flags and no-KEY clears them.
+ * If VALUE == 0 then KEY clears all flags and no-KEY sets all flags.
+ * Thus no-none = all and no-all = none.
+ */
+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 no = strncmp (args, "no-", 3) == 0 ? 3 : 0;
+ int value = XARGMATCH (option, args + no, keys, values);
+ if (value == 0)
+ if (no)
+ *flags = ~0;
+ else
+ *flags = 0;
+ else
+ if (no)
+ *flags &= ~value;
+ 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. |
+`---------------------*/
+
+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 traces",
+ "scan - grammar scanner traces",
+ "parse - grammar parser traces",
+ "automaton - construction of the automaton",
+ "bitsets - use of bitsets",
+ "grammar - reading, reducing the grammar",
+ "resource - memory consumption (where available)",
+ "sets - grammar sets: firsts, nullable etc.",
+ "muscles - m4 definitions passed to the skeleton",
+ "tools - m4 invocation",
+ "m4 - m4 traces",
+ "skeleton - skeleton postprocessing",
+ "time - time consumption",
+ "ielr - IELR conversion",
+ "all - all of the above",
+ 0
+};
+
+static const int trace_types[] =
+{
+ trace_none,
+ trace_scan,
+ trace_parse,
+ trace_automaton,
+ trace_bitsets,
+ trace_grammar,
+ trace_resource,
+ trace_sets,
+ trace_muscles,
+ trace_tools,
+ trace_m4,
+ trace_skeleton,
+ trace_time,
+ trace_ielr,
+ trace_all
+};
+
+ARGMATCH_VERIFY (trace_args, trace_types);
+
+
+/*------------------------.
+| --warnings's handling. |
+`------------------------*/
+
+static const char * const warnings_args[] =
+{
+ /* In a series of synonyms, present the most meaningful first, so
+ that argmatch_valid be more readable. */
+ "none - no warnings",
+ "midrule-values - unset or unused midrule values",
+ "yacc - incompatibilities with POSIX Yacc",
+ "all - all of the above",
+ "error - warnings are errors",
+ 0
+};
+
+static const int warnings_types[] =
+{
+ warnings_none,
+ warnings_midrule_values,
+ warnings_yacc,
+ warnings_all,
+ warnings_error