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 | } |