]> git.saurik.com Git - bison.git/blobdiff - src/muscle-tab.c
muscles: be sure that %code snippets are not glue together on a single line
[bison.git] / src / muscle-tab.c
index 4d5dd0acfb504bf2f925a5e15380c8571dea0d88..9d15cf768dbd53414bc97c94ee585b31a5a16484 100644 (file)
 #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);
 }