Minor code cleanup.
authorJoel E. Denny <jdenny@clemson.edu>
Thu, 8 Oct 2009 03:09:43 +0000 (23:09 -0400)
committerJoel E. Denny <jdenny@clemson.edu>
Thu, 8 Oct 2009 05:54:31 +0000 (01:54 -0400)
* src/muscle_tab.c (MUSCLE_USER_NAME_CONVERT): Remove macro and
replace all uses with UNIQSTR_CONCAT.
* src/uniqstr.c (uniqstr_vsprintf): New function.
* src/uniqstr.h (uniqstr_vsprintf): Add prototype.
(UNIQSTR_CONCAT, UNIQSTR_GEN_FORMAT, UNIQSTR_GEN_FORMAT_): New
macros.
(cherry picked from commit 10659d0ec997368fe57712a7c564795c530ba0c2)

Conflicts:

src/muscle_tab.c

ChangeLog
src/muscle_tab.c
src/uniqstr.c
src/uniqstr.h

index a5b3520..004ba41 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2009-10-07  Joel E. Denny  <jdenny@clemson.edu>
+
+       Minor code cleanup.
+       * src/muscle_tab.c (MUSCLE_USER_NAME_CONVERT): Remove macro and
+       replace all uses with UNIQSTR_CONCAT.
+       * src/uniqstr.c (uniqstr_vsprintf): New function.
+       * src/uniqstr.h (uniqstr_vsprintf): Add prototype.
+       (UNIQSTR_CONCAT, UNIQSTR_GEN_FORMAT, UNIQSTR_GEN_FORMAT_): New
+       macros.
+
 2009-10-04  Joel E. Denny  <jdenny@clemson.edu>
 
        Minor code cleanup.
index c25b519..e75ceef 100644 (file)
@@ -389,18 +389,6 @@ muscle_user_name_list_grow (char const *key, char const *user_name,
   muscle_grow (key, "]]", "");
 }
 
-#define MUSCLE_USER_NAME_CONVERT(NAME, PREFIX, USER_NAME, SUFFIX)    \
-do {                                                                 \
-  char *tmp;                                                         \
-  size_t length = strlen ((USER_NAME));                              \
-  tmp = xmalloc (sizeof (PREFIX) - 1 + length + sizeof (SUFFIX));    \
-  strcpy (tmp, (PREFIX));                                            \
-  strcpy (tmp + sizeof (PREFIX) - 1, (USER_NAME));                   \
-  strcpy (tmp + sizeof (PREFIX) - 1 + length, (SUFFIX));             \
-  (NAME) = uniqstr_new (tmp);                                        \
-  free (tmp);                                                        \
-} while (0)
-
 void
 muscle_percent_define_insert (char const *variable, location variable_loc,
                               char const *value,
@@ -421,11 +409,11 @@ muscle_percent_define_insert (char const *variable, location variable_loc,
       variable = variable_tr;
     }
 
-  MUSCLE_USER_NAME_CONVERT (name, "percent_define(", variable, ")");
-  MUSCLE_USER_NAME_CONVERT (loc_name, "percent_define_loc(", variable, ")");
-  MUSCLE_USER_NAME_CONVERT (syncline_name,
-                            "percent_define_syncline(", variable, ")");
-  MUSCLE_USER_NAME_CONVERT (how_name, "percent_define_how(", variable, ")");
+  name = UNIQSTR_CONCAT ("percent_define(", variable, ")");
+  loc_name = UNIQSTR_CONCAT ("percent_define_loc(", variable, ")");
+  syncline_name =
+    UNIQSTR_CONCAT ("percent_define_syncline(", variable, ")");
+  how_name = UNIQSTR_CONCAT ("percent_define_how(", variable, ")");
 
   /* Command-line options are processed before the grammar file.  */
   if (how == MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE
@@ -463,9 +451,9 @@ muscle_percent_define_get (char const *variable)
   char const *usage_name;
   char *value;
 
-  MUSCLE_USER_NAME_CONVERT (name, "percent_define(", variable, ")");
-  MUSCLE_USER_NAME_CONVERT (usage_name, "percent_define_bison_variables(",
-                            variable, ")");
+  name = UNIQSTR_CONCAT ("percent_define(", variable, ")");
+  usage_name = UNIQSTR_CONCAT ("percent_define_bison_variables(",
+                               variable, ")");
 
   muscle_insert (usage_name, "");
   value = muscle_string_decode (name);
@@ -478,10 +466,10 @@ location
 muscle_percent_define_get_loc (char const *variable)
 {
   char const *loc_name;
-  MUSCLE_USER_NAME_CONVERT (loc_name, "percent_define_loc(", variable, ")");
+  loc_name = UNIQSTR_CONCAT ("percent_define_loc(", variable, ")");
   if (!muscle_find_const (loc_name))
-    fatal(_("undefined %%define variable `%s' passed to muscle_percent_define_get_loc"),
-          variable);
+    fatal(_("undefined %%define variable `%s' passed to"
+            " muscle_percent_define_get_loc"), variable);
   return muscle_location_decode (loc_name);
 }
 
@@ -490,12 +478,12 @@ muscle_percent_define_get_syncline (char const *variable)
 {
   char const *syncline_name;
   char const *syncline;
-  MUSCLE_USER_NAME_CONVERT (syncline_name,
-                            "percent_define_syncline(", variable, ")");
+  syncline_name =
+    UNIQSTR_CONCAT ("percent_define_syncline(", variable, ")");
   syncline = muscle_find_const (syncline_name);
   if (!syncline)
-    fatal(_("undefined %%define variable `%s' passed to muscle_percent_define_get_syncline"),
-          variable);
+    fatal(_("undefined %%define variable `%s' passed to"
+            " muscle_percent_define_get_syncline"), variable);
   return syncline;
 }
 
@@ -506,9 +494,9 @@ muscle_percent_define_ifdef (char const *variable)
   char const *usage_name;
   char const *value;
 
-  MUSCLE_USER_NAME_CONVERT (name, "percent_define(", variable, ")");
-  MUSCLE_USER_NAME_CONVERT (usage_name, "percent_define_bison_variables(",
-                            variable, ")");
+  name = UNIQSTR_CONCAT ("percent_define(", variable, ")");
+  usage_name =
+    UNIQSTR_CONCAT ("percent_define_bison_variables(", variable, ")");
 
   value = muscle_find_const (name);
   if (value)
@@ -526,8 +514,8 @@ muscle_percent_define_flag_if (char const *variable)
   char const *invalid_boolean_name;
   bool result = false;
 
-  MUSCLE_USER_NAME_CONVERT (invalid_boolean_name,
-                            "percent_define_invalid_boolean(", variable, ")");
+  invalid_boolean_name =
+    UNIQSTR_CONCAT ("percent_define_invalid_boolean(", variable, ")");
 
   if (muscle_percent_define_ifdef (variable))
     {
@@ -558,10 +546,10 @@ muscle_percent_define_default (char const *variable, char const *value)
   char const *name;
   char const *loc_name;
   char const *syncline_name;
-  MUSCLE_USER_NAME_CONVERT (name, "percent_define(", variable, ")");
-  MUSCLE_USER_NAME_CONVERT (loc_name, "percent_define_loc(", variable, ")");
-  MUSCLE_USER_NAME_CONVERT (syncline_name,
-                            "percent_define_syncline(", variable, ")");
+  name = UNIQSTR_CONCAT ("percent_define(", variable, ")");
+  loc_name = UNIQSTR_CONCAT ("percent_define_loc(", variable, ")");
+  syncline_name =
+    UNIQSTR_CONCAT ("percent_define_syncline(", variable, ")");
   if (!muscle_find_const (name))
     {
       location loc;
@@ -584,7 +572,7 @@ muscle_percent_define_check_values (char const * const *values)
       char const *name;
       char *value;
 
-      MUSCLE_USER_NAME_CONVERT (name, "percent_define(", *variablep, ")");
+      name = UNIQSTR_CONCAT ("percent_define(", *variablep, ")");
 
       value = muscle_string_decode (name);
       if (value)
@@ -622,7 +610,7 @@ muscle_percent_code_grow (char const *qualifier, location qualifier_loc,
                           char const *code, location code_loc)
 {
   char const *name;
-  MUSCLE_USER_NAME_CONVERT (name, "percent_code(", qualifier, ")");
+  name = UNIQSTR_CONCAT ("percent_code(", qualifier, ")");
   muscle_code_grow (name, code, code_loc);
   muscle_user_name_list_grow ("percent_code_user_qualifiers", qualifier,
                                qualifier_loc);
index 78b8a98..ed8f79a 100644 (file)
@@ -23,6 +23,7 @@
 #include <error.h>
 #include <hash.h>
 #include <quotearg.h>
+#include <stdarg.h>
 
 #include "uniqstr.h"
 
@@ -53,6 +54,21 @@ uniqstr_new (char const *str)
   return res;
 }
 
+uniqstr
+uniqstr_vsprintf (char const *format, ...)
+{
+  va_list args;
+  size_t length;
+  va_start (args, format);
+  length = vsnprintf (NULL, 0, format, args);
+  va_end (args);
+
+  char res[length + 1];
+  va_start (args, format);
+  vsprintf (res, format, args);
+  va_end (args);
+  return uniqstr_new (res);
+}
 
 /*------------------------------.
 | Abort if S is not a uniqstr.  |
index 04600e9..2f9fce0 100644 (file)
@@ -29,6 +29,12 @@ typedef char const *uniqstr;
 /* Return the uniqstr for STR.  */
 uniqstr uniqstr_new (char const *str);
 
+/* Return a uniqstr built by vsprintf.  In order to simply concatenate
+   strings, use UNIQSTR_CONCAT, which is a convenient wrapper around
+   this function.  */
+uniqstr uniqstr_vsprintf (char const *format, ...)
+  __attribute__ ((__format__ (__printf__, 1, 2)));
+
 /* Two uniqstr values have the same value iff they are the same.  */
 #define UNIQSTR_EQ(USTR1, USTR2) ((USTR1) == (USTR2))
 
@@ -52,4 +58,41 @@ void uniqstrs_free (void);
 /* Report them all.  */
 void uniqstrs_print (void);
 
+/*----------------.
+| Concatenation.  |
+`----------------*/
+
+/* Concatenate at most 20 strings and return a uniqstr.  The goal of
+   this macro is to make the caller's code a little more succinct
+   without a trivial uniqstr_vsprintf format string to maintain
+   (for example, "%s%s%s") while still benefitting from gcc's type
+   checking.  Unfortunately, because of the missing format string in the
+   macro invocation, the argument number reported by gcc for a bad
+   argument type is 1 too large.  */
+#define UNIQSTR_CONCAT(...)                                            \
+  uniqstr_vsprintf (UNIQSTR_GEN_FORMAT (__VA_ARGS__,                   \
+                                        "%s", "%s", "%s", "%s", "%s",  \
+                                        "%s", "%s", "%s", "%s", "%s",  \
+                                        "%s", "%s", "%s", "%s", "%s",  \
+                                        "%s", "%s", "%s", "%s", "%s"), \
+                    __VA_ARGS__)
+
+#define UNIQSTR_GEN_FORMAT(F1,  F2,  F3,  F4,  F5,  \
+                           F6,  F7,  F8,  F9,  F10, \
+                           F11, F12, F13, F14, F15, \
+                           F16, F17, F18, F19, F20, \
+                           ...)                     \
+  UNIQSTR_GEN_FORMAT_ (__VA_ARGS__,                 \
+                       "", "", "", "", "",          \
+                       "", "", "", "", "",          \
+                       "", "", "", "", "",          \
+                       "", "", "", "", "")
+
+#define UNIQSTR_GEN_FORMAT_(F1,  F2,  F3,  F4,  F5,       \
+                            F6,  F7,  F8,  F9,  F10,      \
+                            F11, F12, F13, F14, F15,      \
+                            F16, F17, F18, F19, F20, ...) \
+  F1  F2  F3  F4  F5  F6  F7  F8  F9  F10                 \
+  F11 F12 F13 F14 F15 F16 F17 F18 F19 F20
+
 #endif /* ! defined UNIQSTR_H_ */