Rev 4209 | Rev 4213 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4209 | Rev 4210 | ||
---|---|---|---|
Line 112... | Line 112... | ||
112 | printf_spec_t *ps) |
112 | printf_spec_t *ps) |
113 | { |
113 | { |
114 | return ps->write_utf32((void *) buf, size, ps->data); |
114 | return ps->write_utf32((void *) buf, size, ps->data); |
115 | } |
115 | } |
116 | 116 | ||
117 | /** Print UTF-8 string without adding a newline. |
117 | /** Print string without adding newline. |
118 | * |
118 | * |
119 | * @param str UTF-8 string to print. |
119 | * @param str String to print. |
120 | * @param ps Write function specification and support data. |
120 | * @param ps Write function specification and support data. |
121 | * |
121 | * |
122 | * @return Number of UTF-8 characters printed. |
122 | * @return Number of characters printed. |
123 | * |
123 | * |
124 | */ |
124 | */ |
125 | static int printf_putstr(const char *str, printf_spec_t *ps) |
125 | static int printf_putstr(const char *str, printf_spec_t *ps) |
126 | { |
126 | { |
127 | if (str == NULL) |
127 | if (str == NULL) |
Line 236... | Line 236... | ||
236 | } |
236 | } |
237 | 237 | ||
238 | return (int) (counter + 1); |
238 | return (int) (counter + 1); |
239 | } |
239 | } |
240 | 240 | ||
241 | /** Print UTF-8 string. |
241 | /** Format and print a string. |
242 | * |
242 | * |
243 | * @param str UTF-8 string to be printed. |
243 | * @param str String to be printed. |
244 | * @param width Width modifier. |
244 | * @param width Width modifier. |
245 | * @param precision Precision modifier. |
245 | * @param precision Precision modifier. |
246 | * @param flags Flags that modify the way the string is printed. |
246 | * @param flags Flags that modify the way the string is printed. |
247 | * |
247 | * |
248 | * @return Number of UTF-8 characters printed, negative value on failure. |
248 | * @return Number of characters printed, negative value on failure. |
249 | */ |
249 | */ |
250 | static int print_utf8(char *str, int width, unsigned int precision, |
250 | static int print_str(char *str, int width, unsigned int precision, |
251 | uint32_t flags, printf_spec_t *ps) |
251 | uint32_t flags, printf_spec_t *ps) |
252 | { |
252 | { |
253 | if (str == NULL) |
253 | if (str == NULL) |
254 | return printf_putstr(nullstr, ps); |
254 | return printf_putstr(nullstr, ps); |
255 | 255 | ||
256 | /* Print leading spaces. */ |
256 | /* Print leading spaces. */ |
257 | count_t strw = str_length(str); |
257 | count_t strw = str_length(str); |
258 | if (precision == 0) |
258 | if (precision == 0) |
259 | precision = strw; |
259 | precision = strw; |
260 | 260 | ||
- | 261 | /* Left padding */ |
|
261 | count_t counter = 0; |
262 | count_t counter = 0; |
262 | width -= precision; |
263 | width -= precision; |
263 | if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) { |
264 | if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) { |
264 | while (width-- > 0) { |
265 | while (width-- > 0) { |
265 | if (printf_putchar(' ', ps) == 1) |
266 | if (printf_putchar(' ', ps) == 1) |
266 | counter++; |
267 | counter++; |
267 | } |
268 | } |
268 | } |
269 | } |
269 | 270 | ||
- | 271 | /* Part of @a str fitting into the alloted space. */ |
|
270 | int retval; |
272 | int retval; |
271 | size_t size = str_wsize(str, precision); |
273 | size_t size = str_wsize(str, precision); |
272 | if ((retval = printf_putnchars_utf8(str, size, ps)) < 0) |
274 | if ((retval = printf_putnchars_utf8(str, size, ps)) < 0) |
273 | return -counter; |
275 | return -counter; |
274 | 276 | ||
275 | counter += retval; |
277 | counter += retval; |
276 | 278 | ||
- | 279 | /* Right padding */ |
|
277 | while (width-- > 0) { |
280 | while (width-- > 0) { |
278 | if (printf_putchar(' ', ps) == 1) |
281 | if (printf_putchar(' ', ps) == 1) |
279 | counter++; |
282 | counter++; |
280 | } |
283 | } |
281 | 284 | ||
282 | return ((int) counter); |
285 | return ((int) counter); |
283 | 286 | ||
284 | } |
287 | } |
285 | 288 | ||
286 | /** Print UTF-32 string. |
289 | /** Format and print a wide string. |
287 | * |
290 | * |
288 | * @param str UTF-32 string to be printed. |
291 | * @param wstr Wide string to be printed. |
289 | * @param width Width modifier. |
292 | * @param width Width modifier. |
290 | * @param precision Precision modifier. |
293 | * @param precision Precision modifier. |
291 | * @param flags Flags that modify the way the string is printed. |
294 | * @param flags Flags that modify the way the string is printed. |
292 | * |
295 | * |
293 | * @return Number of UTF-32 characters printed, negative value on failure. |
296 | * @return Number of characters printed, negative value |
- | 297 | * on failure. |
|
294 | */ |
298 | */ |
295 | static int print_utf32(wchar_t *wstr, int width, unsigned int precision, |
299 | static int print_wstr(wchar_t *wstr, int width, unsigned int precision, |
296 | uint32_t flags, printf_spec_t *ps) |
300 | uint32_t flags, printf_spec_t *ps) |
297 | { |
301 | { |
298 | if (wstr == NULL) |
302 | if (wstr == NULL) |
299 | return printf_putstr(nullstr, ps); |
303 | return printf_putstr(nullstr, ps); |
300 | 304 | ||
301 | /* Print leading spaces. */ |
305 | /* Print leading spaces. */ |
302 | size_t strw = wstr_length(wstr); |
306 | size_t strw = wstr_length(wstr); |
303 | if (precision == 0) |
307 | if (precision == 0) |
304 | precision = strw; |
308 | precision = strw; |
305 | 309 | ||
- | 310 | /* Left padding */ |
|
306 | count_t counter = 0; |
311 | count_t counter = 0; |
307 | width -= precision; |
312 | width -= precision; |
308 | if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) { |
313 | if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) { |
309 | while (width-- > 0) { |
314 | while (width-- > 0) { |
310 | if (printf_putchar(' ', ps) == 1) |
315 | if (printf_putchar(' ', ps) == 1) |
311 | counter++; |
316 | counter++; |
312 | } |
317 | } |
313 | } |
318 | } |
314 | 319 | ||
- | 320 | /* Part of @a wstr fitting into the alloted space. */ |
|
315 | int retval; |
321 | int retval; |
316 | size_t size = wstr_wlength(wstr, precision) * sizeof(wchar_t); |
322 | size_t size = wstr_wlength(wstr, precision) * sizeof(wchar_t); |
317 | if ((retval = printf_putnchars_utf32(wstr, size, ps)) < 0) |
323 | if ((retval = printf_putnchars_utf32(wstr, size, ps)) < 0) |
318 | return -counter; |
324 | return -counter; |
319 | 325 | ||
320 | counter += retval; |
326 | counter += retval; |
321 | 327 | ||
- | 328 | /* Right padding */ |
|
322 | while (width-- > 0) { |
329 | while (width-- > 0) { |
323 | if (printf_putchar(' ', ps) == 1) |
330 | if (printf_putchar(' ', ps) == 1) |
324 | counter++; |
331 | counter++; |
325 | } |
332 | } |
326 | 333 | ||
Line 414... | Line 421... | ||
414 | if (flags & __PRINTF_FLAG_ZEROPADDED) { |
421 | if (flags & __PRINTF_FLAG_ZEROPADDED) { |
415 | if ((precision == 0) && (width > size)) |
422 | if ((precision == 0) && (width > size)) |
416 | precision = width - size + number_size; |
423 | precision = width - size + number_size; |
417 | } |
424 | } |
418 | 425 | ||
419 | /* Print leading spaces */ |
426 | /* Print leading spaces. */ |
420 | if (number_size > precision) { |
427 | if (number_size > precision) { |
421 | /* Print the whole number, not only a part */ |
428 | /* Print the whole number, not only a part. */ |
422 | precision = number_size; |
429 | precision = number_size; |
423 | } |
430 | } |
424 | 431 | ||
425 | width -= precision + size - number_size; |
432 | width -= precision + size - number_size; |
426 | count_t counter = 0; |
433 | count_t counter = 0; |
Line 430... | Line 437... | ||
430 | if (printf_putchar(' ', ps) == 1) |
437 | if (printf_putchar(' ', ps) == 1) |
431 | counter++; |
438 | counter++; |
432 | } |
439 | } |
433 | } |
440 | } |
434 | 441 | ||
435 | /* Print sign */ |
442 | /* Print sign. */ |
436 | if (sgn) { |
443 | if (sgn) { |
437 | if (printf_putchar(sgn, ps) == 1) |
444 | if (printf_putchar(sgn, ps) == 1) |
438 | counter++; |
445 | counter++; |
439 | } |
446 | } |
440 | 447 | ||
441 | /* Print prefix */ |
448 | /* Print prefix. */ |
442 | if (flags & __PRINTF_FLAG_PREFIX) { |
449 | if (flags & __PRINTF_FLAG_PREFIX) { |
443 | switch(base) { |
450 | switch(base) { |
444 | case 2: |
451 | case 2: |
445 | /* Binary formating is not standard, but usefull */ |
452 | /* Binary formating is not standard, but usefull */ |
446 | if (printf_putchar('0', ps) == 1) |
453 | if (printf_putchar('0', ps) == 1) |
Line 469... | Line 476... | ||
469 | } |
476 | } |
470 | break; |
477 | break; |
471 | } |
478 | } |
472 | } |
479 | } |
473 | 480 | ||
474 | /* Print leading zeroes */ |
481 | /* Print leading zeroes. */ |
475 | precision -= number_size; |
482 | precision -= number_size; |
476 | while (precision-- > 0) { |
483 | while (precision-- > 0) { |
477 | if (printf_putchar('0', ps) == 1) |
484 | if (printf_putchar('0', ps) == 1) |
478 | counter++; |
485 | counter++; |
479 | } |
486 | } |
480 | 487 | ||
481 | /* Print the number itself */ |
488 | /* Print the number itself. */ |
482 | int retval; |
489 | int retval; |
483 | if ((retval = printf_putstr(++ptr, ps)) > 0) |
490 | if ((retval = printf_putstr(++ptr, ps)) > 0) |
484 | counter += retval; |
491 | counter += retval; |
485 | 492 | ||
486 | /* Print tailing spaces */ |
493 | /* Print tailing spaces. */ |
487 | 494 | ||
488 | while (width-- > 0) { |
495 | while (width-- > 0) { |
489 | if (printf_putchar(' ', ps) == 1) |
496 | if (printf_putchar(' ', ps) == 1) |
490 | counter++; |
497 | counter++; |
491 | } |
498 | } |
Line 573... | Line 580... | ||
573 | * - u Print unsigned decimal number. |
580 | * - u Print unsigned decimal number. |
574 | * |
581 | * |
575 | * - X, x Print hexadecimal number with upper- or lower-case. Prefix is |
582 | * - X, x Print hexadecimal number with upper- or lower-case. Prefix is |
576 | * not printed by default. |
583 | * not printed by default. |
577 | * |
584 | * |
578 | * All other characters from fmt except the formatting directives are printed in |
585 | * All other characters from fmt except the formatting directives are printed |
579 | * verbatim. |
586 | * verbatim. |
580 | * |
587 | * |
581 | * @param fmt Formatting NULL terminated string (UTF-8 or plain ASCII). |
588 | * @param fmt Format string. |
582 | * |
- | |
583 | * @return Number of UTF-8 characters printed, negative value on failure. |
589 | * @return Number of characters printed, negative value on failure. |
584 | * |
590 | * |
585 | */ |
591 | */ |
586 | int printf_core(const char *fmt, printf_spec_t *ps, va_list ap) |
592 | int printf_core(const char *fmt, printf_spec_t *ps, va_list ap) |
587 | { |
593 | { |
588 | size_t i = 0; /* Index of the currently processed character from fmt */ |
594 | size_t i = 0; /* Index of the currently processed character from fmt */ |
589 | size_t nxt = 0; |
595 | size_t nxt = 0; |
590 | size_t j = 0; /* Index to the first not printed nonformating character */ |
596 | size_t j = 0; /* Index to the first not printed nonformating character */ |
591 | 597 | ||
592 | wchar_t uc; /* Current UTF-32 character decoded from fmt */ |
598 | wchar_t uc; /* Current character decoded from fmt */ |
593 | count_t counter = 0; /* Number of UTF-8 characters printed */ |
599 | count_t counter = 0; /* Number of characters printed */ |
594 | int retval; /* Return values from nested functions */ |
600 | int retval; /* Return values from nested functions */ |
595 | 601 | ||
596 | while (true) { |
602 | while (true) { |
597 | i = nxt; |
603 | i = nxt; |
598 | uc = chr_decode(fmt, &nxt, UTF8_NO_LIMIT); |
604 | uc = chr_decode(fmt, &nxt, UTF8_NO_LIMIT); |
Line 735... | Line 741... | ||
735 | /* |
741 | /* |
736 | * String and character conversions. |
742 | * String and character conversions. |
737 | */ |
743 | */ |
738 | case 's': |
744 | case 's': |
739 | if (qualifier == PrintfQualifierLong) |
745 | if (qualifier == PrintfQualifierLong) |
740 | retval = print_utf32(va_arg(ap, wchar_t *), width, precision, flags, ps); |
746 | retval = print_wstr(va_arg(ap, wchar_t *), width, precision, flags, ps); |
741 | else |
747 | else |
742 | retval = print_utf8(va_arg(ap, char *), width, precision, flags, ps); |
748 | retval = print_str(va_arg(ap, char *), width, precision, flags, ps); |
743 | 749 | ||
744 | if (retval < 0) { |
750 | if (retval < 0) { |
745 | counter = -counter; |
751 | counter = -counter; |
746 | goto out; |
752 | goto out; |
747 | } |
753 | } |