]> pd.if.org Git - pdclib/blobdiff - draft.c
Disabled format string warnings on ...printf() regtest drivers.
[pdclib] / draft.c
diff --git a/draft.c b/draft.c
index 36b0c7954e25d7597c1fa6e6209ddc440bf8873b..570f305353b9352e07b51be7265c5ccb4e981ef7 100644 (file)
--- a/draft.c
+++ b/draft.c
 #define E_intmax   1<<10
 #define E_size     1<<11
 #define E_ptrdiff  1<<12
-#define E_double   1<<13
-#define E_lower    1<<14
-#define E_unsigned 1<<15
+#define E_intptr   1<<13
+#define E_double   1<<14
+#define E_lower    1<<15
+#define E_unsigned 1<<16
 
 struct status_t
 {
@@ -45,7 +46,8 @@ struct status_t
 
 const char * parse_out( const char * spec, struct status_t * status );
 inline void test( size_t n, const char * expect, ... );
-int _PDCLIB_sprintf( char * buffer, size_t n, const char * format, va_list ap );
+int _PDCLIB_vsnprintf( char * buffer, size_t n, const char * format, va_list ap );
+int _PDCLIB_snprintf( char * s, size_t n, const char * format, ... );
 
 /* The following only for testing. */
 #include <limits.h>
@@ -53,7 +55,6 @@ int _PDCLIB_sprintf( char * buffer, size_t n, const char * format, va_list ap );
 
 int main( void )
 {
-    puts( "- Signed min / max -\n" );
     test( SIZE_MAX, "%hhd", CHAR_MIN );
     test( SIZE_MAX, "%hhd", CHAR_MAX );
     test( SIZE_MAX, "%hhd", 0 );
@@ -69,7 +70,6 @@ int main( void )
     test( SIZE_MAX, "%lld", LLONG_MIN );
     test( SIZE_MAX, "%lld", LLONG_MAX );
     test( SIZE_MAX, "%lld", 0ll );
-    puts( "- Unsigned min / max -\n" );
     test( SIZE_MAX, "%hhu", UCHAR_MAX );
     test( SIZE_MAX, "%hhu", (unsigned char)-1 );
     test( SIZE_MAX, "%hu", USHRT_MAX );
@@ -80,26 +80,23 @@ int main( void )
     test( SIZE_MAX, "%lu", -1ul );
     test( SIZE_MAX, "%llu", ULLONG_MAX );
     test( SIZE_MAX, "%llu", -1ull );
-    puts( "- Hex and Octal, normal and alternative, upper and lowercase -\n" );
     test( SIZE_MAX, "%X", UINT_MAX );
     test( SIZE_MAX, "%#X", -1u );
     test( SIZE_MAX, "%x", UINT_MAX );
     test( SIZE_MAX, "%#x", -1u );
     test( SIZE_MAX, "%o", UINT_MAX );
     test( SIZE_MAX, "%#o", -1u );
-    puts( "- Plus flag -\n" );
+    test( SIZE_MAX, "%.0#o", 0 );
     test( SIZE_MAX, "%+d", INT_MIN );
     test( SIZE_MAX, "%+d", INT_MAX );
     test( SIZE_MAX, "%+d", 0 );
     test( SIZE_MAX, "%+u", UINT_MAX );
     test( SIZE_MAX, "%+u", -1u );
-    puts( "- Space flag -\n" );
     test( SIZE_MAX, "% d", INT_MIN );
     test( SIZE_MAX, "% d", INT_MAX );
     test( SIZE_MAX, "% d", 0 );
     test( SIZE_MAX, "% u", UINT_MAX );
     test( SIZE_MAX, "% u", -1u );
-    puts( "- Field width -\n" );
     test( SIZE_MAX, "%9d", INT_MIN );
     test( SIZE_MAX, "%9d", INT_MAX );
     test( SIZE_MAX, "%10d", INT_MIN );
@@ -108,7 +105,6 @@ int main( void )
     test( SIZE_MAX, "%11d", INT_MAX );
     test( SIZE_MAX, "%12d", INT_MIN );
     test( SIZE_MAX, "%12d", INT_MAX );
-    puts( "- Field width (left bound) -\n" );
     test( SIZE_MAX, "%-9d", INT_MIN );
     test( SIZE_MAX, "%-9d", INT_MAX );
     test( SIZE_MAX, "%-10d", INT_MIN );
@@ -117,7 +113,6 @@ int main( void )
     test( SIZE_MAX, "%-11d", INT_MAX );
     test( SIZE_MAX, "%-12d", INT_MIN );
     test( SIZE_MAX, "%-12d", INT_MAX );
-    puts( "- Field width, zero padding -\n");
     test( SIZE_MAX, "%09d", INT_MIN );
     test( SIZE_MAX, "%09d", INT_MAX );
     test( SIZE_MAX, "%010d", INT_MIN );
@@ -126,7 +121,6 @@ int main( void )
     test( SIZE_MAX, "%011d", INT_MAX );
     test( SIZE_MAX, "%012d", INT_MIN );
     test( SIZE_MAX, "%012d", INT_MAX );
-    puts( "- Field width, zero padding (left bound) -\n" );
     test( SIZE_MAX, "%-09d", INT_MIN );
     test( SIZE_MAX, "%-09d", INT_MAX );
     test( SIZE_MAX, "%-010d", INT_MIN );
@@ -135,7 +129,6 @@ int main( void )
     test( SIZE_MAX, "%-011d", INT_MAX );
     test( SIZE_MAX, "%-012d", INT_MIN );
     test( SIZE_MAX, "%-012d", INT_MAX );
-    puts( "- Limited n -\n" );
     test( 8, "%9d", INT_MAX );
     test( 8, "%9d", INT_MIN );
     test( 9, "%9d", INT_MAX );
@@ -160,7 +153,6 @@ int main( void )
     test( 12, "%12d", INT_MIN );
     test( 13, "%12d", INT_MAX );
     test( 13, "%12d", INT_MIN );
-    puts( "- Precision -\n" );
     test( SIZE_MAX, "%030.20d", INT_MAX );
     test( SIZE_MAX, "%.6x", UINT_MAX );
     test( SIZE_MAX, "%#6.3x", UINT_MAX );
@@ -180,9 +172,21 @@ int main( void )
     test( SIZE_MAX, "%+0.6d", INT_MAX );
     test( SIZE_MAX, "%+06.3d", INT_MAX );
     test( SIZE_MAX, "%+03.6d", INT_MAX );
-    puts( "- Multiple outputs -\n" );
     test( SIZE_MAX, "- %d", INT_MAX );
     test( SIZE_MAX, "- %d %% %d", INT_MAX, INT_MIN );
+    test( SIZE_MAX, "%c", 'x' );
+    test( SIZE_MAX, "%s", "abcdef" );
+    test( SIZE_MAX, "%p", 0xdeadbeef );
+    {
+        char buffer[50];
+        int val1, val2, val3, val4;
+        snprintf( buffer, SIZE_MAX, "123456%n789%n", &val1, &val2 );
+        _PDCLIB_snprintf( buffer, SIZE_MAX, "123456%n789%n", &val3, &val4 );
+        if ( ( val1 != val3 ) || ( val2 != val4 ) )
+        {
+            printf( "Output %d/%d\nExpect %d/%d\n\n", val1, val2, val3, val4 );
+        }
+    }
     return 0;
 }
 
@@ -463,6 +467,7 @@ const char * parse_out( const char * spec, struct status_t * status )
     switch ( *spec )
     {
         case 'd':
+            /* FALLTHROUGH */
         case 'i':
             status->base = 10;
             break;
@@ -493,13 +498,30 @@ const char * parse_out( const char * spec, struct status_t * status )
         case 'A':
             break;
         case 'c':
-            break;
+            /* TODO: Flags, wide chars. */
+            DELIVER( va_arg( status->ap, int ) );
+            return ++spec;
         case 's':
-            break;
+            /* TODO: Flags, wide chars. */
+            {
+                char * s = va_arg( status->ap, char * );
+                while ( *s != '\0' )
+                {
+                    DELIVER( *(s++) );
+                }
+                return ++spec;
+            }
         case 'p':
-            /* uint2base( 16, (intptr_t)value, true ) */
-        case 'n':
+            /* TODO: E_long -> E_intptr */
+            status->base = 16;
+            status->flags |= ( E_lower | E_unsigned | E_alt | E_long );
             break;
+        case 'n':
+           {
+               int * val = va_arg( status->ap, int * );
+               *val = status->i;
+               return ++spec;
+           }
         default:
             /* No conversion specifier. Bad conversion. */
             return orig_spec;
@@ -604,7 +626,7 @@ inline void test( size_t n, const char * expect, ... )
     int rc;
     va_list ap;
     va_start( ap, expect );
-    myrc = _PDCLIB_sprintf( buffer1, n, expect, ap );
+    myrc = _PDCLIB_vsnprintf( buffer1, n, expect, ap );
     rc = vsnprintf( buffer2, n, expect, ap );
     if ( ( strcmp( buffer1, buffer2 ) != 0 ) || ( myrc != rc ) )
     {
@@ -614,7 +636,7 @@ inline void test( size_t n, const char * expect, ... )
     free( buffer2 );
 }
 
-int _PDCLIB_sprintf( char * buffer, size_t n, const char * format, va_list ap )
+int _PDCLIB_vsnprintf( char * buffer, size_t n, const char * format, va_list ap )
 {
     struct status_t status = { 0, 0, n, 0, 0, buffer, 0, 0, NULL, ap };
     while ( *format != '\0' )
@@ -635,6 +657,13 @@ int _PDCLIB_sprintf( char * buffer, size_t n, const char * format, va_list ap )
     return status.i;
 }
 
+int _PDCLIB_snprintf( char * s, size_t n, const char * format, ... )
+{
+    va_list ap;
+    va_start( ap, format );
+    return _PDCLIB_vsnprintf( s, n, format, ap );
+}
+
 #if 0
 int _PDCLIB_fprintf( FILE * stream, const char * format, va_list ap )
 {