summaryrefslogtreecommitdiff
path: root/util.c
diff options
context:
space:
mode:
authorRob Herring <robh@kernel.org>2018-11-24 14:47:54 -0600
committerDavid Gibson <david@gibson.dropbear.id.au>2018-11-25 18:21:48 +1100
commita1eff70c02cfd3a6263adfd6aab25290211f31aa (patch)
tree25cd74143b5984e49f5f22208e39fd6d8bb97ff4 /util.c
parent82a52ce4573b7cd0039786f65b280fb99431fe5d (diff)
downloaddevice-tree-compiler-a1eff70c02cfd3a6263adfd6aab25290211f31aa.tar.gz
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.c60
1 files changed, 39 insertions, 21 deletions
diff --git a/util.c b/util.c
index a69b7a1..9c6fb5f 100644
--- a/util.c
+++ b/util.c
@@ -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);