david/ipxe
Archived
1
0

[libc] Allow for zero-padded decimals in printf()

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown 2011-07-06 14:52:53 +01:00
parent 1b8984eb5d
commit 66cbae73bd

View File

@ -60,12 +60,21 @@ static uint8_t type_sizes[] = {
*/ */
#define ALT_FORM 0x02 #define ALT_FORM 0x02
/**
* Use zero padding
*
* Note that this value is set to 0x10 since that allows the pad
* character to be calculated as @c 0x20|(flags&ZPAD)
*/
#define ZPAD 0x10
/** /**
* Format a hexadecimal number * Format a hexadecimal number
* *
* @v end End of buffer to contain number * @v end End of buffer to contain number
* @v num Number to format * @v num Number to format
* @v width Minimum field width * @v width Minimum field width
* @v flags Format flags
* @ret ptr End of buffer * @ret ptr End of buffer
* *
* Fills a buffer in reverse order with a formatted hexadecimal * Fills a buffer in reverse order with a formatted hexadecimal
@ -79,18 +88,18 @@ static uint8_t type_sizes[] = {
static char * format_hex ( char *end, unsigned long long num, int width, static char * format_hex ( char *end, unsigned long long num, int width,
int flags ) { int flags ) {
char *ptr = end; char *ptr = end;
int case_mod; int case_mod = ( flags & LCASE );
int pad = ( ( flags & ZPAD ) | ' ' );
/* Generate the number */ /* Generate the number */
case_mod = flags & LCASE;
do { do {
*(--ptr) = "0123456789ABCDEF"[ num & 0xf ] | case_mod; *(--ptr) = "0123456789ABCDEF"[ num & 0xf ] | case_mod;
num >>= 4; num >>= 4;
} while ( num ); } while ( num );
/* Zero-pad to width */ /* Pad to width */
while ( ( end - ptr ) < width ) while ( ( end - ptr ) < width )
*(--ptr) = '0'; *(--ptr) = pad;
/* Add "0x" or "0X" if alternate form specified */ /* Add "0x" or "0X" if alternate form specified */
if ( flags & ALT_FORM ) { if ( flags & ALT_FORM ) {
@ -107,6 +116,7 @@ static char * format_hex ( char *end, unsigned long long num, int width,
* @v end End of buffer to contain number * @v end End of buffer to contain number
* @v num Number to format * @v num Number to format
* @v width Minimum field width * @v width Minimum field width
* @v flags Format flags
* @ret ptr End of buffer * @ret ptr End of buffer
* *
* Fills a buffer in reverse order with a formatted decimal number. * Fills a buffer in reverse order with a formatted decimal number.
@ -115,9 +125,12 @@ static char * format_hex ( char *end, unsigned long long num, int width,
* There must be enough space in the buffer to contain the largest * There must be enough space in the buffer to contain the largest
* number that this function can format. * number that this function can format.
*/ */
static char * format_decimal ( char *end, signed long num, int width ) { static char * format_decimal ( char *end, signed long num, int width,
int flags ) {
char *ptr = end; char *ptr = end;
int negative = 0; int negative = 0;
int zpad = ( flags & ZPAD );
int pad = ( zpad | ' ' );
/* Generate the number */ /* Generate the number */
if ( num < 0 ) { if ( num < 0 ) {
@ -130,12 +143,16 @@ static char * format_decimal ( char *end, signed long num, int width ) {
} while ( num ); } while ( num );
/* Add "-" if necessary */ /* Add "-" if necessary */
if ( negative ) if ( negative && ( ! zpad ) )
*(--ptr) = '-'; *(--ptr) = '-';
/* Space-pad to width */ /* Pad to width */
while ( ( end - ptr ) < width ) while ( ( end - ptr ) < width )
*(--ptr) = ' '; *(--ptr) = pad;
/* Add "-" if necessary */
if ( negative && zpad )
*ptr = '-';
return ptr; return ptr;
} }
@ -186,7 +203,7 @@ size_t vcprintf ( struct printf_context *ctx, const char *fmt, va_list args ) {
if ( *fmt == '#' ) { if ( *fmt == '#' ) {
flags |= ALT_FORM; flags |= ALT_FORM;
} else if ( *fmt == '0' ) { } else if ( *fmt == '0' ) {
/* We always 0-pad hex and space-pad decimal */ flags |= ZPAD;
} else { } else {
/* End of flag characters */ /* End of flag characters */
break; break;
@ -250,7 +267,7 @@ size_t vcprintf ( struct printf_context *ctx, const char *fmt, va_list args ) {
} else { } else {
decimal = va_arg ( args, signed int ); decimal = va_arg ( args, signed int );
} }
ptr = format_decimal ( ptr, decimal, width ); ptr = format_decimal ( ptr, decimal, width, flags );
} else { } else {
*(--ptr) = *fmt; *(--ptr) = *fmt;
} }