From: Akim Demaille Date: Thu, 11 Apr 2013 07:21:08 +0000 (+0200) Subject: muscles: be sure that %code snippets are not glue together on a single line X-Git-Tag: v2.7.90~35 X-Git-Url: https://git.saurik.com/bison.git/commitdiff_plain/08cc1a3b1801cafcd0354ce10161571fa45b4553?ds=inline muscles: be sure that %code snippets are not glue together on a single line Recently "braceless" in the parser was changed so that an eol was no longer added to the value. This is not correct when a %code is used multiple times, because the syncline of the next snippet might be appended to the last (and not ended) line of the previous snippet. * src/muscle-tab.h (muscle_grow): Make it private. * src/muscle-tab.c (muscle_grow): Accept a fourth argument: a required terminator. Adjust callers. * tests/input.at (Multiple %code): New. --- diff --git a/src/muscle-tab.c b/src/muscle-tab.c index 10a0a5cb..9d15cf76 100644 --- a/src/muscle-tab.c +++ b/src/muscle-tab.c @@ -153,33 +153,39 @@ muscle_insert (char const *key, char const *value) } -/*-------------------------------------------------------------------. -| Append VALUE to the current value of KEY. If KEY did not already | -| exist, create it. Use MUSCLE_OBSTACK. De-allocate the previously | -| associated value. Copy VALUE and SEPARATOR. | -`-------------------------------------------------------------------*/ +/* Append VALUE to the current value of KEY. If KEY did not already + exist, create it. Use MUSCLE_OBSTACK. De-allocate the previously + associated value. Copy VALUE and SEPARATOR. If VALUE does not end + with TERMINATOR, append one. */ -void -muscle_grow (const char *key, const char *val, const char *separator) +static void +muscle_grow (const char *key, const char *val, + const char *separator, const char *terminator) { muscle_entry *entry = muscle_lookup (key); + size_t vals = strlen (val); + size_t terms = strlen (terminator); if (entry) { - /* Grow the current value. */ - char *new_val; - obstack_printf (&muscle_obstack, "%s%s%s", entry->value, separator, val); + obstack_sgrow (&muscle_obstack, entry->value); + obstack_sgrow (&muscle_obstack, separator); free (entry->storage); - new_val = obstack_finish0 (&muscle_obstack); - entry->value = entry->storage = xstrdup (new_val); - obstack_free (&muscle_obstack, new_val); } else - { - /* First insertion in the hash. */ - entry = muscle_entry_new (key); - entry->value = entry->storage = xstrdup (val); - } + entry = muscle_entry_new (key); + + obstack_sgrow (&muscle_obstack, val); + + if (terms <= vals + && STRNEQ (val + vals - terms, terminator)) + obstack_sgrow (&muscle_obstack, terminator); + + { + char *new_val = obstack_finish0 (&muscle_obstack); + entry->value = entry->storage = xstrdup (new_val); + obstack_free (&muscle_obstack, new_val); + } } /*------------------------------------------------------------------. @@ -196,7 +202,7 @@ muscle_syncline_grow (char const *key, location loc) quotearg_style (c_quoting_style, loc.start.file)); obstack_sgrow (&muscle_obstack, ")["); extension = obstack_finish0 (&muscle_obstack); - muscle_grow (key, extension, ""); + muscle_grow (key, extension, "", ""); obstack_free (&muscle_obstack, extension); } @@ -210,7 +216,7 @@ void muscle_code_grow (const char *key, const char *val, location loc) { muscle_syncline_grow (key, loc); - muscle_grow (key, val, "\n"); + muscle_grow (key, val, "\n", "\n"); } @@ -225,7 +231,7 @@ muscle_pair_list_grow (const char *muscle, obstack_quote (&muscle_obstack, a2); obstack_sgrow (&muscle_obstack, "]"); pair = obstack_finish0 (&muscle_obstack); - muscle_grow (muscle, pair, ",\n"); + muscle_grow (muscle, pair, ",\n", ""); obstack_free (&muscle_obstack, pair); } @@ -262,7 +268,7 @@ muscle_boundary_grow (char const *key, boundary bound) obstack_escape (&muscle_obstack, bound.file); obstack_printf (&muscle_obstack, ":%d.%d]]", bound.line, bound.column); extension = obstack_finish0 (&muscle_obstack); - muscle_grow (key, extension, ""); + muscle_grow (key, extension, "", ""); obstack_free (&muscle_obstack, extension); } @@ -275,7 +281,7 @@ static void muscle_location_grow (char const *key, location loc) { muscle_boundary_grow (key, loc.start); - muscle_grow (key, "", ", "); + muscle_grow (key, "", ", ", ""); muscle_boundary_grow (key, loc.end); } @@ -374,11 +380,11 @@ void muscle_user_name_list_grow (char const *key, char const *user_name, location loc) { - muscle_grow (key, "[[[[", ","); - muscle_grow (key, user_name, ""); - muscle_grow (key, "]], ", ""); + muscle_grow (key, "[[[[", ",", ""); + muscle_grow (key, user_name, "", ""); + muscle_grow (key, "]], ", "", ""); muscle_location_grow (key, loc); - muscle_grow (key, "]]", ""); + muscle_grow (key, "]]", "", ""); } diff --git a/src/muscle-tab.h b/src/muscle-tab.h index af6b615c..3199a2d4 100644 --- a/src/muscle-tab.h +++ b/src/muscle-tab.h @@ -99,14 +99,9 @@ extern struct obstack muscle_obstack; MUSCLE_INSERT_STRING(Key, quotearg_style (c_quoting_style, Value)) -/* Append VALUE to the current value of KEY. If KEY did not already - exist, create it. Use MUSCLE_OBSTACK. De-allocate the previously - associated value. Copy VALUE and SEPARATOR. */ -void muscle_grow (const char *key, const char *value, const char *separator); - - /* Append VALUE to the current value of KEY, using muscle_grow. But - in addition, issue a synchronization line for the location LOC. */ + in addition, issue a synchronization line for the location LOC. + Be sure to append on a new line. */ void muscle_code_grow (const char *key, const char *value, location loc); diff --git a/tests/input.at b/tests/input.at index 322bbe87..aec855d7 100644 --- a/tests/input.at +++ b/tests/input.at @@ -1274,6 +1274,45 @@ special-char-@:>@.y:3.7: error: %code qualifier 'q' is not used AT_CLEANUP +## ---------------- ## +## Multiple %code. ## +## ---------------- ## + +AT_SETUP([Multiple %code]) + +# Make sure that repeated arguments to %code are separated by +# end-of-lines. At some point, a missing eol would leave synclines +# appended to the previous value. Here, we use CPP directive to +# introduce dependency on the absence/presence of the eol. +AT_BISON_OPTION_PUSHDEFS + +AT_DATA([input.y], +[[%code {#include } +%code {#define A B} +%code {#define B C} +%code {#define C D} +%code {#define D 42} +%code { + ]AT_YYERROR_DECLARE[ + ]AT_YYLEX_DECLARE[ +} +%% +start: %empty; +%% +]AT_YYERROR_DEFINE[ +]AT_YYLEX_DEFINE[ +int main (void) +{ + assert (A == 42); + return 0; +} +]]) +AT_FULL_COMPILE([input]) +AT_PARSER_CHECK([./input]) + +AT_BISON_OPTION_POPDEFS +AT_CLEANUP() + ## ---------------- ## ## %define errors. ## ## ---------------- ##