X-Git-Url: https://pd.if.org/git/?a=blobdiff_plain;f=functions%2F_PDCLIB%2Fprint.c;h=6db55e85a27307ef8211091f2891148f69c0ed3f;hb=2f13296a39de23e7ea4cdda37f13ff214147c6be;hp=d2b5dbddc41c29dc895d4e3d17621df31c37fd05;hpb=d104aa65d95bffd22fc56b5a81bae508ee9da8c1;p=pdclib diff --git a/functions/_PDCLIB/print.c b/functions/_PDCLIB/print.c index d2b5dbd..6db55e8 100644 --- a/functions/_PDCLIB/print.c +++ b/functions/_PDCLIB/print.c @@ -9,6 +9,7 @@ #include #include #include +#include #ifndef REGTEST @@ -158,6 +159,12 @@ static void intformat( intmax_t value, struct _PDCLIB_status_t * status ) */ static void int2base( intmax_t value, struct _PDCLIB_status_t * status ) { + /* Special case: zero value, zero precision -- no output (but padding) */ + if ( status->current == 0 && value == 0 && status->prec == 0 ) + { + intformat( value, status ); + return; + } /* Registering the character being printed at the end of the function here already so it will be taken into account when the deepestmost recursion does the prefix / padding stuff. @@ -198,6 +205,55 @@ static void int2base( intmax_t value, struct _PDCLIB_status_t * status ) } +static void stringformat( const char * s, struct _PDCLIB_status_t * status ) +{ + if ( status->flags & E_char ) + { + status->prec = 1; + } + else + { + if ( status->prec < 0 ) + { + status->prec = strlen( s ); + } + else + { + for ( int i = 0; i < status->prec; ++i ) + { + if ( s[i] == 0 ) + { + status->prec = i; + break; + } + } + } + } + if ( ! ( status->flags & E_minus ) && ( status->width > (_PDCLIB_size_t)status->prec ) ) + { + while ( status->current < ( status->width - status->prec ) ) + { + PUT( ' ' ); + ++(status->current); + } + } + while ( status->prec > 0 ) + { + PUT( *(s++) ); + --(status->prec); + ++(status->current); + } + if ( status->flags & E_minus ) + { + while ( status->width > status->current ) + { + PUT( ' ' ); + ++(status->current); + } + } +} + + const char * _PDCLIB_print( const char * spec, struct _PDCLIB_status_t * status ) { const char * orig_spec = spec; @@ -393,21 +449,19 @@ const char * _PDCLIB_print( const char * spec, struct _PDCLIB_status_t * status case 'A': break; case 'c': - /* TODO: Flags, wide chars. */ - PUT( va_arg( status->arg, int ) ); - return ++spec; - case 's': - /* TODO: Flags, wide chars. */ + /* TODO: wide chars. */ { - char * s = va_arg( status->arg, char * ); - while ( *s != '\0' ) - { - PUT( *(s++) ); - } + char c[1]; + c[0] = (char)va_arg( status->arg, int ); + status->flags |= E_char; + stringformat( c, status ); return ++spec; } + case 's': + /* TODO: wide chars. */ + stringformat( va_arg( status->arg, char * ), status ); + return ++spec; case 'p': - /* TODO: E_long -> E_intptr */ status->base = 16; status->flags |= ( E_lower | E_unsigned | E_alt | E_pointer ); break; @@ -457,28 +511,39 @@ const char * _PDCLIB_print( const char * spec, struct _PDCLIB_status_t * status puts( "UNSUPPORTED PRINTF FLAG COMBINATION" ); return NULL; } - ++(status->current); - if ( ( value / status->base ) != 0 ) + /* Special case: zero value, zero precision: No output, just padding */ + if ( value == 0 && status->prec == 0 ) { - /* Get value to "safe" levels re. uintmax_t. */ - int2base( (intmax_t)(value / status->base), status ); + int2base( 0, status ); } else { - intformat( (intmax_t)value, status ); - } - int digit = value % status->base; - if ( digit < 0 ) - { - digit *= -1; - } - if ( status->flags & E_lower ) - { - PUT( _PDCLIB_digits[ digit ] ); - } - else - { - PUT( _PDCLIB_Xdigits[ digit ] ); + /* To make the call to int2base (using intmax_t) safe for + uintmax_t values > INTMAX_MAX, we basically to the first + "recursion" level of int2base right here. + */ + ++(status->current); + if ( ( value / status->base ) != 0 ) + { + int2base( (intmax_t)(value / status->base), status ); + } + else + { + intformat( (intmax_t)value, status ); + } + int digit = value % status->base; + if ( digit < 0 ) + { + digit *= -1; + } + if ( status->flags & E_lower ) + { + PUT( _PDCLIB_digits[ digit ] ); + } + else + { + PUT( _PDCLIB_Xdigits[ digit ] ); + } } } else @@ -548,7 +613,7 @@ static int testprintf( char * buffer, const char * format, ... ) status.current = 0; status.s = buffer; status.width = 0; - status.prec = 0; + status.prec = EOF; status.stream = NULL; va_start( status.arg, format ); memset( buffer, '\0', 100 );