Signed-off-by: Jason Ekstrand <[email protected]>
---

This version of the patch adds a wl_array_vprintf function if we want it.
Both versions accomplish exactly the same thing as far as the series is
concerned.  However, wl_array_vprintf might be nice in the future.  Feel
free to use whichever one you prefer.

 src/wayland-util.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/wayland-util.h |  2 ++
 2 files changed, 63 insertions(+)

diff --git a/src/wayland-util.c b/src/wayland-util.c
index 4fe9c81..3e5ac9c 100644
--- a/src/wayland-util.c
+++ b/src/wayland-util.c
@@ -25,6 +25,7 @@
 #include <stdint.h>
 #include <string.h>
 #include <stdarg.h>
+#include <errno.h>
 
 #include "wayland-util.h"
 #include "wayland-private.h"
@@ -148,6 +149,66 @@ wl_array_copy(struct wl_array *array, struct wl_array 
*source)
        return 0;
 }
 
+int
+wl_array_vprintf(struct wl_array *array, const char *fmt, va_list ap)
+{
+       va_list ap_copy;
+       int nchars;
+       size_t old_size;
+
+       while (1) {
+               errno = 0;
+
+#if defined(va_copy)
+               va_copy(ap_copy, ap);
+#elif defined(__va_copy)
+               __va_copy(ap_copy, ap);
+#else
+               ap_copy = ap;
+#endif
+
+               nchars = vsnprintf((char *)array->data + array->size,
+                                  array->alloc - array->size, fmt, ap_copy);
+               va_end(ap_copy);
+
+               /* Depending on whether the library implements the C99
+                * printf specification or the ISO printf specification,
+                * the return value may be different.  C99 printf returns
+                * the value of the string that *would* be printed in the
+                * case of overflow, ISO printf simply returns -1.
+                *
+                * In order to differentiate between overflow and an error,
+                * we set errno to 0 explicitly.
+                */
+               if (errno != 0)
+                       return -1;
+
+               if (nchars < 0) {
+                       wl_array_add(array, array->alloc);
+               } else if (nchars >= (ssize_t)(array->alloc - array->size)) {
+                       old_size = array->size;
+                       wl_array_add(array, nchars + 1);
+                       array->size = old_size;
+               } else {
+                       array->size += nchars;
+                       return nchars;
+               }
+       }
+}
+
+int
+wl_array_printf(struct wl_array *array, const char *fmt, ...)
+{
+       va_list ap;
+       int nchars;
+
+       va_start(ap, fmt);
+       nchars = wl_array_vprintf(array, fmt, ap);
+       va_end(ap);
+
+       return nchars;
+}
+
 union map_entry {
        uintptr_t next;
        void *data;
diff --git a/src/wayland-util.h b/src/wayland-util.h
index 68d91e2..e527cfd 100644
--- a/src/wayland-util.h
+++ b/src/wayland-util.h
@@ -202,6 +202,8 @@ void wl_array_init(struct wl_array *array);
 void wl_array_release(struct wl_array *array);
 void *wl_array_add(struct wl_array *array, size_t size);
 int wl_array_copy(struct wl_array *array, struct wl_array *source);
+int wl_array_printf(struct wl_array *array, const char *fmt, ...);
+int wl_array_vprintf(struct wl_array *array, const char *fmt, va_list ap);
 
 typedef int32_t wl_fixed_t;
 
-- 
1.8.4.2

_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to