[libc] Allow for zero-padded decimals in printf()
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
parent
1b8984eb5d
commit
66cbae73bd
@ -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;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user