ucx/utils.c

changeset 39
3e55bed345f9
parent 17
11dffb40cd91
child 70
88092b88ec00
--- a/ucx/utils.c	Tue Sep 03 12:08:35 2013 +0200
+++ b/ucx/utils.c	Sat Sep 07 14:08:43 2013 +0200
@@ -134,11 +134,17 @@
 
 /* PRINTF FUNCTIONS */
 
+#ifdef va_copy
 #define UCX_PRINTF_BUFSIZE 256
+#else
+#pragma message("WARNING: C99 va_copy macro not supported by this platform" \
+                " - limiting ucx_*printf to 2 KiB")
+#define UCX_PRINTF_BUFSIZE 0x800
+#endif
 
 int ucx_fprintf(void *stream, write_func wfc, const char *fmt, ...) {
+    int ret;
     va_list ap;
-    int ret;
     va_start(ap, fmt);
     ret = ucx_vfprintf(stream, wfc, fmt, ap);
     va_end(ap);
@@ -147,6 +153,7 @@
 
 int ucx_vfprintf(void *stream, write_func wfc, const char *fmt, va_list ap) {
     char buf[UCX_PRINTF_BUFSIZE];
+#ifdef va_copy
     va_list ap2;
     va_copy(ap2, ap);
     int ret = vsnprintf(buf, UCX_PRINTF_BUFSIZE, fmt, ap);
@@ -167,13 +174,23 @@
         }
         
         ret = vsnprintf(newbuf, len, fmt, ap2);
-        va_end(ap2);
         if (ret > 0) {
             ret = (int)wfc(newbuf, 1, ret, stream);
         }
         free(newbuf);
     }
     return ret;
+#else
+    int ret = vsnprintf(buf, UCX_PRINTF_BUFSIZE, fmt, ap);
+    if (ret < 0) {
+        return ret;
+    } else if (ret < UCX_PRINTF_BUFSIZE) {
+        return (int)wfc(buf, 1, ret, stream);
+    } else {
+        errno = ENOMEM;
+        return -1;
+    }
+#endif
 }
 
 sstr_t ucx_asprintf(UcxAllocator *allocator, const char *fmt, ...) {
@@ -189,9 +206,10 @@
     sstr_t s;
     s.ptr = NULL;
     s.length = 0;
+    char buf[UCX_PRINTF_BUFSIZE];
+#ifdef va_copy
     va_list ap2;
     va_copy(ap2, ap);
-    char buf[UCX_PRINTF_BUFSIZE];
     int ret = vsnprintf(buf, UCX_PRINTF_BUFSIZE, fmt, ap);
     if (ret > 0 && ret < UCX_PRINTF_BUFSIZE) {
         s.ptr = (char*)a->malloc(a->pool, ret + 1);
@@ -204,7 +222,6 @@
         int len = ret + 1;
         s.ptr = (char*)a->malloc(a->pool, len);
         ret = vsnprintf(s.ptr, len, fmt, ap2);
-        va_end(ap2);
         if (ret < 0) {
             free(s.ptr);
             s.ptr = NULL;
@@ -212,5 +229,16 @@
             s.length = (size_t)ret;
         }
     }
+#else
+    int ret = vsnprintf(buf, UCX_PRINTF_BUFSIZE, fmt, ap);
+    if (ret > 0 && ret < UCX_PRINTF_BUFSIZE) {
+        s.ptr = (char*)a->malloc(a->pool, ret + 1);
+        s.length = (size_t)ret;
+        memcpy(s.ptr, buf, ret);
+        s.ptr[s.length] = '\0';
+    } else {
+        errno = ENOMEM;
+    }
+#endif
     return s;
 }

mercurial