]> pd.if.org Git - pdclib/commitdiff
Fixed pointer handling of printf() / scanf().
authorMartin Baute <solar@rootdirectory.de>
Thu, 17 Mar 2016 19:29:04 +0000 (20:29 +0100)
committerMartin Baute <solar@rootdirectory.de>
Thu, 17 Mar 2016 19:29:04 +0000 (20:29 +0100)
functions/_PDCLIB/print.c
functions/_PDCLIB/scan.c

index 40ec2a2c7c88c62f08640107579edd667258ef16..5214612c630fa920a7b006fc8688a4ccc74006f7 100644 (file)
@@ -29,7 +29,7 @@
 #define E_intmax   1<<10
 #define E_size     1<<11
 #define E_ptrdiff  1<<12
-#define E_intptr   1<<13
+#define E_pointer  1<<13
 #define E_ldouble  1<<14
 #define E_lower    1<<15
 #define E_unsigned 1<<16
@@ -394,7 +394,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 +415,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 +435,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 +492,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 )
index 811039317edc3467948f09bb05f7d7e70e095711..8d4d7e0b98b3de5db39ff07fd71c83cadefb68cd 100644 (file)
@@ -25,7 +25,7 @@
 #define E_intmax     1<<10
 #define E_size       1<<11
 #define E_ptrdiff    1<<12
-#define E_intptr     1<<13
+#define E_pointer    1<<13
 #define E_ldouble    1<<14
 #define E_unsigned   1<<16
 
@@ -283,7 +283,7 @@ const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status )
         case 's':
         {
             char * c = va_arg( status->arg, char * );
-            while ( ( status->current < status->width ) && 
+            while ( ( status->current < status->width ) &&
                     ( ( rc = GET( status ) ) != EOF ) )
             {
                 if ( isspace( rc ) )
@@ -343,7 +343,7 @@ const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status )
             } while ( *endspec != ']' );
             // read according to scanlist, equiv. to %s above
             char * c = va_arg( status->arg, char * );
-            while ( ( status->current < status->width ) && 
+            while ( ( status->current < status->width ) &&
                     ( ( rc = GET( status ) ) != EOF ) )
             {
                 if ( negative_scanlist )
@@ -382,8 +382,7 @@ const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status )
         }
         case 'p':
             status->base = 16;
-            /* TODO: Assuming 'long' for pointers, this should be handled differently. */
-            status->flags |= E_unsigned | E_long;
+            status->flags |= E_pointer;
             break;
         case 'n':
         {
@@ -521,7 +520,7 @@ const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status )
         if ( ! ( status->flags & E_suppressed ) )
         {
             switch ( status->flags & ( E_char | E_short | E_long | E_llong |
-                                       E_intmax | E_size | E_ptrdiff |
+                                       E_intmax | E_size | E_ptrdiff | E_pointer |
                                        E_unsigned ) )
             {
                 case E_char:
@@ -576,6 +575,11 @@ const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status )
                     *( va_arg( status->arg,          ptrdiff_t * ) ) =          (ptrdiff_t)( value * sign );
                     break;
 
+                case E_pointer:
+                    /* E_pointer always implies unsigned */
+                    *( uintptr_t* )( va_arg( status->arg, void * ) ) =          (uintptr_t)( value * sign );
+                    break;
+
                 default:
                     puts( "UNSUPPORTED SCANF FLAG COMBINATION" );
                     return NULL; /* behaviour unspecified */