/* 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
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: ref. fputs() for a better way to buffer handling
*/
#define DELIVER( x ) \
do { \
if ( status->i < status->n ) { \
- if ( status->stream != NULL ) { \
- status->stream->buffer[status->stream->bufidx++] = x; \
- if ( ( status->stream->bufidx == status->stream->bufsize ) \
- || ( ( status->stream->status & _IOLBF ) && ( x == '\n' ) ) \
- || ( status->stream->status & _IONBF ) ) \
- fflush( status->stream ); \
- } else \
+ if ( status->stream != NULL ) \
+ putc( x, status->stream ); \
+ else \
status->s[status->i] = x; \
} \
++(status->i); \
already so it will be taken into account when the deepestmost recursion
does the prefix / padding stuff.
*/
- ++(status->this);
+ ++(status->current);
if ( ( value / status->base ) != 0 )
{
/* More digits to be done - recurse deeper */
}
}
{
- size_t prec_pads = ( status->prec > status->this ) ? ( status->prec - status->this ) : 0;
+ size_t prec_pads = ( status->prec > status->current ) ? ( status->prec - status->current ) : 0;
if ( ! ( status->flags & ( E_minus | E_zero ) ) )
{
/* Space padding is only done if no zero padding or left alignment
I've ever perpetrated. Greetings to Samface, DevL, and all
sceners at Breakpoint 2006.
*/
- size_t characters = preidx + ( ( status->this > status->prec ) ? status->this : status->prec );
+ size_t characters = preidx + ( ( status->current > status->prec ) ? status->current : status->prec );
if ( status->width > characters )
{
- for ( int i = 0; i < status->width - characters; ++i )
+ for ( size_t i = 0; i < status->width - characters; ++i )
{
DELIVER( ' ' );
/*
++(status->i);
} while ( 0 );
*/
- ++(status->this);
+ ++(status->current);
}
}
}
while ( preface[ preidx ] != '\0' )
{
DELIVER( preface[ preidx++ ] );
- ++(status->this);
+ ++(status->current);
}
if ( ( ! ( status->flags & E_minus ) ) && ( status->flags & E_zero ) )
{
/* If field is not left aligned, and zero padding is requested, do
so.
*/
- while ( status->this < status->width )
+ while ( status->current < status->width )
{
DELIVER( '0' );
- ++(status->this);
+ ++(status->current);
}
}
/* Do the precision padding if necessary. */
- for ( int i = 0; i < prec_pads; ++i )
+ for ( size_t i = 0; i < prec_pads; ++i )
{
DELIVER( '0' );
}
/* Initializing status structure */
status->flags = 0;
status->base = 0;
- status->this = 0;
+ status->current = 0;
status->width = 0;
status->prec = 0;
if ( *spec == '*' )
{
/* Retrieve width value from argument stack */
- if ( ( status->width = va_arg( status->arg, int ) ) < 0 )
+ int width = va_arg( status->arg, int );
+ if ( width < 0 )
{
- /* Negative value is '-' flag plus absolute value */
status->flags |= E_minus;
- status->width *= -1;
+ status->width = abs( width );
+ }
+ else
+ {
+ status->width = width;
}
++spec;
}
value = (uintmax_t)va_arg( status->arg, size_t );
break;
}
- ++(status->this);
+ ++(status->current);
if ( ( value / status->base ) != 0 )
{
int2base( (intmax_t)(value / status->base), status );
}
if ( status->flags & E_minus )
{
- while ( status->this < status->width )
+ while ( status->current < status->width )
{
DELIVER( ' ' );
- ++(status->this);
+ ++(status->current);
}
}
if ( status->i >= status->n )
static int testprintf( char * buffer, size_t n, const char * format, ... )
{
- /* Members: base, flags, n, i, this, s, width, prec, stream, arg */
- struct _PDCLIB_status_t status = { 0, 0, n, 0, 0, buffer, 0, 0, NULL, NULL };
- memset( buffer, '\0', 100 );
+ /* Members: base, flags, n, i, current, s, width, prec, stream, arg */
+ struct _PDCLIB_status_t status;
+ status.base = 0;
+ status.flags = 0;
+ status.n = n;
+ status.i = 0;
+ status.current = 0;
+ status.s = buffer;
+ status.width = 0;
+ status.prec = 0;
+ status.stream = NULL;
va_start( status.arg, format );
+ memset( buffer, '\0', 100 );
if ( *(_PDCLIB_print( format, &status )) != '\0' )
{
printf( "_PDCLIB_print() did not return end-of-specifier on '%s'.\n", format );