From: Akim Demaille Date: Tue, 31 Jul 2012 09:50:18 +0000 (+0200) Subject: Merge branch 'maint' X-Git-Tag: v2.7.90~368 X-Git-Url: https://git.saurik.com/bison.git/commitdiff_plain/cb9ec4fada480554cf47810fee736997d64e7427 Merge branch 'maint' * maint: use obstack_printf scanner: restore a missing start condition gnulib: update maint: post-release administrivia version 2.6.1 gnulib: update maint: fix some syntax-check issues tests: do not depend on __cplusplus to decide for C++ or C output Conflicts: NEWS bootstrap.conf cfg.mk lib/.gitignore --- cb9ec4fada480554cf47810fee736997d64e7427 diff --cc NEWS index fa1b948f,f940d8ed..bd47608b --- a/NEWS +++ b/NEWS @@@ -2,145 -2,9 +2,148 @@@ GNU Bison NEW * Noteworthy changes in release ?.? (????-??-??) [?] +** Incompatible changes + +*** Obsolete features + + Support for YYFAIL is removed, as announced since Bison 2.4.2. + Support for yystype and yyltype (instead of YYSTYPE and YYLTYPE) + is removed, as announced in Bison 1.875. + +** Warnings + +*** Warning categories are now displayed + + For instance: + + foo.y:4.6: warning: type clash on default action: != [-Wother] + +*** Useless semantic types + + Bison now warns about useless (uninhabited) semantic types. Since + semantic types are not declared to Bison (they are defined in the opaque + %union structure), it is %printer/%destructor directives about useless + types that trigger the warning: + + %token term + %type nterm + %printer {} + %destructor {} + %% + nterm: term { $$ = $1; }; + + 3.28-34: warning: type is used, but is not associated to any symbol + 4.28-34: warning: type is used, but is not associated to any symbol + +*** Undeclared symbols + + Bison used to raise an error for %printer and %destructor directives for + undefined symbols. + + %printer {} symbol1 + %destructor {} symbol2 + %% + exp: "a"; + + This is now only a warning. + +*** Useless destructors or printers + + Bison now warns about useless destructors or printers. In the following + example, the printer for , and the destructor for are + useless: all symbols of (token1) already have a printer, and all + symbols of type (token2) already have a destructor. + + %token token1 + token2 + token3 + token4 + %printer {} token1 + %destructor {} token2 + +** Additional yylex/yyparse arguments + + The new directive %param declares additional arguments to both yylex and + yyparse. The %lex-param, %parse-param, and %param directives support one + or more arguments. Instead of + + %lex-param {arg1_type *arg1} + %lex-param {arg2_type *arg2} + %parse-param {arg1_type *arg1} + %parse-param {arg2_type *arg2} + + one may now declare + + %param {arg1_type *arg1} {arg2_type *arg2} + +** Java skeleton improvements + + The constants for token names were moved to the Lexer interface. + Also, it is possible to add code to the parser's constructors using + "%code init" and "%define init_throws". + +** C++ skeletons improvements + +*** parser header (%defines) is no longer mandatory (lalr1.cc) + + In which case, if needed, the support classes are defined in the generated + parser, instead of additional files (location.hh, position.hh and + stack.hh). + +*** locations are no longer mandatory (lalr1.cc, glr.cc) + + Both lalr1.cc and glr.cc no longer require %location. + +*** syntax_error exception (lalr1.cc) + + The C++ parser features a syntax_error exception, which can be + thrown from the scanner or from user rules to raise syntax errors. + This facilitates reporting errors caught in sub-functions (e.g., + rejecting too large integral literals from a conversion function + used by the scanner, or rejecting invalid combinations from a + factory invoked by the user actions). + +** Variable api.tokens.prefix + + The variable api.tokens.prefix changes the way tokens are identified in + the generated files. This is especially useful to avoid collisions + with identifiers in the target language. For instance + + %token FILE for ERROR + %define api.tokens.prefix "TOK_" + %% + start: FILE for ERROR; + + will generate the definition of the symbols TOK_FILE, TOK_for, and + TOK_ERROR in the generated sources. In particular, the scanner must + use these prefixed token names, although the grammar itself still + uses the short names (as in the sample rule given above). + +** Variable api.namespace + + The "namespace" variable is renamed "api.namespace". Backward + compatibility is ensured, but upgrading is recommended. + +** Variable parse.error + + The variable error controls the verbosity of error messages. The + use of the %error-verbose directive is deprecated in favor of + %define parse.error "verbose". + +** Semantic predicates + + The new, experimental, semantic-predicate feature allows actions of + the form %?{ BOOLEAN-EXPRESSION }, which cause syntax errors (as for + YYERROR) if the expression evaluates to 0, and are evaluated immediately + in GLR parsers, rather than being deferred. The result is that they + allow the programmer to prune possible parses based on the values of + run-time expressions. + +* Noteworthy changes in release ?.? (????-??-??) [?] + + + * Noteworthy changes in release 2.6.1 (2012-07-30) [stable] + Bison no longer executes user-specified M4 code when processing a grammar. ** Future Changes diff --cc bootstrap.conf index 486268d7,165d5e7d..e90cf12d --- a/bootstrap.conf +++ b/bootstrap.conf @@@ -23,8 -23,11 +23,11 @@@ gnulib_modules= error extensions fdl fopen-safer getopt-gnu gettext git-version-gen gitlog-to-changelog gpl-3.0 hash inttypes isnan javacomp-script - javaexec-script ldexpl malloc-gnu mbschr mbsrchr + javaexec-script ldexpl malloc-gnu - mbswidth obstack perror progname + mbswidth + obstack + obstack-printf + perror progname quote quotearg readme-release realloc-posix diff --cc cfg.mk index f1caf313,53855aef..af1e09e8 --- a/cfg.mk +++ b/cfg.mk @@@ -64,9 -70,11 +64,11 @@@ $(call exclude, prohibit_always-defined_macros+=?|^src/(parse-gram.c|system.h)$$ \ prohibit_always-defined_macros+=?|^tests/regression.at$$ \ prohibit_defined_have_decl_tests=?|^lib/timevar.c$$ \ - prohibit_empty_lines_at_EOF=^src/parse-gram.[ch]$$ \ + prohibit_empty_lines_at_EOF=^src/parse-gram.h$$ \ + prohibit_magic_number_exit=^doc/bison.texi$$ \ + prohibit_magic_number_exit+=?|^tests/(conflicts|regression).at$$ \ + prohibit_strcmp=^doc/bison\.texi$$ \ require_config_h_first=^(lib/yyerror|data/(glr|yacc))\.c$$ \ space_tab=^tests/(input|c\+\+)\.at$$ \ - trailing_blank=^src/parse-gram.[ch]$$ \ unmarked_diagnostics=^(djgpp/|doc/bison.texi$$) \ ) diff --cc lib/.gitignore index 8e0e2096,964d7f45..a448e841 --- a/lib/.gitignore +++ b/lib/.gitignore @@@ -35,6 -35,6 +35,8 @@@ /close.c /closeout.c /closeout.h ++/concat-filename.c ++/concat-filename.h /config.charset /config.h /config.in.h @@@ -62,6 -62,6 +64,7 @@@ /fd-hook.h /fd-safer-flag.c /fd-safer.c ++/filename.h /float+.h /float.c /float.h @@@ -123,6 -125,6 +126,7 @@@ /nonblocking.h /obstack.c /obstack.h ++/obstack_printf.c /open.c /pathmax.h /perror.c @@@ -223,6 -225,6 +227,7 @@@ /sys_socket.in.h /sys_stat.h /sys_stat.in.h ++/sys_types.in.h /sys_wait.h /sys_wait.in.h /sysexits.in.h @@@ -259,14 -261,11 +264,10 @@@ /xalloc-die.c /xalloc-oversized.h /xalloc.h ++/xconcat-filename.c /xmalloc.c ++/xmemdup0.c ++/xmemdup0.h /xsize.h /xstrndup.c /xstrndup.h --/xmemdup0.c --/xmemdup0.h --/sys_types.in.h - /concat-filename.c - /concat-filename.h - /filename.h - /xconcat-filename.c -/obstack_printf.c diff --cc src/conflicts.c index ccd50ebf,ba0b6ed3..dad65683 --- a/src/conflicts.c +++ b/src/conflicts.c @@@ -70,69 -70,69 +70,69 @@@ log_resolution (rule *r, symbol_number { /* The description of the resolution. */ switch (resolution) - { - case shift_resolution: - case right_resolution: - obstack_printf (&solved_conflicts_obstack, - _(" Conflict between rule %d and token %s" - " resolved as shift"), - r->number, - symbols[token]->tag); - break; - - case reduce_resolution: - case left_resolution: - obstack_printf (&solved_conflicts_obstack, - _(" Conflict between rule %d and token %s" - " resolved as reduce"), - r->number, - symbols[token]->tag); - break; - - case nonassoc_resolution: - obstack_printf (&solved_conflicts_obstack, - _(" Conflict between rule %d and token %s" - " resolved as an error"), - r->number, - symbols[token]->tag); - break; - } + { + case shift_resolution: + case right_resolution: - obstack_fgrow2 (&solved_conflicts_obstack, ++ obstack_printf (&solved_conflicts_obstack, + _(" Conflict between rule %d and token %s" + " resolved as shift"), + r->number, + symbols[token]->tag); + break; + + case reduce_resolution: + case left_resolution: - obstack_fgrow2 (&solved_conflicts_obstack, ++ obstack_printf (&solved_conflicts_obstack, + _(" Conflict between rule %d and token %s" + " resolved as reduce"), + r->number, + symbols[token]->tag); + break; + + case nonassoc_resolution: - obstack_fgrow2 (&solved_conflicts_obstack, ++ obstack_printf (&solved_conflicts_obstack, + _(" Conflict between rule %d and token %s" + " resolved as an error"), + r->number, + symbols[token]->tag); + break; + } /* The reason. */ switch (resolution) - { - case shift_resolution: - obstack_printf (&solved_conflicts_obstack, - " (%s < %s)", - r->prec->tag, - symbols[token]->tag); - break; - - case reduce_resolution: - obstack_printf (&solved_conflicts_obstack, - " (%s < %s)", - symbols[token]->tag, - r->prec->tag); - break; - - case left_resolution: - obstack_printf (&solved_conflicts_obstack, - " (%%left %s)", - symbols[token]->tag); - break; - - case right_resolution: - obstack_printf (&solved_conflicts_obstack, - " (%%right %s)", - symbols[token]->tag); - break; - - case nonassoc_resolution: - obstack_printf (&solved_conflicts_obstack, - " (%%nonassoc %s)", - symbols[token]->tag); - break; - } + { + case shift_resolution: - obstack_fgrow2 (&solved_conflicts_obstack, ++ obstack_printf (&solved_conflicts_obstack, + " (%s < %s)", + r->prec->tag, + symbols[token]->tag); + break; + + case reduce_resolution: - obstack_fgrow2 (&solved_conflicts_obstack, ++ obstack_printf (&solved_conflicts_obstack, + " (%s < %s)", + symbols[token]->tag, + r->prec->tag); + break; + + case left_resolution: - obstack_fgrow1 (&solved_conflicts_obstack, ++ obstack_printf (&solved_conflicts_obstack, + " (%%left %s)", + symbols[token]->tag); + break; + + case right_resolution: - obstack_fgrow1 (&solved_conflicts_obstack, ++ obstack_printf (&solved_conflicts_obstack, + " (%%right %s)", + symbols[token]->tag); + break; + + case nonassoc_resolution: - obstack_fgrow1 (&solved_conflicts_obstack, ++ obstack_printf (&solved_conflicts_obstack, + " (%%nonassoc %s)", + symbols[token]->tag); + break; + } obstack_sgrow (&solved_conflicts_obstack, ".\n"); } diff --cc src/muscle-tab.c index 1168a9c3,bd1fd174..bb54bed7 --- a/src/muscle-tab.c +++ b/src/muscle-tab.c @@@ -268,12 -268,12 +268,12 @@@ muscle_boundary_grow (char const *key, char *extension; obstack_sgrow (&muscle_obstack, "[["); obstack_escape (&muscle_obstack, bound.file); - obstack_1grow (&muscle_obstack, ':'); + obstack_1grow (&muscle_obstack, ':'); - obstack_fgrow1 (&muscle_obstack, "%d", bound.line); + obstack_printf (&muscle_obstack, "%d", bound.line); - obstack_1grow (&muscle_obstack, '.'); + obstack_1grow (&muscle_obstack, '.'); - obstack_fgrow1 (&muscle_obstack, "%d", bound.column); + obstack_printf (&muscle_obstack, "%d", bound.column); obstack_sgrow (&muscle_obstack, "]]"); - obstack_1grow (&muscle_obstack, '\0'); + obstack_1grow (&muscle_obstack, '\0'); extension = obstack_finish (&muscle_obstack); muscle_grow (key, extension, ""); obstack_free (&muscle_obstack, extension); diff --cc src/output.c index c227be22,e77a2d1a..24bb83cd --- a/src/output.c +++ b/src/output.c @@@ -53,51 -54,51 +53,51 @@@ static struct obstack format_obstack `-------------------------------------------------------------------*/ -#define GENERATE_MUSCLE_INSERT_TABLE(Name, Type) \ - \ -static void \ -Name (char const *name, \ - Type *table_data, \ - Type first, \ - int begin, \ - int end) \ -{ \ - Type min = first; \ - Type max = first; \ - long int lmin; \ - long int lmax; \ - int i; \ - int j = 1; \ - \ - obstack_printf (&format_obstack, "%6d", first); \ - for (i = begin; i < end; ++i) \ - { \ - obstack_1grow (&format_obstack, ','); \ - if (j >= 10) \ - { \ - obstack_sgrow (&format_obstack, "\n "); \ - j = 1; \ - } \ - else \ - ++j; \ - obstack_printf (&format_obstack, "%6d", table_data[i]); \ - if (table_data[i] < min) \ - min = table_data[i]; \ - if (max < table_data[i]) \ - max = table_data[i]; \ - } \ - obstack_1grow (&format_obstack, 0); \ - muscle_insert (name, obstack_finish (&format_obstack)); \ - \ - lmin = min; \ - lmax = max; \ - /* Build `NAME_min' and `NAME_max' in the obstack. */ \ - obstack_printf (&format_obstack, "%s_min", name); \ - obstack_1grow (&format_obstack, 0); \ - MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), lmin); \ - obstack_printf (&format_obstack, "%s_max", name); \ - obstack_1grow (&format_obstack, 0); \ - MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), lmax); \ +#define GENERATE_MUSCLE_INSERT_TABLE(Name, Type) \ + \ +static void \ +Name (char const *name, \ + Type *table_data, \ + Type first, \ + int begin, \ + int end) \ +{ \ + Type min = first; \ + Type max = first; \ + long int lmin; \ + long int lmax; \ + int i; \ + int j = 1; \ + \ - obstack_fgrow1 (&format_obstack, "%6d", first); \ ++ obstack_printf (&format_obstack, "%6d", first); \ + for (i = begin; i < end; ++i) \ + { \ + obstack_1grow (&format_obstack, ','); \ + if (j >= 10) \ + { \ + obstack_sgrow (&format_obstack, "\n "); \ + j = 1; \ + } \ + else \ + ++j; \ - obstack_fgrow1 (&format_obstack, "%6d", table_data[i]); \ ++ obstack_printf (&format_obstack, "%6d", table_data[i]); \ + if (table_data[i] < min) \ + min = table_data[i]; \ + if (max < table_data[i]) \ + max = table_data[i]; \ + } \ + obstack_1grow (&format_obstack, 0); \ + muscle_insert (name, obstack_finish (&format_obstack)); \ + \ + lmin = min; \ + lmax = max; \ + /* Build `NAME_min' and `NAME_max' in the obstack. */ \ - obstack_fgrow1 (&format_obstack, "%s_min", name); \ ++ obstack_printf (&format_obstack, "%s_min", name); \ + obstack_1grow (&format_obstack, 0); \ + MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), lmin); \ - obstack_fgrow1 (&format_obstack, "%s_max", name); \ ++ obstack_printf (&format_obstack, "%s_max", name); \ + obstack_1grow (&format_obstack, 0); \ + MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), lmax); \ } GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_unsigned_int_table, unsigned int) @@@ -394,88 -338,96 +394,88 @@@ merger_output (FILE *out fputs ("]])\n\n", out); } -/*--------------------------------------. -| Output the tokens definition to OUT. | -`--------------------------------------*/ + +/*---------------------------------------------. +| Prepare the muscles for symbol definitions. | +`---------------------------------------------*/ static void -token_definitions_output (FILE *out) +prepare_symbol_definitions (void) { int i; - char const *sep = ""; - - fputs ("m4_define([b4_tokens], \n[", out); - for (i = 0; i < ntokens; ++i) + for (i = 0; i < nsyms; ++i) { symbol *sym = symbols[i]; - int number = sym->user_token_number; - - /* At this stage, if there are literal string aliases, they are - part of SYMBOLS, so we should not find their aliased symbols - here. */ - aver (number != USER_NUMBER_HAS_STRING_ALIAS); - - /* Skip error token. */ - if (sym == errtoken) - continue; - - /* If this string has an alias, then it is necessarily the alias - which is to be output. */ - if (sym->alias) - sym = sym->alias; - - /* Don't output literal chars or strings (when defined only as a - string). Note that must be done after the alias resolution: - think about `%token 'f' "f"'. */ - if (sym->tag[0] == '\'' || sym->tag[0] == '\"') - continue; - - /* Don't #define nonliteral tokens whose names contain periods, - dashes or '$' (as does the default value of the EOF token). */ - if (mbschr (sym->tag, '.') - || mbschr (sym->tag, '-') - || mbschr (sym->tag, '$')) - continue; - - fprintf (out, "%s[[[%s]], %d]", - sep, sym->tag, number); - sep = ",\n"; - } - fputs ("])\n\n", out); -} + const char *key; + const char *value; +#define SET_KEY(Entry) \ - obstack_fgrow2 (&format_obstack, "symbol(%d, %s)", \ ++ obstack_printf (&format_obstack, "symbol(%d, %s)", \ + i, Entry); \ + obstack_1grow (&format_obstack, 0); \ + key = obstack_finish (&format_obstack); -/*---------------------------------------------------. -| Output the symbol destructors or printers to OUT. | -`---------------------------------------------------*/ +#define SET_KEY2(Entry, Suffix) \ - obstack_fgrow3 (&format_obstack, "symbol(%d, %s_%s)", \ ++ obstack_printf (&format_obstack, "symbol(%d, %s_%s)", \ + i, Entry, Suffix); \ + obstack_1grow (&format_obstack, 0); \ + key = obstack_finish (&format_obstack); -static void -symbol_code_props_output (FILE *out, char const *what, - code_props const *(*get)(symbol const *)) -{ - int i; - char const *sep = ""; + // Whether the symbol has an identifier. + value = symbol_id_get (sym); + SET_KEY("has_id"); + MUSCLE_INSERT_INT (key, !!value); - fputs ("m4_define([b4_symbol_", out); - fputs (what, out); - fputs ("], \n[", out); - for (i = 0; i < nsyms; ++i) - { - symbol *sym = symbols[i]; - char const *code = (*get) (sym)->code; - if (code) - { - location loc = (*get) (sym)->location; - /* Filename, lineno, - Symbol-name, Symbol-number, - code, optional typename. */ - fprintf (out, "%s[", sep); - sep = ",\n"; - string_output (out, loc.start.file); - fprintf (out, ", %d, ", loc.start.line); - quoted_output (out, sym->tag); - fprintf (out, ", %d, [[%s]]", sym->number, code); - if (sym->type_name) - { - fputs (", ", out); - quoted_output (out, sym->type_name); - } - fputc (']', out); - } + // Its identifier. + SET_KEY("id"); + MUSCLE_INSERT_STRING (key, value ? value : ""); + + // Its tag. Typically for documentation purpose. + SET_KEY("tag"); + MUSCLE_INSERT_STRING (key, sym->tag); + + SET_KEY("user_number"); + MUSCLE_INSERT_INT (key, sym->user_token_number); + + SET_KEY("is_token"); + MUSCLE_INSERT_INT (key, + i < ntokens && sym != errtoken && sym != undeftoken); + + SET_KEY("number"); + MUSCLE_INSERT_INT (key, sym->number); + + SET_KEY("has_type"); + MUSCLE_INSERT_INT (key, !!sym->type_name); + + SET_KEY("type"); + MUSCLE_INSERT_STRING (key, sym->type_name ? sym->type_name : ""); + + { + int j; + for (j = 0; j < CODE_PROPS_SIZE; ++j) + { + /* "printer", not "%printer". */ + char const *pname = code_props_type_string (j) + 1; + code_props const *p = symbol_code_props_get (sym, j); + SET_KEY2("has", pname); + MUSCLE_INSERT_INT (key, !!p->code); + + if (p->code) + { + SET_KEY2(pname, "file"); + MUSCLE_INSERT_STRING (key, p->location.start.file); + + SET_KEY2(pname, "line"); + MUSCLE_INSERT_INT (key, p->location.start.line); + + SET_KEY(pname); + MUSCLE_INSERT_STRING_RAW (key, p->code); + } + } + } +#undef SET_KEY2 +#undef SET_KEY } - fputs ("])\n\n", out); } diff --cc src/print_graph.c index 61d36512,f5695a7a..d37afb2c --- a/src/print_graph.c +++ b/src/print_graph.c @@@ -68,39 -68,39 +68,39 @@@ print_core (struct obstack *oout, stat r = item_number_as_rule_number (*sp); - obstack_fgrow1 (oout, "\n%s -> ", rules[r].lhs->tag); + obstack_printf (oout, "\n%s -> ", rules[r].lhs->tag); for (sp = rules[r].rhs; sp < sp1; sp++) - obstack_fgrow1 (oout, "%s ", symbols[*sp]->tag); - obstack_printf (oout, "%s ", symbols[*sp]->tag); ++ obstack_printf (oout, "%s ", symbols[*sp]->tag); obstack_1grow (oout, '.'); for (/* Nothing */; *sp >= 0; ++sp) - obstack_fgrow1 (oout, " %s", symbols[*sp]->tag); - obstack_printf (oout, " %s", symbols[*sp]->tag); ++ obstack_printf (oout, " %s", symbols[*sp]->tag); /* Experimental feature: display the lookahead tokens. */ if (report_flag & report_lookahead_tokens && item_number_is_rule_number (*sp1)) - { - /* Find the reduction we are handling. */ - reductions *reds = s->reductions; - int redno = state_reduction_find (s, &rules[r]); - - /* Print them if there are. */ - if (reds->lookahead_tokens && redno != -1) - { - bitset_iterator biter; - int k; - char const *sep = ""; - obstack_sgrow (oout, "["); - BITSET_FOR_EACH (biter, reds->lookahead_tokens[redno], k, 0) - { - obstack_printf (oout, "%s%s", sep, symbols[k]->tag); - sep = ", "; - } - obstack_sgrow (oout, "]"); - } - } + { + /* Find the reduction we are handling. */ + reductions *reds = s->reductions; + int redno = state_reduction_find (s, &rules[r]); + + /* Print them if there are. */ + if (reds->lookahead_tokens && redno != -1) + { + bitset_iterator biter; + int k; + char const *sep = ""; + obstack_sgrow (oout, "["); + BITSET_FOR_EACH (biter, reds->lookahead_tokens[redno], k, 0) + { - obstack_fgrow2 (oout, "%s%s", sep, symbols[k]->tag); ++ obstack_printf (oout, "%s%s", sep, symbols[k]->tag); + sep = ", "; + } + obstack_sgrow (oout, "]"); + } + } } } diff --cc src/scan-code.l index 2fe880ed,fa593beb..83501475 --- a/src/scan-code.l +++ b/src/scan-code.l @@@ -414,62 -424,60 +414,62 @@@ show_sub_messages (const char* cp, boo if (var->err == 0) { if (is_warning) - warn_at_indent (var->loc, &indent, _("refers to: %c%s at %s"), - dollar_or_at, var->id, at_spec); + complain_at_indent (var->loc, Wother, &indent, + _("refers to: %c%s at %s"), dollar_or_at, + var->id, at_spec); else - complain_at_indent (var->loc, &indent, _("refers to: %c%s at %s"), - dollar_or_at, var->id, at_spec); + complain_at_indent (var->loc, complaint, &indent, + _("refers to: %c%s at %s"), dollar_or_at, + var->id, at_spec); } else - { - static struct obstack msg_buf; - const char *tail = explicit_bracketing ? "" : - cp + strlen (var->id); - const char *id = var->hidden_by ? var->hidden_by->id : - var->id; - location id_loc = var->hidden_by ? var->hidden_by->loc : - var->loc; - - /* Create the explanation message. */ - obstack_init (&msg_buf); - - obstack_printf (&msg_buf, _("possibly meant: %c"), dollar_or_at); - if (contains_dot_or_dash (id)) - obstack_printf (&msg_buf, "[%s]", id); - else - obstack_sgrow (&msg_buf, id); - obstack_sgrow (&msg_buf, tail); - - if (var->err & VARIANT_HIDDEN) - { - obstack_printf (&msg_buf, _(", hiding %c"), dollar_or_at); - if (contains_dot_or_dash (var->id)) - obstack_printf (&msg_buf, "[%s]", var->id); - else - obstack_sgrow (&msg_buf, var->id); - obstack_sgrow (&msg_buf, tail); - } - - obstack_printf (&msg_buf, _(" at %s"), at_spec); - - if (var->err & VARIANT_NOT_VISIBLE_FROM_MIDRULE) + { + static struct obstack msg_buf; + const char *tail = explicit_bracketing ? "" : + cp + strlen (var->id); + const char *id = var->hidden_by ? var->hidden_by->id : + var->id; + location id_loc = var->hidden_by ? var->hidden_by->loc : + var->loc; + + /* Create the explanation message. */ + obstack_init (&msg_buf); + - obstack_fgrow1 (&msg_buf, _("possibly meant: %c"), dollar_or_at); ++ obstack_printf (&msg_buf, _("possibly meant: %c"), dollar_or_at); + if (contains_dot_or_dash (id)) - obstack_fgrow1 (&msg_buf, "[%s]", id); ++ obstack_printf (&msg_buf, "[%s]", id); + else + obstack_sgrow (&msg_buf, id); + obstack_sgrow (&msg_buf, tail); + + if (var->err & VARIANT_HIDDEN) + { - obstack_fgrow1 (&msg_buf, _(", hiding %c"), dollar_or_at); ++ obstack_printf (&msg_buf, _(", hiding %c"), dollar_or_at); + if (contains_dot_or_dash (var->id)) - obstack_fgrow1 (&msg_buf, "[%s]", var->id); ++ obstack_printf (&msg_buf, "[%s]", var->id); + else + obstack_sgrow (&msg_buf, var->id); + obstack_sgrow (&msg_buf, tail); + } + - obstack_fgrow1 (&msg_buf, _(" at %s"), at_spec); ++ obstack_printf (&msg_buf, _(" at %s"), at_spec); + + if (var->err & VARIANT_NOT_VISIBLE_FROM_MIDRULE) { const char *format = _(", cannot be accessed from mid-rule action at $%d"); - obstack_fgrow1 (&msg_buf, format, midrule_rhs_index); + obstack_printf (&msg_buf, format, midrule_rhs_index); } - obstack_1grow (&msg_buf, '\0'); + obstack_1grow (&msg_buf, '\0'); if (is_warning) - warn_at_indent (id_loc, &indent, "%s", - (char *) obstack_finish (&msg_buf)); + complain_at_indent (id_loc, Wother, &indent, "%s", + (char *) obstack_finish (&msg_buf)); else - complain_at_indent (id_loc, &indent, "%s", + complain_at_indent (id_loc, complaint, &indent, "%s", (char *) obstack_finish (&msg_buf)); - obstack_free (&msg_buf, 0); - } + obstack_free (&msg_buf, 0); + } } } @@@ -784,8 -788,8 +784,8 @@@ handle_action_dollar (symbol_list *rule untyped_var_seen = true; } - obstack_fgrow2 (&obstack_for_string, + obstack_printf (&obstack_for_string, - "]b4_rhs_value(%d, %d, ", effective_rule_length, n); + "]b4_rhs_value(%d, %d, ", effective_rule_length, n); obstack_quote (&obstack_for_string, type_name); obstack_sgrow (&obstack_for_string, ")["); if (n > 0) @@@ -834,8 -838,8 +834,8 @@@ handle_action_at (symbol_list *rule, ch break; default: - obstack_fgrow2 (&obstack_for_string, "]b4_rhs_location(%d, %d)[", + obstack_printf (&obstack_for_string, "]b4_rhs_location(%d, %d)[", - effective_rule_length, n); + effective_rule_length, n); break; } } diff --cc src/scan-skel.l index b79e5832,ed61b5c8..32bfe737 --- a/src/scan-skel.l +++ b/src/scan-skel.l @@@ -87,11 -87,11 +87,11 @@@ static void fail_for_invalid_at (char c } /* This pattern must not match more than the previous @ patterns. */ -@[^@{}`(\n]* fail_for_invalid_at (yytext); -\n out_lineno++; ECHO; -[^@\n]+ ECHO; +@[^@{}`(\n]* fail_for_invalid_at (yytext); +\n out_lineno++; ECHO; +[^@\n]+ ECHO; - <> { + <> { if (outname) { free (outname); diff --cc src/system.h index 1d0af8fa,1ae6a6b4..a56c058a --- a/src/system.h +++ b/src/system.h @@@ -169,42 -156,13 +169,13 @@@ typedef size_t uintptr_t | Obstacks. | `-----------*/ -# define obstack_chunk_alloc xmalloc -# define obstack_chunk_free free -# include +#define obstack_chunk_alloc xmalloc +#define obstack_chunk_free free +#include -# define obstack_sgrow(Obs, Str) \ +#define obstack_sgrow(Obs, Str) \ obstack_grow (Obs, Str, strlen (Str)) - #define obstack_fgrow1(Obs, Format, Arg1) \ - do { \ - char buf[4096]; \ - sprintf (buf, Format, Arg1); \ - obstack_grow (Obs, buf, strlen (buf)); \ - } while (0) - - #define obstack_fgrow2(Obs, Format, Arg1, Arg2) \ - do { \ - char buf[4096]; \ - sprintf (buf, Format, Arg1, Arg2); \ - obstack_grow (Obs, buf, strlen (buf)); \ - } while (0) - - #define obstack_fgrow3(Obs, Format, Arg1, Arg2, Arg3) \ - do { \ - char buf[4096]; \ - sprintf (buf, Format, Arg1, Arg2, Arg3); \ - obstack_grow (Obs, buf, strlen (buf)); \ - } while (0) - - #define obstack_fgrow4(Obs, Format, Arg1, Arg2, Arg3, Arg4) \ - do { \ - char buf[4096]; \ - sprintf (buf, Format, Arg1, Arg2, Arg3, Arg4); \ - obstack_grow (Obs, buf, strlen (buf)); \ - } while (0) - - /* Output Str escaped for our postprocessing (i.e., escape M4 special characters).