bison-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Minor code cleanup.


From: Joel E. Denny
Subject: [PATCH] Minor code cleanup.
Date: Thu, 8 Oct 2009 01:58:29 -0400 (EDT)
User-agent: Alpine 1.00 (DEB 882 2007-12-20)

I started out just wanting to implement a uniqstr_concat function because 
it seems to make constructing new muscle names easier.  This gets rid of 
the ugly MUSCLE_USER_NAME_CONVERT macro and helps some of my offline work 
as well.  There are likely other places in bison it could help, but I 
haven't tried to hunt them all down.

However, after I got into it, I ended up implementing a crazy C99 scheme 
to get gcc to check argument types for variadic functions that do not have 
a format argument.  It requires a separate uniqstr_vsprintf function, 
which, in hindsight, may have been sufficient by itself.  But oh well, 
UNIQSTR_CONCAT is born, it makes life a little nicer, and so I'm keeping 
it for now unless someone shows me a better way.

I pushed this to master and branch-2.5.

>From 10659d0ec997368fe57712a7c564795c530ba0c2 Mon Sep 17 00:00:00 2001
From: Joel E. Denny <address@hidden>
Date: Wed, 7 Oct 2009 23:09:43 -0400
Subject: [PATCH] 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.
---
 ChangeLog        |   10 ++++++++
 src/muscle-tab.c |   66 ++++++++++++++++++++++-------------------------------
 src/uniqstr.c    |   16 +++++++++++++
 src/uniqstr.h    |   43 +++++++++++++++++++++++++++++++++++
 4 files changed, 96 insertions(+), 39 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 5bbab03..219d9b9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2009-10-07  Joel E. Denny  <address@hidden>
+
+       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-06  Joel E. Denny  <address@hidden>
 
        * TODO (Complaint submessage indentation): New.
diff --git a/src/muscle-tab.c b/src/muscle-tab.c
index bfb7803..455515b 100644
--- a/src/muscle-tab.c
+++ b/src/muscle-tab.c
@@ -413,18 +413,6 @@ muscle_percent_variable_update (char const *variable)
   return variable;
 }
 
-#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,
@@ -438,11 +426,11 @@ muscle_percent_define_insert (char const *variable, 
location variable_loc,
   /* Permit certain names with underscores for backward compatibility.  */
   variable = muscle_percent_variable_update (variable);
 
-  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
@@ -476,7 +464,7 @@ muscle_percent_define_ensure (char const *variable, 
location loc,
 {
   char const *val = value ? "" : "false";
   char const *name;
-  MUSCLE_USER_NAME_CONVERT (name, "percent_define(", variable, ")");
+  name = UNIQSTR_CONCAT ("percent_define(", variable, ")");
 
   /* %pure-parser is deprecated in favor of `%define api.pure', so use
      `%define api.pure' in a backward-compatible manner here.  First,
@@ -499,9 +487,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);
@@ -514,10 +502,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);
 }
 
@@ -526,12 +514,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;
 }
 
@@ -542,9 +530,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)
@@ -562,8 +550,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))
     {
@@ -594,10 +582,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;
@@ -620,7 +608,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)
@@ -658,7 +646,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);
diff --git a/src/uniqstr.c b/src/uniqstr.c
index 78b8a98..ed8f79a 100644
--- a/src/uniqstr.c
+++ b/src/uniqstr.c
@@ -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.  |
diff --git a/src/uniqstr.h b/src/uniqstr.h
index 04600e9..2f9fce0 100644
--- a/src/uniqstr.h
+++ b/src/uniqstr.h
@@ -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_ */
-- 
1.5.4.3





reply via email to

[Prev in Thread] Current Thread [Next in Thread]