int main( void )
{
- int rc;
puts( "- Signed min / max -\n" );
test( SIZE_MAX, "%hhd", CHAR_MIN );
test( SIZE_MAX, "%hhd", CHAR_MAX );
test( 12, "%12d", INT_MIN );
test( 13, "%12d", INT_MAX );
test( 13, "%12d", INT_MIN );
- puts( "- Precision (tbd) -\n" );
- {
- const char * format = "%030.20d";
- printf( "glibc '" );
- rc = printf( format, INT_MAX );
- printf( "', RC %d\n", rc );
- test( SIZE_MAX, format, INT_MAX );
- }
- puts( "- vanilla -" );
- printf( "No width, no precision: %#x\n", 42 );
- printf( "Width, no precision: %#6x\n", 42 );
- printf( "No width, precision: %#.6x\n", 42 );
- printf( "Big width, small precision: %#6.3x\n", 42 );
- printf( "Small width, big precision: %#3.6x\n", 42 );
- printf( "No width, no precision: %#d\n", 42 );
- printf( "Width, no precision: %#6d\n", 42 );
- printf( "No width, precision: %#.6d\n", 42 );
- printf( "Big width, small precision: %#6.3d\n", 42 );
- printf( "Small width, big precision: %#3.6d\n", 42 );
- puts( "- zero flag -" );
- printf( "No width, no precision: %#0x\n", 42 );
- printf( "Width, no precision: %#06x\n", 42 );
- printf( "No width, precision: %#0.6x\n", 42 );
- printf( "Big width, small precision: %#06.3x\n", 42 );
- printf( "Small width, big precision: %#03.6x\n", 42 );
- printf( "No width, no precision: %#0d\n", 42 );
- printf( "Width, no precision: %#06d\n", 42 );
- printf( "No width, precision: %#0.6d\n", 42 );
- printf( "Big width, small precision: %#06.3d\n", 42 );
- printf( "Small width, big precision: %#03.6d\n", 42 );
- puts( "- plus flag -" );
- printf( "No width, no precision: %#+d\n", 42 );
- printf( "Width, no precision: %#+6d\n", 42 );
- printf( "No width, precision: %#+.6d\n", 42 );
- printf( "Big width, small precision: %#+6.3d\n", 42 );
- printf( "Small width, big precision: %#+3.6d\n", 42 );
- puts( "- plus and zero flag -" );
- printf( "No width, no precision: %#+0d\n", 42 );
- printf( "Width, no precision: %#+06d\n", 42 );
- printf( "No width, precision: %#+0.6d\n", 42 );
- printf( "Big width, small precision: %#+06.3d\n", 42 );
- printf( "Small width, big precision: %#+03.6d\n", 42 );
+ puts( "- Precision -\n" );
+ test( SIZE_MAX, "%030.20d", INT_MAX );
+ test( SIZE_MAX, "%.6x", UINT_MAX );
+ test( SIZE_MAX, "%#6.3x", UINT_MAX );
+ test( SIZE_MAX, "%#3.6x", UINT_MAX );
+ test( SIZE_MAX, "%.6d", INT_MIN );
+ test( SIZE_MAX, "%6.3d", INT_MIN );
+ test( SIZE_MAX, "%3.6d", INT_MIN );
+ test( SIZE_MAX, "%#0.6x", UINT_MAX );
+ test( SIZE_MAX, "%#06.3x", UINT_MAX );
+ test( SIZE_MAX, "%#03.6x", UINT_MAX );
+ test( SIZE_MAX, "%#0.6d", INT_MAX );
+ test( SIZE_MAX, "%#06.3d", INT_MAX );
+ test( SIZE_MAX, "%#03.6d", INT_MAX );
+ test( SIZE_MAX, "%#+.6d", INT_MAX );
+ test( SIZE_MAX, "%#+6.3d", INT_MAX );
+ test( SIZE_MAX, "%#+3.6d", INT_MAX );
+ 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 );
return 0;
}
i - pointer to number of characters already delivered in this call
n - pointer to maximum number of characters to be delivered in this call
s - the buffer into which the character shall be delivered
- TODO: Overruns.
*/
#define DELIVER( x ) do { if ( status->i < status->n ) { if ( status->stream != NULL ) putc( x, status->stream ); else status->s[status->i] = x; } ++(status->i); } while ( 0 )
if ( ( status->flags & E_alt ) && ( status->base == 16 || status->base == 8 ) )
{
/* Octal / hexadecimal prefix for "%#" conversions */
- preface[ preidx++ ] = '0'; /* TODO: For octal, standard states "extend the precision" */
+ preface[ preidx++ ] = '0';
if ( status->base == 16 )
{
preface[ preidx++ ] = ( status->flags & E_lower ) ? 'x' : 'X';
preface[ preidx++ ] = ' ';
}
}
+ {
+ size_t prec_pads = ( status->prec > status->this ) ? ( status->prec - status->this ) : 0;
if ( ! ( status->flags & ( E_minus | E_zero ) ) )
{
/* Space padding is only done if no zero padding or left alignment
for ( int i = 0; i < status->width - characters; ++i )
{
DELIVER( ' ' );
- ++(status->this); /* TODO: Probably have to do something so I still know how many zeroes are required, later. */
+ ++(status->this);
}
}
}
if ( ( ! ( status->flags & E_minus ) ) && ( status->flags & E_zero ) )
{
/* If field is not left aligned, and zero padding is requested, do
- so. TODO: This should include precision handling (probably).
+ so.
*/
while ( status->this < status->width )
{
++(status->this);
}
}
+ /* Do the precision padding if necessary. */
+ for ( int i = 0; i < prec_pads; ++i )
+ {
+ DELIVER( '0' );
+ }
+ }
}
/* Recursion tail - print the current digit. */
{
if ( *(++spec) == '%' )
{
DELIVER( *spec );
- return spec;
+ return ++spec;
}
/* Initializing status structure */
status->flags = 0;
}
spec = endptr;
}
- status->flags &= ! E_zero;
+ /* Having a precision cancels out any zero flag. */
+ status->flags ^= E_zero;
}
/* Optional length modifier