]> pd.if.org Git - pdclib.old/blobdiff - functions/stdio/vsnprintf.c
Add _cbprintf/_vcbprintf (callback based printf formatters)
[pdclib.old] / functions / stdio / vsnprintf.c
index cda7ab6579d4f45ef9d47580fb5ef540e070d094..6cc233d97f4bed54e2cea64b20ac092734f2c163 100644 (file)
 
 #ifndef REGTEST
 #include <_PDCLIB_io.h>
+#include <string.h>
 
-int vsnprintf( char * _PDCLIB_restrict s, 
-               size_t n, 
-               const char * _PDCLIB_restrict format, 
-               _PDCLIB_va_list arg )
+struct state {
+    size_t bufrem;
+    char *bufp;
+};
+
+static size_t strout( void *p, const char *buf, size_t sz )
 {
-    /* TODO: This function should interpret format as multibyte characters.  */
-    struct _PDCLIB_status_t status;
-    status.base = 0;
-    status.flags = 0;
-    status.n = n;
-    status.i = 0;
-    status.current = 0;
-    status.s = s;
-    status.width = 0;
-    status.prec = 0;
-    status.stream = NULL;
-    va_copy( status.arg, arg );
+    struct state *s = p;
+    size_t copy = s->bufrem >= sz ? sz : s->bufrem;
+    memcpy( s->bufp, buf, copy );
+    s->bufrem -= copy;
+    s->bufp   += copy;
+    return sz;
+}
 
-    while ( *format != '\0' )
-    {
-        const char * rc;
-        if ( ( *format != '%' ) || ( ( rc = _PDCLIB_print( format, &status ) ) == format ) )
-        {
-            /* No conversion specifier, print verbatim */
-            if ( status.i < n )
-            {
-                s[ status.i ] = *format;
-            }
-            status.i++;
-            format++;
-        }
-        else
-        {
-            /* Continue parsing after conversion specifier */
-            format = rc;
-        }
-    }
-    if ( status.i  < n )
+int vsnprintf( char * _PDCLIB_restrict s,
+               size_t n,
+               const char * _PDCLIB_restrict format,
+               _PDCLIB_va_list arg )
+{
+    struct state st;
+    st.bufrem = n;
+    st.bufp   = s;
+    int r = _vcbprintf( &st, strout, format, arg );
+    if ( st.bufrem )
     {
-        s[ status.i ] = '\0';
+        *st.bufp = 0;
     }
-    va_end( status.arg );
-    return status.i;
+
+    return r;
 }
 
 #endif