[PATCH wayland 2/3] Add a wl_array_printf function for easy string formatting

Jason Ekstrand jason at jlekstrand.net
Thu Dec 19 09:40:44 PST 2013


Signed-off-by: Jason Ekstrand <jason at jlekstrand.net>
---

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



More information about the wayland-devel mailing list