diff options
| author | Michael Brown | 2011-07-06 15:52:53 +0200 |
|---|---|---|
| committer | Michael Brown | 2011-07-06 15:52:53 +0200 |
| commit | 66cbae73bd6c7a7c87647cb0fe9fa761f9a51aaf (patch) | |
| tree | 6518f7d15ed89e51f148ee7c3c40362434bca8f4 /src/core | |
| parent | [iscsi] Avoid duplicate calls to iscsi_tx_done() (diff) | |
| download | ipxe-66cbae73bd6c7a7c87647cb0fe9fa761f9a51aaf.tar.gz ipxe-66cbae73bd6c7a7c87647cb0fe9fa761f9a51aaf.tar.xz ipxe-66cbae73bd6c7a7c87647cb0fe9fa761f9a51aaf.zip | |
[libc] Allow for zero-padded decimals in printf()
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/vsprintf.c | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/src/core/vsprintf.c b/src/core/vsprintf.c index b46d9c419..b838b89e5 100644 --- a/src/core/vsprintf.c +++ b/src/core/vsprintf.c @@ -61,11 +61,20 @@ static uint8_t type_sizes[] = { #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 * * @v end End of buffer to contain number * @v num Number to format * @v width Minimum field width + * @v flags Format flags * @ret ptr End of buffer * * 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, int flags ) { char *ptr = end; - int case_mod; + int case_mod = ( flags & LCASE ); + int pad = ( ( flags & ZPAD ) | ' ' ); /* Generate the number */ - case_mod = flags & LCASE; do { *(--ptr) = "0123456789ABCDEF"[ num & 0xf ] | case_mod; num >>= 4; } while ( num ); - /* Zero-pad to width */ + /* Pad to width */ while ( ( end - ptr ) < width ) - *(--ptr) = '0'; + *(--ptr) = pad; /* Add "0x" or "0X" if alternate form specified */ 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 num Number to format * @v width Minimum field width + * @v flags Format flags * @ret ptr End of buffer * * 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 * 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; int negative = 0; + int zpad = ( flags & ZPAD ); + int pad = ( zpad | ' ' ); /* Generate the number */ if ( num < 0 ) { @@ -130,12 +143,16 @@ static char * format_decimal ( char *end, signed long num, int width ) { } while ( num ); /* Add "-" if necessary */ - if ( negative ) + if ( negative && ( ! zpad ) ) *(--ptr) = '-'; - /* Space-pad to width */ + /* Pad to width */ while ( ( end - ptr ) < width ) - *(--ptr) = ' '; + *(--ptr) = pad; + + /* Add "-" if necessary */ + if ( negative && zpad ) + *ptr = '-'; return ptr; } @@ -186,7 +203,7 @@ size_t vcprintf ( struct printf_context *ctx, const char *fmt, va_list args ) { if ( *fmt == '#' ) { flags |= ALT_FORM; } else if ( *fmt == '0' ) { - /* We always 0-pad hex and space-pad decimal */ + flags |= ZPAD; } else { /* End of flag characters */ break; @@ -250,7 +267,7 @@ size_t vcprintf ( struct printf_context *ctx, const char *fmt, va_list args ) { } else { decimal = va_arg ( args, signed int ); } - ptr = format_decimal ( ptr, decimal, width ); + ptr = format_decimal ( ptr, decimal, width, flags ); } else { *(--ptr) = *fmt; } |
