diff options
author | Rob Herring <robh@kernel.org> | 2018-11-24 14:47:54 -0600 |
---|---|---|
committer | David Gibson <david@gibson.dropbear.id.au> | 2018-11-25 18:21:48 +1100 |
commit | a1eff70c02cfd3a6263adfd6aab25290211f31aa (patch) | |
tree | 25cd74143b5984e49f5f22208e39fd6d8bb97ff4 /util.c | |
parent | 82a52ce4573b7cd0039786f65b280fb99431fe5d (diff) | |
download | dtc-a1eff70c02cfd3a6263adfd6aab25290211f31aa.zip dtc-a1eff70c02cfd3a6263adfd6aab25290211f31aa.tar.gz dtc-a1eff70c02cfd3a6263adfd6aab25290211f31aa.tar.bz2 |
util: Add xa{v}sprintf_append functions
Add variadic and va_list functions, xa{v}sprintf, which appends a
formatted string to an existing string and re-allocate the string buffer
if necessary. xasprintf becomes just a special case of xasprintf_append
with a NULL starting string.
Rather than looping to get a big enough buffer, simply the implementation
by assuming we have a C99 compliant vsnprintf implementation to return the
necessary size. A side effect is glibc 2.0 support is dropped which seems
unnecessary.
Signed-off-by: Rob Herring <robh@kernel.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'util.c')
-rw-r--r-- | util.c | 60 |
1 files changed, 39 insertions, 21 deletions
@@ -46,36 +46,54 @@ char *xstrdup(const char *s) return d; } -/* based in part from (3) vsnprintf */ -int xasprintf(char **strp, const char *fmt, ...) +int xavsprintf_append(char **strp, const char *fmt, va_list ap) { - int n, size = 128; /* start with 128 bytes */ + int n, size = 0; /* start with 128 bytes */ char *p; - va_list ap; + va_list ap_copy; - /* initial pointer is NULL making the fist realloc to be malloc */ - p = NULL; - while (1) { - p = xrealloc(p, size); + p = *strp; + if (p) + size = strlen(p); - /* Try to print in the allocated space. */ - va_start(ap, fmt); - n = vsnprintf(p, size, fmt, ap); - va_end(ap); + va_copy(ap_copy, ap); + n = vsnprintf(NULL, 0, fmt, ap_copy) + 1; + va_end(ap_copy); + + p = xrealloc(p, size + n); + + n = vsnprintf(p + size, n, fmt, ap); - /* If that worked, return the string. */ - if (n > -1 && n < size) - break; - /* Else try again with more space. */ - if (n > -1) /* glibc 2.1 */ - size = n + 1; /* precisely what is needed */ - else /* glibc 2.0 */ - size *= 2; /* twice the old size */ - } *strp = p; return strlen(p); } +int xasprintf_append(char **strp, const char *fmt, ...) +{ + int n; + va_list ap; + + va_start(ap, fmt); + n = xavsprintf_append(strp, fmt, ap); + va_end(ap); + + return n; +} + +int xasprintf(char **strp, const char *fmt, ...) +{ + int n; + va_list ap; + + *strp = NULL; + + va_start(ap, fmt); + n = xavsprintf_append(strp, fmt, ap); + va_end(ap); + + return n; +} + char *join_path(const char *path, const char *name) { int lenp = strlen(path); |