]> pd.if.org Git - pdclib/blobdiff - functions/_PDCLIB/print.c
Activated Tyndur tests for _PDCLIB_print(). Fixed flag handling bug.
[pdclib] / functions / _PDCLIB / print.c
index 40ec2a2c7c88c62f08640107579edd667258ef16..9a30ca2446b0d332784fdecebfa7d12b0b55b94f 100644 (file)
 #include <stdlib.h>
 #include <stddef.h>
 
+#ifndef REGTEST
+
 /* Using an integer's bits as flags for both the conversion flags and length
    modifiers.
 */
 /* FIXME: one too many flags to work on a 16-bit machine, join some (e.g. the
           width flags) into a combined field.
 */
-#define E_minus    1<<0
-#define E_plus     1<<1
-#define E_alt      1<<2
-#define E_space    1<<3
-#define E_zero     1<<4
-#define E_done     1<<5
-#define E_char     1<<6
-#define E_short    1<<7
-#define E_long     1<<8
-#define E_llong    1<<9
-#define E_intmax   1<<10
-#define E_size     1<<11
-#define E_ptrdiff  1<<12
-#define E_intptr   1<<13
-#define E_ldouble  1<<14
-#define E_lower    1<<15
-#define E_unsigned 1<<16
+#define E_minus    (1<<0)
+#define E_plus     (1<<1)
+#define E_alt      (1<<2)
+#define E_space    (1<<3)
+#define E_zero     (1<<4)
+#define E_done     (1<<5)
+
+#define E_char     (1<<6)
+#define E_short    (1<<7)
+#define E_long     (1<<8)
+#define E_llong    (1<<9)
+#define E_intmax   (1<<10)
+#define E_size     (1<<11)
+#define E_ptrdiff  (1<<12)
+#define E_pointer  (1<<13)
+
+#define E_ldouble  (1<<14)
+
+#define E_lower    (1<<15)
+#define E_unsigned (1<<16)
 
 /* This macro delivers a given character to either a memory buffer or a stream,
    depending on the contents of 'status' (struct _PDCLIB_status_t).
@@ -59,7 +64,7 @@ static void intformat( intmax_t value, struct _PDCLIB_status_t * status )
     /* At worst, we need two prefix characters (hex prefix). */
     char preface[3] = "\0";
     size_t preidx = 0;
-    if ( ( status->flags & E_alt ) && ( status->base == 16 || status->base == 8 ) )
+    if ( ( status->flags & E_alt ) && ( status->base == 16 || status->base == 8 ) && ( value != 0 ) )
     {
         /* Octal / hexadecimal prefix for "%#" conversions */
         preface[ preidx++ ] = '0';
@@ -286,7 +291,7 @@ const char * _PDCLIB_print( const char * spec, struct _PDCLIB_status_t * status
             spec = endptr;
         }
         /* Having a precision cancels out any zero flag. */
-        status->flags ^= E_zero;
+        status->flags &= ~E_zero;
     }
 
     /* Optional length modifier
@@ -394,7 +399,7 @@ const char * _PDCLIB_print( const char * spec, struct _PDCLIB_status_t * status
         case 'p':
             /* TODO: E_long -> E_intptr */
             status->base = 16;
-            status->flags |= ( E_lower | E_unsigned | E_alt | E_long );
+            status->flags |= ( E_lower | E_unsigned | E_alt | E_pointer );
             break;
         case 'n':
            {
@@ -415,7 +420,7 @@ const char * _PDCLIB_print( const char * spec, struct _PDCLIB_status_t * status
         if ( status->flags & E_unsigned )
         {
             uintmax_t value;
-            switch ( status->flags & ( E_char | E_short | E_long | E_llong | E_size ) )
+            switch ( status->flags & ( E_char | E_short | E_long | E_llong | E_size | E_pointer ) )
             {
                 case E_char:
                     value = (uintmax_t)(unsigned char)va_arg( status->arg, int );
@@ -435,6 +440,12 @@ const char * _PDCLIB_print( const char * spec, struct _PDCLIB_status_t * status
                 case E_size:
                     value = (uintmax_t)va_arg( status->arg, size_t );
                     break;
+                case E_pointer:
+                    value = (uintmax_t)(uintptr_t)va_arg( status->arg, void * );
+                    break;
+                default:
+                    puts( "UNSUPPORTED PRINTF FLAG COMBINATION" );
+                    return NULL;
             }
             ++(status->current);
             /* FIXME: The if clause means one-digit values do not get formatted */
@@ -486,6 +497,9 @@ const char * _PDCLIB_print( const char * spec, struct _PDCLIB_status_t * status
                 case E_intmax:
                     int2base( va_arg( status->arg, intmax_t ), status );
                     break;
+                default:
+                    puts( "UNSUPPORTED PRINTF FLAG COMBINATION" );
+                    return NULL;
             }
         }
         if ( status->flags & E_minus )
@@ -504,11 +518,15 @@ const char * _PDCLIB_print( const char * spec, struct _PDCLIB_status_t * status
     return ++spec;
 }
 
+#endif
+
 #ifdef TEST
 #define _PDCLIB_FILEID "_PDCLIB/print.c"
 #define _PDCLIB_STRINGIO
 
-#include <_PDCLIB_test.h>
+#include "_PDCLIB_test.h"
+
+#ifndef REGTEST
 
 static int testprintf( char * buffer, const char * format, ... )
 {
@@ -534,12 +552,16 @@ static int testprintf( char * buffer, const char * format, ... )
     return status.i;
 }
 
+#endif
+
 #define TEST_CONVERSION_ONLY
 
 int main( void )
 {
+#ifndef REGTEST
     char target[100];
 #include "printf_testcases.h"
+#endif
     return TEST_RESULTS;
 }