From 951366c145107e763a92094462bfed0ae19d9ad1 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Mon, 5 Nov 2001 09:09:19 +0000 Subject: [PATCH] * src/options.h (struct option_table_struct): set_flags is void*. * src/options.c (longopts): Support `--output' and `%output'. (usage): Adjust. * src/lex.h (tok_setopt): Remove, replaced with... (tok_intopt, tok_stropt): these new guys. * src/lex.c (getopt.h): Not needed. (token_buffer, unlexed_token_buffer): Not const. (percent_table): Promote `-' over `_' in directive names. Active `%name-prefix', `file-prefix', and `output'. (parse_percent_token): Accept possible arguments to directives. Promote `-' over `_' in directive names. --- ChangeLog | 14 +++++++++ src/getargs.c | 6 ++-- src/lex.c | 76 ++++++++++++++++++++++++++++++++++++++----------- src/lex.h | 5 ++-- src/options.c | 47 ++++++++++++++++-------------- src/options.h | 4 +-- src/reader.c | 14 +++++---- tests/output.at | 10 +++++++ 8 files changed, 126 insertions(+), 50 deletions(-) diff --git a/ChangeLog b/ChangeLog index d94ffdaa..86ddb27e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2001-11-05 Akim Demaille + + * src/options.h (struct option_table_struct): set_flags is void*. + * src/options.c (longopts): Support `--output' and `%output'. + (usage): Adjust. + * src/lex.h (tok_setopt): Remove, replaced with... + (tok_intopt, tok_stropt): these new guys. + * src/lex.c (getopt.h): Not needed. + (token_buffer, unlexed_token_buffer): Not const. + (percent_table): Promote `-' over `_' in directive names. + Active `%name-prefix', `file-prefix', and `output'. + (parse_percent_token): Accept possible arguments to directives. + Promote `-' over `_' in directive names. + 2001-11-04 Akim Demaille * doc/bison.texinfo (Decl Summary): Split the list into diff --git a/src/getargs.c b/src/getargs.c index 24b6d893..e3ffdb68 100644 --- a/src/getargs.c +++ b/src/getargs.c @@ -89,9 +89,9 @@ Output:\n\ -d, --defines also produce a header file\n\ -v, --verbose also produce an explanation of the automaton\n\ -b, --file-prefix=PREFIX specify a PREFIX for output files\n\ - -o, --output-file=FILE leave output to FILE\n\ - -g, --graph also produce a VCG graph description of the \ -automaton\n"), stream); + -o, --output=FILE leave output to FILE\n\ + -g, --graph also produce a VCG description of the automaton\n\ +"), stream); putc ('\n', stream); fputs (_("\ diff --git a/src/lex.c b/src/lex.c index f09596e6..b27cfeeb 100644 --- a/src/lex.c +++ b/src/lex.c @@ -21,7 +21,6 @@ #include "system.h" #include "getargs.h" #include "files.h" -#include "getopt.h" /* for optarg */ #include "symtab.h" #include "options.h" #include "lex.h" @@ -31,7 +30,7 @@ /* Buffer for storing the current token. */ static struct obstack token_obstack; -const char *token_buffer = NULL; +char *token_buffer = NULL; bucket *symval; int numval; @@ -39,7 +38,7 @@ int numval; /* A token to be reread, see unlex and lex. */ static token_t unlexed = tok_undef; static bucket *unlexed_symval = NULL; -static const char *unlexed_token_buffer = NULL; +static char *unlexed_token_buffer = NULL; void lex_init (void) @@ -428,7 +427,7 @@ lex (void) /* parse the literal token and compute character code in code */ { - int code, discode; + int code; obstack_1grow (&token_obstack, '\''); literalchar (&token_obstack, &code, '\''); @@ -436,6 +435,7 @@ lex (void) c = getc (finput); if (c != '\'') { + int discode; complain (_("use \"...\" for multi-character literal tokens")); while (1) if (!literalchar (0, &discode, '\'')) @@ -553,7 +553,10 @@ option_strcmp (const char *left, const char *right) token_t parse_percent_token (void) { - const struct option_table_struct *tx; + const struct option_table_struct *tx = NULL; + /* Where `=' was found in token_buffer. */ + size_t equal_offset = 0; + char *arg = NULL; int c = getc (finput); @@ -565,6 +568,8 @@ parse_percent_token (void) case '{': return tok_percent_left_curly; + /* FIXME: Who the heck are those 5 guys!?! `%<' = `%left'!!! + Let's ask for there removal. */ case '<': return tok_left; @@ -593,9 +598,33 @@ parse_percent_token (void) c = getc (finput); } - ungetc (c, finput); + if (c == '=') + { + equal_offset = obstack_object_size (&token_obstack); + obstack_1grow (&token_obstack, c); + c = getc (finput); + if (c = '"') + { + int code; /* ignored here */ + + obstack_1grow (&token_obstack, '"'); + /* Read up to and including ". */ + while (literalchar (&token_obstack, &code, '"')) + /* nothing */; + } + } + else + ungetc (c, finput); + obstack_1grow (&token_obstack, '\0'); token_buffer = obstack_finish (&token_obstack); + if (equal_offset) + { + /* %token_buffer="arg" */ + arg = token_buffer + equal_offset + 2; + arg[strlen (arg) - 1] = '\0'; + token_buffer[equal_offset] = '\0'; + } /* table lookup % directive */ for (tx = option_table; tx->name; tx++) @@ -603,27 +632,42 @@ parse_percent_token (void) && option_strcmp (token_buffer + 1, tx->name) == 0) break; - if (tx->set_flag) - { - *((int *) (tx->set_flag)) = 1; - return tok_noop; - } + if (arg && !tx->ret_val == tok_stropt) + fatal (_("`%s' supports no argument: %s"), token_buffer, quotearg (arg)); + switch (tx->ret_val) { - case tok_setopt: - *((char **) (tx->set_flag)) = optarg; + case tok_stropt: + assert (tx->set_flag); + if (arg) + { + /* Keep only the first assignment: command line options have + already been processed, and we want them to have + precedence. Side effect: if this %-option is used + several times, only the first is honored. Bah. */ + if (!*((char **) (tx->set_flag))) + *((char **) (tx->set_flag)) = arg; + } + else + fatal (_("`%s' requires an argument"), token_buffer); + return tok_noop; + break; + + case tok_intopt: + assert (tx->set_flag); + *((int *) (tx->set_flag)) = 1; return tok_noop; break; case tok_obsolete: fatal (_("`%s' is no longer supported"), token_buffer); + return tok_noop; break; default: - /* Other cases do not apply here. */ + return tx->ret_val; break; } - - return tx->ret_val; + abort (); } diff --git a/src/lex.h b/src/lex.h index cb5a75e8..38edec80 100644 --- a/src/lex.h +++ b/src/lex.h @@ -51,12 +51,13 @@ typedef enum token_e tok_define, tok_skel, tok_noop, - tok_setopt, + tok_intopt, + tok_stropt, tok_illegal, tok_obsolete } token_t; -extern const char *token_buffer; +extern char *token_buffer; extern bucket *symval; extern int numval; diff --git a/src/options.c b/src/options.c index 37963cd4..9ab81531 100644 --- a/src/options.c +++ b/src/options.c @@ -22,6 +22,7 @@ #include "xalloc.h" #include "system.h" #include "getopt.h" +#include "files.h" #include "getargs.h" #include "gram.h" #include "symtab.h" @@ -52,10 +53,13 @@ const struct option_table_struct option_table[] = /* Output. */ {opt_cmd_line, "file-prefix", required_argument, 0, 0, 'b'}, + {opt_cmd_line, "output", required_argument, 0, 0, 'o'}, {opt_cmd_line, "output-file", required_argument, 0, 0, 'o'}, {opt_cmd_line, "graph", optional_argument, 0, 0, 'g'}, /* Hidden. */ + /* Fixme: What is this `1' doing here!!! Sounds dead wrong. See + locations too below. */ {opt_cmd_line, "statistics", no_argument, &statistics_flag, 0, 1}, /* @@ -76,19 +80,18 @@ const struct option_table_struct option_table[] = {opt_percent, "nonassoc", 0, NULL, tok_nonassoc, 0}, {opt_percent, "binary", 0, NULL, tok_nonassoc, 0}, {opt_percent, "prec", 0, NULL, tok_prec, 0}, -#if 0 - /* For the time being, this is not enabled yet, while it's possible - though, since we use obstacks. The only risk is with semantic - parsers which will output an `include' of an output file: be sure - that the naem included is indeed the name of the output file. */ - /* FIXME Should we activate this options ? */ - {opt_both, "output-file", required_argument, &spec_outfile, tok_setopt, 'o'}, - {opt_both, "file-prefix", required_argument,&spec_file_prefix,tok_setopt,'b'}, - {opt_both, "name-prefix", required_argument,&spec_name_prefix,tok_setopt,'p'}, -#endif + + /* FIXME: semantic parsers will output an `include' of an + output file: be sure that the naem included is indeed the name of + the output file. */ /* FIXME Should we activate this options ? + */ + {opt_both, "output", required_argument, &spec_outfile, tok_stropt, 'o'}, + {opt_both, "file-prefix", required_argument,&spec_file_prefix,tok_stropt,'b'}, + {opt_both, "name-prefix", required_argument,&spec_name_prefix,tok_stropt,'p'}, + {opt_percent, "define", 0, NULL, tok_define, 0}, - {opt_percent, "semantic-parser", 0, &semantic_parser, tok_noop, 0}, - {opt_percent, "pure-parser", 0, &pure_parser, tok_noop, 0}, + {opt_percent, "semantic-parser", 0, &semantic_parser, tok_intopt, 0}, + {opt_percent, "pure-parser", 0, &pure_parser, tok_intopt, 0}, /* * Percent and command line declarations. @@ -99,21 +102,21 @@ const struct option_table_struct option_table[] = the same, the char `-'. */ /* Output. */ - {opt_both, "defines", optional_argument, &defines_flag, tok_noop, 'd'}, - {opt_both, "verbose", no_argument, &verbose_flag, tok_noop, 'v'}, + {opt_both, "defines", optional_argument, &defines_flag, tok_intopt, 'd'}, + {opt_both, "verbose", no_argument, &verbose_flag, tok_intopt, 'v'}, /* Operation modes. */ - {opt_both, "fixed-output-files", no_argument, &yacc_flag, tok_noop, 'y'}, - {opt_both, "yacc", no_argument, &yacc_flag, tok_noop, 'y'}, + {opt_both, "fixed-output-files", no_argument, &yacc_flag, tok_intopt, 'y'}, + {opt_both, "yacc", no_argument, &yacc_flag, tok_intopt, 'y'}, /* Parser. */ - {opt_both, "debug", no_argument, &debug_flag, tok_noop, 't'}, - {opt_both, "locations", no_argument, &locations_flag, tok_noop, 1}, - {opt_both, "no-lines", no_argument, &no_lines_flag, tok_noop, 'l'}, - {opt_both, "no-parser", no_argument, &no_parser_flag, tok_noop, 'n'}, + {opt_both, "debug", no_argument, &debug_flag, tok_intopt, 't'}, + {opt_both, "locations", no_argument, &locations_flag, tok_intopt, 1}, + {opt_both, "no-lines", no_argument, &no_lines_flag, tok_intopt, 'l'}, + {opt_both, "no-parser", no_argument, &no_parser_flag, tok_intopt, 'n'}, {opt_both, "raw", no_argument, 0, tok_obsolete, 'r'}, {opt_both, "skeleton", required_argument, 0, tok_skel, 'S'}, - {opt_both, "token-table", no_argument, &token_table_flag, tok_noop, 'k'}, + {opt_both, "token-table", no_argument, &token_table_flag, tok_intopt, 'k'}, {0, 0, 0, 0, 0, 0} }; @@ -143,7 +146,7 @@ create_long_option_table () longopts[j].name = option_table[i].name; longopts[j].has_arg = option_table[i].has_arg; /* When an options is declared having 'optional_argument' and - a flag is specified to be set, the option is skipped on + a flag is specified to be set, the option is skipped on command line. So we never use a flag when a command line option is declared 'optional_argument. */ if (longopts[j].has_arg == optional_argument) diff --git a/src/options.h b/src/options.h index c509580f..8ad5a62e 100644 --- a/src/options.h +++ b/src/options.h @@ -21,7 +21,7 @@ #ifndef OPTIONS_H_ # define OPTIONS_H_ -/* opt_access_t and struct option_table_struct need to be declare +/* opt_access_t and struct option_table_struct need to be declare here, for the parse_percent_token function in lex.c. */ /* Option accessibility. */ @@ -43,7 +43,7 @@ struct option_table_struct /* Use for command line. */ int has_arg; /* A set_flag value causes the named flag to be set. */ - int *set_flag; + void *set_flag; /* A retval action returns the code. */ int ret_val; /* The short option value, frequently a letter. */ diff --git a/src/reader.c b/src/reader.c index bbdb40ae..bf6eef0d 100644 --- a/src/reader.c +++ b/src/reader.c @@ -962,16 +962,13 @@ parse_skel_decl (void) static void read_declarations (void) { - int c; - int tok; - for (;;) { - c = skip_white_space (); + int c = skip_white_space (); if (c == '%') { - tok = parse_percent_token (); + token_t tok = parse_percent_token (); switch (tok) { @@ -1033,6 +1030,13 @@ read_declarations (void) case tok_noop: break; + case tok_stropt: + case tok_intopt: + case tok_obsolete: + case tok_illegal: + abort (); + break; + default: complain (_("unrecognized: %s"), token_buffer); skip_to_char ('%'); diff --git a/tests/output.at b/tests/output.at index 964e9119..55177fe4 100644 --- a/tests/output.at +++ b/tests/output.at @@ -53,6 +53,16 @@ AT_CHECK_OUTPUT([foo.y], [%defines %verbose], [], AT_CHECK_OUTPUT([foo.y], [%defines %verbose %yacc],[], [y.output y.tab.c y.tab.h]) +# Exercise %output and %file-prefix +AT_CHECK_OUTPUT([foo.y], [%file-prefix="bar" %defines %verbose], [], + [bar.output bar.tab.c bar.tab.h]) +AT_CHECK_OUTPUT([foo.y], [%output="bar.c" %defines %verbose %yacc],[], + [bar.output bar.c bar.h]) +AT_CHECK_OUTPUT([foo.y], + [%file-prefix="baz" %output="bar.c" %defines %verbose %yacc], + [], + [bar.output bar.c bar.h]) + # Check priorities of extension control. AT_CHECK_OUTPUT([foo.yy], [%defines %verbose], [], -- 2.45.2