Rev 992 | Rev 1010 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 992 | Rev 995 | ||
---|---|---|---|
Line 30... | Line 30... | ||
30 | #include <stdio.h> |
30 | #include <stdio.h> |
31 | #include <unistd.h> |
31 | #include <unistd.h> |
32 | #include <io/io.h> |
32 | #include <io/io.h> |
33 | #include <stdarg.h> |
33 | #include <stdarg.h> |
34 | 34 | ||
- | 35 | #define __PRINTF_FLAG_PREFIX 0x00000001 |
|
- | 36 | #define __PRINTF_FLAG_SIGNED 0x00000002 |
|
- | 37 | ||
35 | static char digits[] = "0123456789abcdef"; /**< Hexadecimal characters */ |
38 | static char digits[] = "0123456789abcdef"; /**< Hexadecimal characters */ |
36 | 39 | ||
37 | /** Print hexadecimal digits |
40 | /** Print hexadecimal digits |
38 | * |
41 | * |
39 | * Print fixed count of hexadecimal digits from |
42 | * Print fixed count of hexadecimal digits from |
Line 43... | Line 46... | ||
43 | * |
46 | * |
44 | * @param num Number containing digits. |
47 | * @param num Number containing digits. |
45 | * @param width Count of digits to print. |
48 | * @param width Count of digits to print. |
46 | * |
49 | * |
47 | */ |
50 | */ |
48 | static int print_fixed_hex(const uint64_t num, const int width) |
51 | static int print_fixed_hex(const uint64_t num, const int width, uint64_t flags) |
49 | { |
52 | { |
50 | int i; |
53 | int i; |
51 | char buf[16]; |
54 | char buf[18]; /* 16 bytes for number + 2 for optionaly prefix */ |
52 | char *bptr; |
55 | char *bptr; |
53 | 56 | ||
54 | bptr = buf; |
57 | bptr = buf; |
- | 58 | ||
- | 59 | if (flags & __PRINTF_FLAG_PREFIX) { |
|
- | 60 | buf[0] = '0'; |
|
- | 61 | buf[1] = 'x'; |
|
- | 62 | bptr += 2; |
|
- | 63 | } |
|
- | 64 | ||
55 | for (i = width*8 - 4; i >= 0; i -= 4) |
65 | for (i = width*8 - 4; i >= 0; i -= 4) |
56 | *bptr++ = digits[(num>>i) & 0xf]; |
66 | *bptr++ = digits[(num>>i) & 0xf]; |
57 | *bptr = '\0'; |
67 | *bptr = '\0'; |
58 | 68 | ||
59 | return putstr(buf); |
69 | return putstr(buf); |
Line 68... | Line 78... | ||
68 | * @param num Number to print. |
78 | * @param num Number to print. |
69 | * @param base Base to print the number in (should |
79 | * @param base Base to print the number in (should |
70 | * be in range 2 .. 16). |
80 | * be in range 2 .. 16). |
71 | * |
81 | * |
72 | */ |
82 | */ |
73 | static int print_number(const unsigned int num, const unsigned int base) |
83 | static int print_number(const unsigned long num, const unsigned int base, uint64_t flags) |
74 | { |
84 | { |
75 | int val = num; |
85 | int val = num; |
76 | char d[sizeof(unsigned int)*8+1]; /* this is good enough even for base == 2 */ |
86 | char d[sizeof(unsigned long)*8+1]; /* this is good enough even for base == 2 */ |
77 | int i = sizeof(unsigned int)*8-1; |
87 | int i = sizeof(unsigned long)*8-1; |
- | 88 | ||
- | 89 | /* FIXME: if signed, print sign */ |
|
78 | 90 | ||
79 | do { |
91 | do { |
80 | d[i--] = digits[val % base]; |
92 | d[i--] = digits[val % base]; |
81 | } while (val /= base); |
93 | } while (val /= base); |
82 | 94 | ||
83 | d[sizeof(unsigned int)*8] = 0; |
95 | d[sizeof(unsigned long)*8] = 0; |
84 | 96 | ||
85 | return putstr(&d[i + 1]); |
97 | return putstr(&d[i + 1]); |
86 | } |
98 | } |
87 | 99 | ||
88 | 100 | ||
Line 146... | Line 158... | ||
146 | { |
158 | { |
147 | int i = 0, j = 0; |
159 | int i = 0, j = 0; |
148 | int counter, retval; |
160 | int counter, retval; |
149 | va_list ap; |
161 | va_list ap; |
150 | char c; |
162 | char c; |
- | 163 | ||
- | 164 | uint64_t flags; |
|
151 | 165 | ||
152 | counter = 0; |
166 | counter = 0; |
153 | va_start(ap, fmt); |
167 | va_start(ap, fmt); |
154 | 168 | ||
155 | while ((c = fmt[i])) { |
169 | while ((c = fmt[i])) { |
156 | /* control character */ |
170 | /* control character */ |
157 | if (c == '%' ) { |
171 | if (c == '%' ) { |
158 | /* print common characters if any processed */ |
172 | /* print common characters if any processed */ |
159 | if (i > j) { |
173 | if (i > j) { |
160 | if ((retval = putnchars(&fmt[j], i - j)) == EOF) { /* error */ |
174 | if ((retval = putnchars(&fmt[j], (size_t)(i - j))) == EOF) { /* error */ |
161 | return -counter; |
175 | return -counter; |
162 | } |
176 | } |
163 | counter += retval; |
177 | counter += retval; |
164 | } |
178 | } |
165 | 179 | ||
166 | j = ++i; |
180 | j = ++i; |
167 | 181 | ||
- | 182 | /* parse modifiers */ |
|
- | 183 | flags = 0; |
|
- | 184 | /*switch (c = fmt[i]) { |
|
- | 185 | case '-': |
|
- | 186 | } |
|
- | 187 | */ |
|
168 | switch (c = fmt[i]) { |
188 | switch (c = fmt[i]) { |
169 | 189 | ||
170 | /* percentile itself */ |
190 | /* percentile itself */ |
171 | case '%': |
191 | case '%': |
172 | --j; /* soon will be incremented back */ |
192 | --j; /* soon will be incremented back */ |
Line 181... | Line 201... | ||
181 | }; |
201 | }; |
182 | 202 | ||
183 | counter += retval; |
203 | counter += retval; |
184 | break; |
204 | break; |
185 | case 'c': |
205 | case 'c': |
186 | if ((retval = putnchars((char *)&va_arg(ap, int), sizeof(char))) == EOF) { |
206 | if ((retval = putnchars((char *)&va_arg(ap, unsigned long), sizeof(char))) == EOF) { |
187 | return -counter; |
207 | return -counter; |
188 | }; |
208 | }; |
189 | 209 | ||
190 | counter += retval; |
210 | counter += retval; |
191 | break; |
211 | break; |
192 | 212 | ||
193 | /* |
213 | /* |
194 | * Hexadecimal conversions with fixed width. |
214 | * Hexadecimal conversions with fixed width. |
195 | */ |
215 | */ |
196 | case 'P': |
216 | case 'P': |
197 | if ((retval = putnchars("0x", 2)) == EOF) { |
217 | flags |= __PRINTF_FLAG_PREFIX; |
198 | return -counter; |
- | |
199 | }; |
- | |
200 | - | ||
201 | counter += retval; |
- | |
202 | case 'p': |
218 | case 'p': |
203 | if ((retval = print_fixed_hex(va_arg(ap, int), sizeof(int))) == EOF ) { |
219 | if ((retval = print_fixed_hex(va_arg(ap, unsigned long), sizeof(unsigned long), flags)) == EOF ) { |
204 | return -counter; |
220 | return -counter; |
205 | }; |
221 | }; |
206 | 222 | ||
207 | counter += retval; |
223 | counter += retval; |
208 | break; |
224 | break; |
209 | case 'Q': |
225 | case 'Q': |
210 | if ((retval = putnchars("0x", 2)) == EOF) { |
226 | flags |= __PRINTF_FLAG_PREFIX; |
211 | return -counter; |
- | |
212 | }; |
- | |
213 | - | ||
214 | counter += retval; |
- | |
215 | case 'q': |
227 | case 'q': |
216 | if ((retval = print_fixed_hex(va_arg(ap, uint64_t), sizeof(uint64_t))) == EOF ) { |
228 | if ((retval = print_fixed_hex(va_arg(ap, uint64_t), sizeof(uint64_t), flags)) == EOF ) { |
217 | return -counter; |
229 | return -counter; |
218 | }; |
230 | }; |
219 | 231 | ||
220 | counter += retval; |
232 | counter += retval; |
221 | break; |
233 | break; |
222 | case 'L': |
234 | case 'L': |
223 | if ((retval = putnchars("0x", 2)) == EOF) { |
235 | flags |= __PRINTF_FLAG_PREFIX; |
224 | return -counter; |
- | |
225 | }; |
- | |
226 | - | ||
227 | counter += retval; |
- | |
228 | case 'l': |
236 | case 'l': |
229 | if ((retval = print_fixed_hex(va_arg(ap, int), sizeof(uint32_t))) == EOF ) { |
237 | if ((retval = print_fixed_hex(va_arg(ap, unsigned long), sizeof(uint32_t), flags)) == EOF ) { |
230 | return -counter; |
238 | return -counter; |
231 | }; |
239 | }; |
232 | 240 | ||
233 | counter += retval; |
241 | counter += retval; |
234 | break; |
242 | break; |
235 | case 'W': |
243 | case 'W': |
236 | if ((retval = putnchars("0x", 2)) == EOF) { |
244 | flags |= __PRINTF_FLAG_PREFIX; |
237 | return -counter; |
- | |
238 | }; |
- | |
239 | - | ||
240 | counter += retval; |
- | |
241 | case 'w': |
245 | case 'w': |
242 | if ((retval = print_fixed_hex(va_arg(ap, int), sizeof(uint16_t))) == EOF ) { |
246 | if ((retval = print_fixed_hex(va_arg(ap, unsigned long), sizeof(uint16_t), flags)) == EOF ) { |
243 | return -counter; |
247 | return -counter; |
244 | }; |
248 | }; |
245 | 249 | ||
246 | counter += retval; |
250 | counter += retval; |
247 | break; |
251 | break; |
248 | case 'B': |
252 | case 'B': |
249 | if ((retval = putnchars("0x", 2)) == EOF) { |
253 | flags |= __PRINTF_FLAG_PREFIX; |
250 | return -counter; |
- | |
251 | }; |
- | |
252 | - | ||
253 | counter += retval; |
- | |
254 | case 'b': |
254 | case 'b': |
255 | if ((retval = print_fixed_hex(va_arg(ap, int), sizeof(uint8_t))) == EOF ) { |
255 | if ((retval = print_fixed_hex(va_arg(ap, unsigned long), sizeof(uint8_t), flags)) == EOF ) { |
256 | return -counter; |
256 | return -counter; |
257 | }; |
257 | }; |
258 | 258 | ||
259 | counter += retval; |
259 | counter += retval; |
260 | break; |
260 | break; |
261 | /* |
261 | /* |
262 | * Decimal and hexadecimal conversions. |
262 | * Decimal and hexadecimal conversions. |
263 | */ |
263 | */ |
264 | case 'd': |
264 | case 'd': |
- | 265 | case 'i': |
|
- | 266 | flags |= __PRINTF_FLAG_SIGNED; |
|
265 | if ((retval = print_number(va_arg(ap, int), 10)) == EOF ) { |
267 | if ((retval = print_number(va_arg(ap,unsigned long), 10, flags)) == EOF ) { |
266 | return -counter; |
268 | return -counter; |
267 | }; |
269 | }; |
268 | 270 | ||
269 | counter += retval; |
271 | counter += retval; |
270 | break; |
272 | break; |
271 | case 'X': |
273 | case 'X': |
272 | if ((retval = putnchars("0x", 2)) == EOF) { |
274 | flags |= __PRINTF_FLAG_PREFIX; |
273 | return -counter; |
- | |
274 | }; |
- | |
275 | - | ||
276 | counter += retval; |
- | |
277 | case 'x': |
275 | case 'x': |
278 | if ((retval = print_number(va_arg(ap, int), 16)) == EOF ) { |
276 | if ((retval = print_number(va_arg(ap, unsigned long), 16, flags)) == EOF ) { |
279 | return -counter; |
277 | return -counter; |
280 | }; |
278 | }; |
281 | 279 | ||
282 | counter += retval; |
280 | counter += retval; |
283 | break; |
281 | break; |
Line 291... | Line 289... | ||
291 | } |
289 | } |
292 | ++i; |
290 | ++i; |
293 | } |
291 | } |
294 | 292 | ||
295 | if (i > j) { |
293 | if (i > j) { |
296 | if ((retval = putnchars(&fmt[j], i - j)) == EOF) { /* error */ |
294 | if ((retval = putnchars(&fmt[j], (size_t)(i - j))) == EOF) { /* error */ |
297 | return -counter; |
295 | return -counter; |
298 | } |
296 | } |
299 | counter += retval; |
297 | counter += retval; |
300 | } |
298 | } |
301 | 299 |