X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/36a17b50b5b88fcc90d574adb13567ba65755116..08cc1a3b1801cafcd0354ce10161571fa45b4553:/src/muscle-tab.c diff --git a/src/muscle-tab.c b/src/muscle-tab.c index 4d5dd0ac..9d15cf76 100644 --- a/src/muscle-tab.c +++ b/src/muscle-tab.c @@ -28,6 +28,31 @@ #include "muscle-tab.h" #include "quote.h" +muscle_kind +muscle_kind_new (char const *k) +{ + if (STREQ (k, "code")) + return muscle_code; + else if (STREQ (k, "keyword")) + return muscle_keyword; + else if (STREQ (k, "string")) + return muscle_string; + aver (0); +} + +char const * +muscle_kind_string (muscle_kind k) +{ + switch (k) + { + case muscle_code: return "code"; + case muscle_keyword: return "keyword"; + case muscle_string: return "string"; + } + aver (0); +} + + /* A key-value pair, along with storage that can be reclaimed when this pair is no longer needed. */ typedef struct @@ -35,6 +60,7 @@ typedef struct char const *key; char const *value; char *storage; + muscle_kind kind; } muscle_entry; /* An obstack used to create some entries. */ @@ -127,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); + } } /*------------------------------------------------------------------. @@ -170,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); } @@ -184,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"); } @@ -199,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); } @@ -236,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); } @@ -249,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); } @@ -348,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, "]]", "", ""); } @@ -446,6 +478,7 @@ muscle_percent_variable_update (char const *variable, location variable_loc, void muscle_percent_define_insert (char const *var, location variable_loc, + muscle_kind kind, char const *value, muscle_percent_define_how how) { @@ -456,6 +489,8 @@ muscle_percent_define_insert (char const *var, location variable_loc, char const *syncline_name = UNIQSTR_CONCAT ("percent_define_syncline(", variable, ")"); char const *how_name = UNIQSTR_CONCAT ("percent_define_how(", variable, ")"); + char const *kind_name = + UNIQSTR_CONCAT ("percent_define_kind(", variable, ")"); /* Command-line options are processed before the grammar file. */ if (how == MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE @@ -481,6 +516,7 @@ muscle_percent_define_insert (char const *var, location variable_loc, muscle_user_name_list_grow ("percent_define_user_variables", variable, variable_loc); MUSCLE_INSERT_INT (how_name, how); + MUSCLE_INSERT_STRING (kind_name, muscle_kind_string (kind)); end: free (variable); } @@ -497,10 +533,10 @@ muscle_percent_define_ensure (char const *variable, location loc, /* Don't complain is VARIABLE is already defined, but be sure to set its value to VAL. */ if (!muscle_find_const (name)) - muscle_percent_define_insert (variable, loc, val, + muscle_percent_define_insert (variable, loc, muscle_keyword, val, MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE); if (muscle_percent_define_flag_if (variable) != value) - muscle_percent_define_insert (variable, loc, val, + muscle_percent_define_insert (variable, loc, muscle_keyword, val, MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE); }