Browse Source

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

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 13 years ago
parent
commit
66cbae73bd
1 changed files with 27 additions and 10 deletions
  1. 27
    10
      src/core/vsprintf.c

+ 27
- 10
src/core/vsprintf.c View File

@@ -60,12 +60,21 @@ static uint8_t type_sizes[] = {
60 60
  */
61 61
 #define ALT_FORM 0x02
62 62
 
63
+/**
64
+ * Use zero padding
65
+ *
66
+ * Note that this value is set to 0x10 since that allows the pad
67
+ * character to be calculated as @c 0x20|(flags&ZPAD)
68
+ */
69
+#define ZPAD 0x10
70
+
63 71
 /**
64 72
  * Format a hexadecimal number
65 73
  *
66 74
  * @v end		End of buffer to contain number
67 75
  * @v num		Number to format
68 76
  * @v width		Minimum field width
77
+ * @v flags		Format flags
69 78
  * @ret ptr		End of buffer
70 79
  *
71 80
  * Fills a buffer in reverse order with a formatted hexadecimal
@@ -79,18 +88,18 @@ static uint8_t type_sizes[] = {
79 88
 static char * format_hex ( char *end, unsigned long long num, int width,
80 89
 			   int flags ) {
81 90
 	char *ptr = end;
82
-	int case_mod;
91
+	int case_mod = ( flags & LCASE );
92
+	int pad = ( ( flags & ZPAD ) | ' ' );
83 93
 
84 94
 	/* Generate the number */
85
-	case_mod = flags & LCASE;
86 95
 	do {
87 96
 		*(--ptr) = "0123456789ABCDEF"[ num & 0xf ] | case_mod;
88 97
 		num >>= 4;
89 98
 	} while ( num );
90 99
 
91
-	/* Zero-pad to width */
100
+	/* Pad to width */
92 101
 	while ( ( end - ptr ) < width )
93
-		*(--ptr) = '0';
102
+		*(--ptr) = pad;
94 103
 
95 104
 	/* Add "0x" or "0X" if alternate form specified */
96 105
 	if ( flags & ALT_FORM ) {
@@ -107,6 +116,7 @@ static char * format_hex ( char *end, unsigned long long num, int width,
107 116
  * @v end		End of buffer to contain number
108 117
  * @v num		Number to format
109 118
  * @v width		Minimum field width
119
+ * @v flags		Format flags
110 120
  * @ret ptr		End of buffer
111 121
  *
112 122
  * 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,
115 125
  * There must be enough space in the buffer to contain the largest
116 126
  * number that this function can format.
117 127
  */
118
-static char * format_decimal ( char *end, signed long num, int width ) {
128
+static char * format_decimal ( char *end, signed long num, int width,
129
+			       int flags ) {
119 130
 	char *ptr = end;
120 131
 	int negative = 0;
132
+	int zpad = ( flags & ZPAD );
133
+	int pad = ( zpad | ' ' );
121 134
 
122 135
 	/* Generate the number */
123 136
 	if ( num < 0 ) {
@@ -130,12 +143,16 @@ static char * format_decimal ( char *end, signed long num, int width ) {
130 143
 	} while ( num );
131 144
 
132 145
 	/* Add "-" if necessary */
133
-	if ( negative )
146
+	if ( negative && ( ! zpad ) )
134 147
 		*(--ptr) = '-';
135 148
 
136
-	/* Space-pad to width */
149
+	/* Pad to width */
137 150
 	while ( ( end - ptr ) < width )
138
-		*(--ptr) = ' ';
151
+		*(--ptr) = pad;
152
+
153
+	/* Add "-" if necessary */
154
+	if ( negative && zpad )
155
+		*ptr = '-';
139 156
 
140 157
 	return ptr;
141 158
 }
@@ -186,7 +203,7 @@ size_t vcprintf ( struct printf_context *ctx, const char *fmt, va_list args ) {
186 203
 			if ( *fmt == '#' ) {
187 204
 				flags |= ALT_FORM;
188 205
 			} else if ( *fmt == '0' ) {
189
-				/* We always 0-pad hex and space-pad decimal */
206
+				flags |= ZPAD;
190 207
 			} else {
191 208
 				/* End of flag characters */
192 209
 				break;
@@ -250,7 +267,7 @@ size_t vcprintf ( struct printf_context *ctx, const char *fmt, va_list args ) {
250 267
 			} else {
251 268
 				decimal = va_arg ( args, signed int );
252 269
 			}
253
-			ptr = format_decimal ( ptr, decimal, width );
270
+			ptr = format_decimal ( ptr, decimal, width, flags );
254 271
 		} else {
255 272
 			*(--ptr) = *fmt;
256 273
 		}

Loading…
Cancel
Save