mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-19 01:03:04 +00:00
uniqstr: avoid need for VLAs
C11 no longer requires support for variable-length arrays, and VS2015 does not have them. Redo UNIQSTR_CONCAT to use a method that is simpler and better anyway. * src/uniqstr.c (uniqstr_vsprintf): Remove; no longer needed. * src/uniqstr.h (UNIQSTR_GEN_FORMAT, UNIQSTR_GEN_FORMAT_): * src/uniqstr.c (uniqstr_concat): New function. * src/uniqstr.h (UNIQSTR_CONCAT): Use it instead of using uniqstr_vsprintf.
This commit is contained in:
@@ -56,19 +56,36 @@ uniqstr_new (char const *str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
uniqstr
|
uniqstr
|
||||||
uniqstr_vsprintf (char const *format, ...)
|
uniqstr_concat (int nargs, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
size_t length;
|
|
||||||
va_start (args, format);
|
va_start (args, nargs);
|
||||||
length = vsnprintf (NULL, 0, format, args);
|
size_t reslen = 0;
|
||||||
|
for (int i = 0; i < nargs; i++)
|
||||||
|
reslen += strlen (va_arg (args, char const *));
|
||||||
va_end (args);
|
va_end (args);
|
||||||
|
|
||||||
char res[length + 1];
|
char *str = xmalloc (reslen + 1);
|
||||||
va_start (args, format);
|
char *p = str;
|
||||||
vsprintf (res, format, args);
|
|
||||||
|
va_start (args, nargs);
|
||||||
|
for (int i = 0; i < nargs; i++)
|
||||||
|
{
|
||||||
|
char const *arg = va_arg (args, char const *);
|
||||||
|
size_t arglen = strlen (arg);
|
||||||
|
memcpy (p, arg, arglen);
|
||||||
|
p += arglen;
|
||||||
|
}
|
||||||
va_end (args);
|
va_end (args);
|
||||||
return uniqstr_new (res);
|
|
||||||
|
*p = '\0';
|
||||||
|
uniqstr res = hash_insert (uniqstrs_table, str);
|
||||||
|
if (!res)
|
||||||
|
xalloc_die ();
|
||||||
|
if (res != str)
|
||||||
|
free (str);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*------------------------------.
|
/*------------------------------.
|
||||||
|
|||||||
@@ -32,12 +32,6 @@ typedef char const *uniqstr;
|
|||||||
/* Return the uniqstr for STR. */
|
/* Return the uniqstr for STR. */
|
||||||
uniqstr uniqstr_new (char const *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, ...)
|
|
||||||
_GL_ATTRIBUTE_FORMAT_PRINTF (1, 2);
|
|
||||||
|
|
||||||
/* Two uniqstr values have the same value iff they are the same. */
|
/* Two uniqstr values have the same value iff they are the same. */
|
||||||
# define UNIQSTR_EQ(Ustr1, Ustr2) (!!((Ustr1) == (Ustr2)))
|
# define UNIQSTR_EQ(Ustr1, Ustr2) (!!((Ustr1) == (Ustr2)))
|
||||||
|
|
||||||
@@ -52,38 +46,12 @@ void uniqstr_assert (char const *str);
|
|||||||
| Concatenation. |
|
| Concatenation. |
|
||||||
`----------------*/
|
`----------------*/
|
||||||
|
|
||||||
/* Concatenate at most 20 strings and return a uniqstr. The goal of
|
/* Concatenate strings and return a uniqstr. The goal of
|
||||||
this macro is to make the caller's code a little more succinct
|
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(...) \
|
# define UNIQSTR_CONCAT(...) \
|
||||||
uniqstr_vsprintf (UNIQSTR_GEN_FORMAT (__VA_ARGS__, \
|
uniqstr_concat (ARRAY_CARDINALITY (((char const *[]) {__VA_ARGS__})), \
|
||||||
"%s", "%s", "%s", "%s", "%s", \
|
__VA_ARGS__)
|
||||||
"%s", "%s", "%s", "%s", "%s", \
|
uniqstr uniqstr_concat (int nargs, ...);
|
||||||
"%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
|
|
||||||
|
|
||||||
/*--------------------.
|
/*--------------------.
|
||||||
| Table of uniqstrs. |
|
| Table of uniqstrs. |
|
||||||
|
|||||||
Reference in New Issue
Block a user