diff options
Diffstat (limited to 'lib/vsprintf.c')
-rw-r--r-- | lib/vsprintf.c | 509 |
1 files changed, 304 insertions, 205 deletions
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 73a14b8c6d1f..735343fc857a 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c | |||
@@ -9,7 +9,7 @@ | |||
9 | * Wirzenius wrote this portably, Torvalds fucked it up :-) | 9 | * Wirzenius wrote this portably, Torvalds fucked it up :-) |
10 | */ | 10 | */ |
11 | 11 | ||
12 | /* | 12 | /* |
13 | * Fri Jul 13 2001 Crutcher Dunnavant <crutcher+kernel@datastacks.com> | 13 | * Fri Jul 13 2001 Crutcher Dunnavant <crutcher+kernel@datastacks.com> |
14 | * - changed to provide snprintf and vsnprintf functions | 14 | * - changed to provide snprintf and vsnprintf functions |
15 | * So Feb 1 16:51:32 CET 2004 Juergen Quade <quade@hsnr.de> | 15 | * So Feb 1 16:51:32 CET 2004 Juergen Quade <quade@hsnr.de> |
@@ -47,14 +47,14 @@ static unsigned int simple_guess_base(const char *cp) | |||
47 | } | 47 | } |
48 | 48 | ||
49 | /** | 49 | /** |
50 | * simple_strtoul - convert a string to an unsigned long | 50 | * simple_strtoull - convert a string to an unsigned long long |
51 | * @cp: The start of the string | 51 | * @cp: The start of the string |
52 | * @endp: A pointer to the end of the parsed string will be placed here | 52 | * @endp: A pointer to the end of the parsed string will be placed here |
53 | * @base: The number base to use | 53 | * @base: The number base to use |
54 | */ | 54 | */ |
55 | unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base) | 55 | unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base) |
56 | { | 56 | { |
57 | unsigned long result = 0; | 57 | unsigned long long result = 0; |
58 | 58 | ||
59 | if (!base) | 59 | if (!base) |
60 | base = simple_guess_base(cp); | 60 | base = simple_guess_base(cp); |
@@ -71,58 +71,39 @@ unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base) | |||
71 | result = result * base + value; | 71 | result = result * base + value; |
72 | cp++; | 72 | cp++; |
73 | } | 73 | } |
74 | |||
75 | if (endp) | 74 | if (endp) |
76 | *endp = (char *)cp; | 75 | *endp = (char *)cp; |
76 | |||
77 | return result; | 77 | return result; |
78 | } | 78 | } |
79 | EXPORT_SYMBOL(simple_strtoul); | 79 | EXPORT_SYMBOL(simple_strtoull); |
80 | 80 | ||
81 | /** | 81 | /** |
82 | * simple_strtol - convert a string to a signed long | 82 | * simple_strtoul - convert a string to an unsigned long |
83 | * @cp: The start of the string | 83 | * @cp: The start of the string |
84 | * @endp: A pointer to the end of the parsed string will be placed here | 84 | * @endp: A pointer to the end of the parsed string will be placed here |
85 | * @base: The number base to use | 85 | * @base: The number base to use |
86 | */ | 86 | */ |
87 | long simple_strtol(const char *cp, char **endp, unsigned int base) | 87 | unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base) |
88 | { | 88 | { |
89 | if(*cp == '-') | 89 | return simple_strtoull(cp, endp, base); |
90 | return -simple_strtoul(cp + 1, endp, base); | ||
91 | return simple_strtoul(cp, endp, base); | ||
92 | } | 90 | } |
93 | EXPORT_SYMBOL(simple_strtol); | 91 | EXPORT_SYMBOL(simple_strtoul); |
94 | 92 | ||
95 | /** | 93 | /** |
96 | * simple_strtoull - convert a string to an unsigned long long | 94 | * simple_strtol - convert a string to a signed long |
97 | * @cp: The start of the string | 95 | * @cp: The start of the string |
98 | * @endp: A pointer to the end of the parsed string will be placed here | 96 | * @endp: A pointer to the end of the parsed string will be placed here |
99 | * @base: The number base to use | 97 | * @base: The number base to use |
100 | */ | 98 | */ |
101 | unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base) | 99 | long simple_strtol(const char *cp, char **endp, unsigned int base) |
102 | { | 100 | { |
103 | unsigned long long result = 0; | 101 | if (*cp == '-') |
104 | 102 | return -simple_strtoul(cp + 1, endp, base); | |
105 | if (!base) | ||
106 | base = simple_guess_base(cp); | ||
107 | |||
108 | if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x') | ||
109 | cp += 2; | ||
110 | |||
111 | while (isxdigit(*cp)) { | ||
112 | unsigned int value; | ||
113 | |||
114 | value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10; | ||
115 | if (value >= base) | ||
116 | break; | ||
117 | result = result * base + value; | ||
118 | cp++; | ||
119 | } | ||
120 | 103 | ||
121 | if (endp) | 104 | return simple_strtoul(cp, endp, base); |
122 | *endp = (char *)cp; | ||
123 | return result; | ||
124 | } | 105 | } |
125 | EXPORT_SYMBOL(simple_strtoull); | 106 | EXPORT_SYMBOL(simple_strtol); |
126 | 107 | ||
127 | /** | 108 | /** |
128 | * simple_strtoll - convert a string to a signed long long | 109 | * simple_strtoll - convert a string to a signed long long |
@@ -132,8 +113,9 @@ EXPORT_SYMBOL(simple_strtoull); | |||
132 | */ | 113 | */ |
133 | long long simple_strtoll(const char *cp, char **endp, unsigned int base) | 114 | long long simple_strtoll(const char *cp, char **endp, unsigned int base) |
134 | { | 115 | { |
135 | if(*cp=='-') | 116 | if (*cp == '-') |
136 | return -simple_strtoull(cp + 1, endp, base); | 117 | return -simple_strtoull(cp + 1, endp, base); |
118 | |||
137 | return simple_strtoull(cp, endp, base); | 119 | return simple_strtoull(cp, endp, base); |
138 | } | 120 | } |
139 | 121 | ||
@@ -173,6 +155,7 @@ int strict_strtoul(const char *cp, unsigned int base, unsigned long *res) | |||
173 | val = simple_strtoul(cp, &tail, base); | 155 | val = simple_strtoul(cp, &tail, base); |
174 | if (tail == cp) | 156 | if (tail == cp) |
175 | return -EINVAL; | 157 | return -EINVAL; |
158 | |||
176 | if ((*tail == '\0') || | 159 | if ((*tail == '\0') || |
177 | ((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) { | 160 | ((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) { |
178 | *res = val; | 161 | *res = val; |
@@ -285,10 +268,11 @@ EXPORT_SYMBOL(strict_strtoll); | |||
285 | 268 | ||
286 | static int skip_atoi(const char **s) | 269 | static int skip_atoi(const char **s) |
287 | { | 270 | { |
288 | int i=0; | 271 | int i = 0; |
289 | 272 | ||
290 | while (isdigit(**s)) | 273 | while (isdigit(**s)) |
291 | i = i*10 + *((*s)++) - '0'; | 274 | i = i*10 + *((*s)++) - '0'; |
275 | |||
292 | return i; | 276 | return i; |
293 | } | 277 | } |
294 | 278 | ||
@@ -302,7 +286,7 @@ static int skip_atoi(const char **s) | |||
302 | /* Formats correctly any integer in [0,99999]. | 286 | /* Formats correctly any integer in [0,99999]. |
303 | * Outputs from one to five digits depending on input. | 287 | * Outputs from one to five digits depending on input. |
304 | * On i386 gcc 4.1.2 -O2: ~250 bytes of code. */ | 288 | * On i386 gcc 4.1.2 -O2: ~250 bytes of code. */ |
305 | static char* put_dec_trunc(char *buf, unsigned q) | 289 | static char *put_dec_trunc(char *buf, unsigned q) |
306 | { | 290 | { |
307 | unsigned d3, d2, d1, d0; | 291 | unsigned d3, d2, d1, d0; |
308 | d1 = (q>>4) & 0xf; | 292 | d1 = (q>>4) & 0xf; |
@@ -331,14 +315,15 @@ static char* put_dec_trunc(char *buf, unsigned q) | |||
331 | d3 = d3 - 10*q; | 315 | d3 = d3 - 10*q; |
332 | *buf++ = d3 + '0'; /* next digit */ | 316 | *buf++ = d3 + '0'; /* next digit */ |
333 | if (q != 0) | 317 | if (q != 0) |
334 | *buf++ = q + '0'; /* most sign. digit */ | 318 | *buf++ = q + '0'; /* most sign. digit */ |
335 | } | 319 | } |
336 | } | 320 | } |
337 | } | 321 | } |
322 | |||
338 | return buf; | 323 | return buf; |
339 | } | 324 | } |
340 | /* Same with if's removed. Always emits five digits */ | 325 | /* Same with if's removed. Always emits five digits */ |
341 | static char* put_dec_full(char *buf, unsigned q) | 326 | static char *put_dec_full(char *buf, unsigned q) |
342 | { | 327 | { |
343 | /* BTW, if q is in [0,9999], 8-bit ints will be enough, */ | 328 | /* BTW, if q is in [0,9999], 8-bit ints will be enough, */ |
344 | /* but anyway, gcc produces better code with full-sized ints */ | 329 | /* but anyway, gcc produces better code with full-sized ints */ |
@@ -347,14 +332,15 @@ static char* put_dec_full(char *buf, unsigned q) | |||
347 | d2 = (q>>8) & 0xf; | 332 | d2 = (q>>8) & 0xf; |
348 | d3 = (q>>12); | 333 | d3 = (q>>12); |
349 | 334 | ||
350 | /* Possible ways to approx. divide by 10 */ | 335 | /* |
351 | /* gcc -O2 replaces multiply with shifts and adds */ | 336 | * Possible ways to approx. divide by 10 |
352 | // (x * 0xcd) >> 11: 11001101 - shorter code than * 0x67 (on i386) | 337 | * gcc -O2 replaces multiply with shifts and adds |
353 | // (x * 0x67) >> 10: 1100111 | 338 | * (x * 0xcd) >> 11: 11001101 - shorter code than * 0x67 (on i386) |
354 | // (x * 0x34) >> 9: 110100 - same | 339 | * (x * 0x67) >> 10: 1100111 |
355 | // (x * 0x1a) >> 8: 11010 - same | 340 | * (x * 0x34) >> 9: 110100 - same |
356 | // (x * 0x0d) >> 7: 1101 - same, shortest code (on i386) | 341 | * (x * 0x1a) >> 8: 11010 - same |
357 | 342 | * (x * 0x0d) >> 7: 1101 - same, shortest code (on i386) | |
343 | */ | ||
358 | d0 = 6*(d3 + d2 + d1) + (q & 0xf); | 344 | d0 = 6*(d3 + d2 + d1) + (q & 0xf); |
359 | q = (d0 * 0xcd) >> 11; | 345 | q = (d0 * 0xcd) >> 11; |
360 | d0 = d0 - 10*q; | 346 | d0 = d0 - 10*q; |
@@ -375,10 +361,11 @@ static char* put_dec_full(char *buf, unsigned q) | |||
375 | d3 = d3 - 10*q; | 361 | d3 = d3 - 10*q; |
376 | *buf++ = d3 + '0'; | 362 | *buf++ = d3 + '0'; |
377 | *buf++ = q + '0'; | 363 | *buf++ = q + '0'; |
364 | |||
378 | return buf; | 365 | return buf; |
379 | } | 366 | } |
380 | /* No inlining helps gcc to use registers better */ | 367 | /* No inlining helps gcc to use registers better */ |
381 | static noinline char* put_dec(char *buf, unsigned long long num) | 368 | static noinline char *put_dec(char *buf, unsigned long long num) |
382 | { | 369 | { |
383 | while (1) { | 370 | while (1) { |
384 | unsigned rem; | 371 | unsigned rem; |
@@ -448,9 +435,9 @@ static char *number(char *buf, char *end, unsigned long long num, | |||
448 | spec.flags &= ~ZEROPAD; | 435 | spec.flags &= ~ZEROPAD; |
449 | sign = 0; | 436 | sign = 0; |
450 | if (spec.flags & SIGN) { | 437 | if (spec.flags & SIGN) { |
451 | if ((signed long long) num < 0) { | 438 | if ((signed long long)num < 0) { |
452 | sign = '-'; | 439 | sign = '-'; |
453 | num = - (signed long long) num; | 440 | num = -(signed long long)num; |
454 | spec.field_width--; | 441 | spec.field_width--; |
455 | } else if (spec.flags & PLUS) { | 442 | } else if (spec.flags & PLUS) { |
456 | sign = '+'; | 443 | sign = '+'; |
@@ -478,7 +465,9 @@ static char *number(char *buf, char *end, unsigned long long num, | |||
478 | else if (spec.base != 10) { /* 8 or 16 */ | 465 | else if (spec.base != 10) { /* 8 or 16 */ |
479 | int mask = spec.base - 1; | 466 | int mask = spec.base - 1; |
480 | int shift = 3; | 467 | int shift = 3; |
481 | if (spec.base == 16) shift = 4; | 468 | |
469 | if (spec.base == 16) | ||
470 | shift = 4; | ||
482 | do { | 471 | do { |
483 | tmp[i++] = (digits[((unsigned char)num) & mask] | locase); | 472 | tmp[i++] = (digits[((unsigned char)num) & mask] | locase); |
484 | num >>= shift; | 473 | num >>= shift; |
@@ -493,7 +482,7 @@ static char *number(char *buf, char *end, unsigned long long num, | |||
493 | /* leading space padding */ | 482 | /* leading space padding */ |
494 | spec.field_width -= spec.precision; | 483 | spec.field_width -= spec.precision; |
495 | if (!(spec.flags & (ZEROPAD+LEFT))) { | 484 | if (!(spec.flags & (ZEROPAD+LEFT))) { |
496 | while(--spec.field_width >= 0) { | 485 | while (--spec.field_width >= 0) { |
497 | if (buf < end) | 486 | if (buf < end) |
498 | *buf = ' '; | 487 | *buf = ' '; |
499 | ++buf; | 488 | ++buf; |
@@ -543,15 +532,16 @@ static char *number(char *buf, char *end, unsigned long long num, | |||
543 | *buf = ' '; | 532 | *buf = ' '; |
544 | ++buf; | 533 | ++buf; |
545 | } | 534 | } |
535 | |||
546 | return buf; | 536 | return buf; |
547 | } | 537 | } |
548 | 538 | ||
549 | static char *string(char *buf, char *end, char *s, struct printf_spec spec) | 539 | static char *string(char *buf, char *end, const char *s, struct printf_spec spec) |
550 | { | 540 | { |
551 | int len, i; | 541 | int len, i; |
552 | 542 | ||
553 | if ((unsigned long)s < PAGE_SIZE) | 543 | if ((unsigned long)s < PAGE_SIZE) |
554 | s = "<NULL>"; | 544 | s = "(null)"; |
555 | 545 | ||
556 | len = strnlen(s, spec.precision); | 546 | len = strnlen(s, spec.precision); |
557 | 547 | ||
@@ -572,6 +562,7 @@ static char *string(char *buf, char *end, char *s, struct printf_spec spec) | |||
572 | *buf = ' '; | 562 | *buf = ' '; |
573 | ++buf; | 563 | ++buf; |
574 | } | 564 | } |
565 | |||
575 | return buf; | 566 | return buf; |
576 | } | 567 | } |
577 | 568 | ||
@@ -585,47 +576,101 @@ static char *symbol_string(char *buf, char *end, void *ptr, | |||
585 | sprint_symbol(sym, value); | 576 | sprint_symbol(sym, value); |
586 | else | 577 | else |
587 | kallsyms_lookup(value, NULL, NULL, NULL, sym); | 578 | kallsyms_lookup(value, NULL, NULL, NULL, sym); |
579 | |||
588 | return string(buf, end, sym, spec); | 580 | return string(buf, end, sym, spec); |
589 | #else | 581 | #else |
590 | spec.field_width = 2*sizeof(void *); | 582 | spec.field_width = 2 * sizeof(void *); |
591 | spec.flags |= SPECIAL | SMALL | ZEROPAD; | 583 | spec.flags |= SPECIAL | SMALL | ZEROPAD; |
592 | spec.base = 16; | 584 | spec.base = 16; |
585 | |||
593 | return number(buf, end, value, spec); | 586 | return number(buf, end, value, spec); |
594 | #endif | 587 | #endif |
595 | } | 588 | } |
596 | 589 | ||
597 | static char *resource_string(char *buf, char *end, struct resource *res, | 590 | static char *resource_string(char *buf, char *end, struct resource *res, |
598 | struct printf_spec spec) | 591 | struct printf_spec spec, const char *fmt) |
599 | { | 592 | { |
600 | #ifndef IO_RSRC_PRINTK_SIZE | 593 | #ifndef IO_RSRC_PRINTK_SIZE |
601 | #define IO_RSRC_PRINTK_SIZE 4 | 594 | #define IO_RSRC_PRINTK_SIZE 6 |
602 | #endif | 595 | #endif |
603 | 596 | ||
604 | #ifndef MEM_RSRC_PRINTK_SIZE | 597 | #ifndef MEM_RSRC_PRINTK_SIZE |
605 | #define MEM_RSRC_PRINTK_SIZE 8 | 598 | #define MEM_RSRC_PRINTK_SIZE 10 |
606 | #endif | 599 | #endif |
607 | struct printf_spec num_spec = { | 600 | struct printf_spec hex_spec = { |
608 | .base = 16, | 601 | .base = 16, |
609 | .precision = -1, | 602 | .precision = -1, |
610 | .flags = SPECIAL | SMALL | ZEROPAD, | 603 | .flags = SPECIAL | SMALL | ZEROPAD, |
611 | }; | 604 | }; |
612 | /* room for the actual numbers, the two "0x", -, [, ] and the final zero */ | 605 | struct printf_spec dec_spec = { |
613 | char sym[4*sizeof(resource_size_t) + 8]; | 606 | .base = 10, |
607 | .precision = -1, | ||
608 | .flags = 0, | ||
609 | }; | ||
610 | struct printf_spec str_spec = { | ||
611 | .field_width = -1, | ||
612 | .precision = 10, | ||
613 | .flags = LEFT, | ||
614 | }; | ||
615 | struct printf_spec flag_spec = { | ||
616 | .base = 16, | ||
617 | .precision = -1, | ||
618 | .flags = SPECIAL | SMALL, | ||
619 | }; | ||
620 | |||
621 | /* 32-bit res (sizeof==4): 10 chars in dec, 10 in hex ("0x" + 8) | ||
622 | * 64-bit res (sizeof==8): 20 chars in dec, 18 in hex ("0x" + 16) */ | ||
623 | #define RSRC_BUF_SIZE ((2 * sizeof(resource_size_t)) + 4) | ||
624 | #define FLAG_BUF_SIZE (2 * sizeof(res->flags)) | ||
625 | #define DECODED_BUF_SIZE sizeof("[mem - 64bit pref disabled]") | ||
626 | #define RAW_BUF_SIZE sizeof("[mem - flags 0x]") | ||
627 | char sym[max(2*RSRC_BUF_SIZE + DECODED_BUF_SIZE, | ||
628 | 2*RSRC_BUF_SIZE + FLAG_BUF_SIZE + RAW_BUF_SIZE)]; | ||
629 | |||
614 | char *p = sym, *pend = sym + sizeof(sym); | 630 | char *p = sym, *pend = sym + sizeof(sym); |
615 | int size = -1; | 631 | int size = -1, addr = 0; |
632 | int decode = (fmt[0] == 'R') ? 1 : 0; | ||
616 | 633 | ||
617 | if (res->flags & IORESOURCE_IO) | 634 | if (res->flags & IORESOURCE_IO) { |
618 | size = IO_RSRC_PRINTK_SIZE; | 635 | size = IO_RSRC_PRINTK_SIZE; |
619 | else if (res->flags & IORESOURCE_MEM) | 636 | addr = 1; |
637 | } else if (res->flags & IORESOURCE_MEM) { | ||
620 | size = MEM_RSRC_PRINTK_SIZE; | 638 | size = MEM_RSRC_PRINTK_SIZE; |
639 | addr = 1; | ||
640 | } | ||
621 | 641 | ||
622 | *p++ = '['; | 642 | *p++ = '['; |
623 | num_spec.field_width = size; | 643 | if (res->flags & IORESOURCE_IO) |
624 | p = number(p, pend, res->start, num_spec); | 644 | p = string(p, pend, "io ", str_spec); |
625 | *p++ = '-'; | 645 | else if (res->flags & IORESOURCE_MEM) |
626 | p = number(p, pend, res->end, num_spec); | 646 | p = string(p, pend, "mem ", str_spec); |
647 | else if (res->flags & IORESOURCE_IRQ) | ||
648 | p = string(p, pend, "irq ", str_spec); | ||
649 | else if (res->flags & IORESOURCE_DMA) | ||
650 | p = string(p, pend, "dma ", str_spec); | ||
651 | else { | ||
652 | p = string(p, pend, "??? ", str_spec); | ||
653 | decode = 0; | ||
654 | } | ||
655 | hex_spec.field_width = size; | ||
656 | p = number(p, pend, res->start, addr ? hex_spec : dec_spec); | ||
657 | if (res->start != res->end) { | ||
658 | *p++ = '-'; | ||
659 | p = number(p, pend, res->end, addr ? hex_spec : dec_spec); | ||
660 | } | ||
661 | if (decode) { | ||
662 | if (res->flags & IORESOURCE_MEM_64) | ||
663 | p = string(p, pend, " 64bit", str_spec); | ||
664 | if (res->flags & IORESOURCE_PREFETCH) | ||
665 | p = string(p, pend, " pref", str_spec); | ||
666 | if (res->flags & IORESOURCE_DISABLED) | ||
667 | p = string(p, pend, " disabled", str_spec); | ||
668 | } else { | ||
669 | p = string(p, pend, " flags ", str_spec); | ||
670 | p = number(p, pend, res->flags, flag_spec); | ||
671 | } | ||
627 | *p++ = ']'; | 672 | *p++ = ']'; |
628 | *p = 0; | 673 | *p = '\0'; |
629 | 674 | ||
630 | return string(buf, end, sym, spec); | 675 | return string(buf, end, sym, spec); |
631 | } | 676 | } |
@@ -666,24 +711,26 @@ static char *ip4_string(char *p, const u8 *addr, bool leading_zeros) | |||
666 | if (i < 3) | 711 | if (i < 3) |
667 | *p++ = '.'; | 712 | *p++ = '.'; |
668 | } | 713 | } |
669 | |||
670 | *p = '\0'; | 714 | *p = '\0'; |
715 | |||
671 | return p; | 716 | return p; |
672 | } | 717 | } |
673 | 718 | ||
674 | static char *ip6_compressed_string(char *p, const struct in6_addr *addr) | 719 | static char *ip6_compressed_string(char *p, const char *addr) |
675 | { | 720 | { |
676 | int i; | 721 | int i, j, range; |
677 | int j; | ||
678 | int range; | ||
679 | unsigned char zerolength[8]; | 722 | unsigned char zerolength[8]; |
680 | int longest = 1; | 723 | int longest = 1; |
681 | int colonpos = -1; | 724 | int colonpos = -1; |
682 | u16 word; | 725 | u16 word; |
683 | u8 hi; | 726 | u8 hi, lo; |
684 | u8 lo; | ||
685 | bool needcolon = false; | 727 | bool needcolon = false; |
686 | bool useIPv4 = ipv6_addr_v4mapped(addr) || ipv6_addr_is_isatap(addr); | 728 | bool useIPv4; |
729 | struct in6_addr in6; | ||
730 | |||
731 | memcpy(&in6, addr, sizeof(struct in6_addr)); | ||
732 | |||
733 | useIPv4 = ipv6_addr_v4mapped(&in6) || ipv6_addr_is_isatap(&in6); | ||
687 | 734 | ||
688 | memset(zerolength, 0, sizeof(zerolength)); | 735 | memset(zerolength, 0, sizeof(zerolength)); |
689 | 736 | ||
@@ -695,7 +742,7 @@ static char *ip6_compressed_string(char *p, const struct in6_addr *addr) | |||
695 | /* find position of longest 0 run */ | 742 | /* find position of longest 0 run */ |
696 | for (i = 0; i < range; i++) { | 743 | for (i = 0; i < range; i++) { |
697 | for (j = i; j < range; j++) { | 744 | for (j = i; j < range; j++) { |
698 | if (addr->s6_addr16[j] != 0) | 745 | if (in6.s6_addr16[j] != 0) |
699 | break; | 746 | break; |
700 | zerolength[i]++; | 747 | zerolength[i]++; |
701 | } | 748 | } |
@@ -722,7 +769,7 @@ static char *ip6_compressed_string(char *p, const struct in6_addr *addr) | |||
722 | needcolon = false; | 769 | needcolon = false; |
723 | } | 770 | } |
724 | /* hex u16 without leading 0s */ | 771 | /* hex u16 without leading 0s */ |
725 | word = ntohs(addr->s6_addr16[i]); | 772 | word = ntohs(in6.s6_addr16[i]); |
726 | hi = word >> 8; | 773 | hi = word >> 8; |
727 | lo = word & 0xff; | 774 | lo = word & 0xff; |
728 | if (hi) { | 775 | if (hi) { |
@@ -730,8 +777,9 @@ static char *ip6_compressed_string(char *p, const struct in6_addr *addr) | |||
730 | p = pack_hex_byte(p, hi); | 777 | p = pack_hex_byte(p, hi); |
731 | else | 778 | else |
732 | *p++ = hex_asc_lo(hi); | 779 | *p++ = hex_asc_lo(hi); |
780 | p = pack_hex_byte(p, lo); | ||
733 | } | 781 | } |
734 | if (hi || lo > 0x0f) | 782 | else if (lo > 0x0f) |
735 | p = pack_hex_byte(p, lo); | 783 | p = pack_hex_byte(p, lo); |
736 | else | 784 | else |
737 | *p++ = hex_asc_lo(lo); | 785 | *p++ = hex_asc_lo(lo); |
@@ -741,24 +789,25 @@ static char *ip6_compressed_string(char *p, const struct in6_addr *addr) | |||
741 | if (useIPv4) { | 789 | if (useIPv4) { |
742 | if (needcolon) | 790 | if (needcolon) |
743 | *p++ = ':'; | 791 | *p++ = ':'; |
744 | p = ip4_string(p, &addr->s6_addr[12], false); | 792 | p = ip4_string(p, &in6.s6_addr[12], false); |
745 | } | 793 | } |
746 | |||
747 | *p = '\0'; | 794 | *p = '\0'; |
795 | |||
748 | return p; | 796 | return p; |
749 | } | 797 | } |
750 | 798 | ||
751 | static char *ip6_string(char *p, const struct in6_addr *addr, const char *fmt) | 799 | static char *ip6_string(char *p, const char *addr, const char *fmt) |
752 | { | 800 | { |
753 | int i; | 801 | int i; |
802 | |||
754 | for (i = 0; i < 8; i++) { | 803 | for (i = 0; i < 8; i++) { |
755 | p = pack_hex_byte(p, addr->s6_addr[2 * i]); | 804 | p = pack_hex_byte(p, *addr++); |
756 | p = pack_hex_byte(p, addr->s6_addr[2 * i + 1]); | 805 | p = pack_hex_byte(p, *addr++); |
757 | if (fmt[0] == 'I' && i != 7) | 806 | if (fmt[0] == 'I' && i != 7) |
758 | *p++ = ':'; | 807 | *p++ = ':'; |
759 | } | 808 | } |
760 | |||
761 | *p = '\0'; | 809 | *p = '\0'; |
810 | |||
762 | return p; | 811 | return p; |
763 | } | 812 | } |
764 | 813 | ||
@@ -768,9 +817,9 @@ static char *ip6_addr_string(char *buf, char *end, const u8 *addr, | |||
768 | char ip6_addr[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255")]; | 817 | char ip6_addr[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255")]; |
769 | 818 | ||
770 | if (fmt[0] == 'I' && fmt[2] == 'c') | 819 | if (fmt[0] == 'I' && fmt[2] == 'c') |
771 | ip6_compressed_string(ip6_addr, (const struct in6_addr *)addr); | 820 | ip6_compressed_string(ip6_addr, addr); |
772 | else | 821 | else |
773 | ip6_string(ip6_addr, (const struct in6_addr *)addr, fmt); | 822 | ip6_string(ip6_addr, addr, fmt); |
774 | 823 | ||
775 | return string(buf, end, ip6_addr, spec); | 824 | return string(buf, end, ip6_addr, spec); |
776 | } | 825 | } |
@@ -785,6 +834,52 @@ static char *ip4_addr_string(char *buf, char *end, const u8 *addr, | |||
785 | return string(buf, end, ip4_addr, spec); | 834 | return string(buf, end, ip4_addr, spec); |
786 | } | 835 | } |
787 | 836 | ||
837 | static char *uuid_string(char *buf, char *end, const u8 *addr, | ||
838 | struct printf_spec spec, const char *fmt) | ||
839 | { | ||
840 | char uuid[sizeof("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")]; | ||
841 | char *p = uuid; | ||
842 | int i; | ||
843 | static const u8 be[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; | ||
844 | static const u8 le[16] = {3,2,1,0,5,4,7,6,8,9,10,11,12,13,14,15}; | ||
845 | const u8 *index = be; | ||
846 | bool uc = false; | ||
847 | |||
848 | switch (*(++fmt)) { | ||
849 | case 'L': | ||
850 | uc = true; /* fall-through */ | ||
851 | case 'l': | ||
852 | index = le; | ||
853 | break; | ||
854 | case 'B': | ||
855 | uc = true; | ||
856 | break; | ||
857 | } | ||
858 | |||
859 | for (i = 0; i < 16; i++) { | ||
860 | p = pack_hex_byte(p, addr[index[i]]); | ||
861 | switch (i) { | ||
862 | case 3: | ||
863 | case 5: | ||
864 | case 7: | ||
865 | case 9: | ||
866 | *p++ = '-'; | ||
867 | break; | ||
868 | } | ||
869 | } | ||
870 | |||
871 | *p = 0; | ||
872 | |||
873 | if (uc) { | ||
874 | p = uuid; | ||
875 | do { | ||
876 | *p = toupper(*p); | ||
877 | } while (*(++p)); | ||
878 | } | ||
879 | |||
880 | return string(buf, end, uuid, spec); | ||
881 | } | ||
882 | |||
788 | /* | 883 | /* |
789 | * Show a '%p' thing. A kernel extension is that the '%p' is followed | 884 | * Show a '%p' thing. A kernel extension is that the '%p' is followed |
790 | * by an extra set of alphanumeric characters that are extended format | 885 | * by an extra set of alphanumeric characters that are extended format |
@@ -796,8 +891,8 @@ static char *ip4_addr_string(char *buf, char *end, const u8 *addr, | |||
796 | * - 'f' For simple symbolic function names without offset | 891 | * - 'f' For simple symbolic function names without offset |
797 | * - 'S' For symbolic direct pointers with offset | 892 | * - 'S' For symbolic direct pointers with offset |
798 | * - 's' For symbolic direct pointers without offset | 893 | * - 's' For symbolic direct pointers without offset |
799 | * - 'R' For a struct resource pointer, it prints the range of | 894 | * - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref] |
800 | * addresses (not the name nor the flags) | 895 | * - 'r' For raw struct resource, e.g., [mem 0x0-0x1f flags 0x201] |
801 | * - 'M' For a 6-byte MAC address, it prints the address in the | 896 | * - 'M' For a 6-byte MAC address, it prints the address in the |
802 | * usual colon-separated hex notation | 897 | * usual colon-separated hex notation |
803 | * - 'm' For a 6-byte MAC address, it prints the hex address without colons | 898 | * - 'm' For a 6-byte MAC address, it prints the hex address without colons |
@@ -809,6 +904,18 @@ static char *ip4_addr_string(char *buf, char *end, const u8 *addr, | |||
809 | * IPv4 uses dot-separated decimal with leading 0's (010.123.045.006) | 904 | * IPv4 uses dot-separated decimal with leading 0's (010.123.045.006) |
810 | * - 'I6c' for IPv6 addresses printed as specified by | 905 | * - 'I6c' for IPv6 addresses printed as specified by |
811 | * http://www.ietf.org/id/draft-kawamura-ipv6-text-representation-03.txt | 906 | * http://www.ietf.org/id/draft-kawamura-ipv6-text-representation-03.txt |
907 | * - 'U' For a 16 byte UUID/GUID, it prints the UUID/GUID in the form | ||
908 | * "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" | ||
909 | * Options for %pU are: | ||
910 | * b big endian lower case hex (default) | ||
911 | * B big endian UPPER case hex | ||
912 | * l little endian lower case hex | ||
913 | * L little endian UPPER case hex | ||
914 | * big endian output byte order is: | ||
915 | * [0][1][2][3]-[4][5]-[6][7]-[8][9]-[10][11][12][13][14][15] | ||
916 | * little endian output byte order is: | ||
917 | * [3][2][1][0]-[5][4]-[7][6]-[8][9]-[10][11][12][13][14][15] | ||
918 | * | ||
812 | * Note: The difference between 'S' and 'F' is that on ia64 and ppc64 | 919 | * Note: The difference between 'S' and 'F' is that on ia64 and ppc64 |
813 | * function pointers are really function descriptors, which contain a | 920 | * function pointers are really function descriptors, which contain a |
814 | * pointer to the real address. | 921 | * pointer to the real address. |
@@ -823,12 +930,13 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr, | |||
823 | case 'F': | 930 | case 'F': |
824 | case 'f': | 931 | case 'f': |
825 | ptr = dereference_function_descriptor(ptr); | 932 | ptr = dereference_function_descriptor(ptr); |
826 | case 's': | ||
827 | /* Fallthrough */ | 933 | /* Fallthrough */ |
828 | case 'S': | 934 | case 'S': |
935 | case 's': | ||
829 | return symbol_string(buf, end, ptr, spec, *fmt); | 936 | return symbol_string(buf, end, ptr, spec, *fmt); |
830 | case 'R': | 937 | case 'R': |
831 | return resource_string(buf, end, ptr, spec); | 938 | case 'r': |
939 | return resource_string(buf, end, ptr, spec, fmt); | ||
832 | case 'M': /* Colon separated: 00:01:02:03:04:05 */ | 940 | case 'M': /* Colon separated: 00:01:02:03:04:05 */ |
833 | case 'm': /* Contiguous: 000102030405 */ | 941 | case 'm': /* Contiguous: 000102030405 */ |
834 | return mac_address_string(buf, end, ptr, spec, fmt); | 942 | return mac_address_string(buf, end, ptr, spec, fmt); |
@@ -848,6 +956,8 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr, | |||
848 | return ip4_addr_string(buf, end, ptr, spec, fmt); | 956 | return ip4_addr_string(buf, end, ptr, spec, fmt); |
849 | } | 957 | } |
850 | break; | 958 | break; |
959 | case 'U': | ||
960 | return uuid_string(buf, end, ptr, spec, fmt); | ||
851 | } | 961 | } |
852 | spec.flags |= SMALL; | 962 | spec.flags |= SMALL; |
853 | if (spec.field_width == -1) { | 963 | if (spec.field_width == -1) { |
@@ -965,8 +1075,8 @@ precision: | |||
965 | qualifier: | 1075 | qualifier: |
966 | /* get the conversion qualifier */ | 1076 | /* get the conversion qualifier */ |
967 | spec->qualifier = -1; | 1077 | spec->qualifier = -1; |
968 | if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || | 1078 | if (*fmt == 'h' || TOLOWER(*fmt) == 'l' || |
969 | *fmt == 'Z' || *fmt == 'z' || *fmt == 't') { | 1079 | TOLOWER(*fmt) == 'z' || *fmt == 't') { |
970 | spec->qualifier = *fmt++; | 1080 | spec->qualifier = *fmt++; |
971 | if (unlikely(spec->qualifier == *fmt)) { | 1081 | if (unlikely(spec->qualifier == *fmt)) { |
972 | if (spec->qualifier == 'l') { | 1082 | if (spec->qualifier == 'l') { |
@@ -1033,7 +1143,7 @@ qualifier: | |||
1033 | spec->type = FORMAT_TYPE_LONG; | 1143 | spec->type = FORMAT_TYPE_LONG; |
1034 | else | 1144 | else |
1035 | spec->type = FORMAT_TYPE_ULONG; | 1145 | spec->type = FORMAT_TYPE_ULONG; |
1036 | } else if (spec->qualifier == 'Z' || spec->qualifier == 'z') { | 1146 | } else if (TOLOWER(spec->qualifier) == 'z') { |
1037 | spec->type = FORMAT_TYPE_SIZE_T; | 1147 | spec->type = FORMAT_TYPE_SIZE_T; |
1038 | } else if (spec->qualifier == 't') { | 1148 | } else if (spec->qualifier == 't') { |
1039 | spec->type = FORMAT_TYPE_PTRDIFF; | 1149 | spec->type = FORMAT_TYPE_PTRDIFF; |
@@ -1086,8 +1196,7 @@ qualifier: | |||
1086 | int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) | 1196 | int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) |
1087 | { | 1197 | { |
1088 | unsigned long long num; | 1198 | unsigned long long num; |
1089 | char *str, *end, c; | 1199 | char *str, *end; |
1090 | int read; | ||
1091 | struct printf_spec spec = {0}; | 1200 | struct printf_spec spec = {0}; |
1092 | 1201 | ||
1093 | /* Reject out-of-range values early. Large positive sizes are | 1202 | /* Reject out-of-range values early. Large positive sizes are |
@@ -1106,8 +1215,7 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) | |||
1106 | 1215 | ||
1107 | while (*fmt) { | 1216 | while (*fmt) { |
1108 | const char *old_fmt = fmt; | 1217 | const char *old_fmt = fmt; |
1109 | 1218 | int read = format_decode(fmt, &spec); | |
1110 | read = format_decode(fmt, &spec); | ||
1111 | 1219 | ||
1112 | fmt += read; | 1220 | fmt += read; |
1113 | 1221 | ||
@@ -1131,7 +1239,9 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) | |||
1131 | spec.precision = va_arg(args, int); | 1239 | spec.precision = va_arg(args, int); |
1132 | break; | 1240 | break; |
1133 | 1241 | ||
1134 | case FORMAT_TYPE_CHAR: | 1242 | case FORMAT_TYPE_CHAR: { |
1243 | char c; | ||
1244 | |||
1135 | if (!(spec.flags & LEFT)) { | 1245 | if (!(spec.flags & LEFT)) { |
1136 | while (--spec.field_width > 0) { | 1246 | while (--spec.field_width > 0) { |
1137 | if (str < end) | 1247 | if (str < end) |
@@ -1150,6 +1260,7 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) | |||
1150 | ++str; | 1260 | ++str; |
1151 | } | 1261 | } |
1152 | break; | 1262 | break; |
1263 | } | ||
1153 | 1264 | ||
1154 | case FORMAT_TYPE_STR: | 1265 | case FORMAT_TYPE_STR: |
1155 | str = string(str, end, va_arg(args, char *), spec); | 1266 | str = string(str, end, va_arg(args, char *), spec); |
@@ -1180,8 +1291,7 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) | |||
1180 | if (qualifier == 'l') { | 1291 | if (qualifier == 'l') { |
1181 | long *ip = va_arg(args, long *); | 1292 | long *ip = va_arg(args, long *); |
1182 | *ip = (str - buf); | 1293 | *ip = (str - buf); |
1183 | } else if (qualifier == 'Z' || | 1294 | } else if (TOLOWER(qualifier) == 'z') { |
1184 | qualifier == 'z') { | ||
1185 | size_t *ip = va_arg(args, size_t *); | 1295 | size_t *ip = va_arg(args, size_t *); |
1186 | *ip = (str - buf); | 1296 | *ip = (str - buf); |
1187 | } else { | 1297 | } else { |
@@ -1264,7 +1374,8 @@ int vscnprintf(char *buf, size_t size, const char *fmt, va_list args) | |||
1264 | { | 1374 | { |
1265 | int i; | 1375 | int i; |
1266 | 1376 | ||
1267 | i=vsnprintf(buf,size,fmt,args); | 1377 | i = vsnprintf(buf, size, fmt, args); |
1378 | |||
1268 | return (i >= size) ? (size - 1) : i; | 1379 | return (i >= size) ? (size - 1) : i; |
1269 | } | 1380 | } |
1270 | EXPORT_SYMBOL(vscnprintf); | 1381 | EXPORT_SYMBOL(vscnprintf); |
@@ -1283,14 +1394,15 @@ EXPORT_SYMBOL(vscnprintf); | |||
1283 | * | 1394 | * |
1284 | * See the vsnprintf() documentation for format string extensions over C99. | 1395 | * See the vsnprintf() documentation for format string extensions over C99. |
1285 | */ | 1396 | */ |
1286 | int snprintf(char * buf, size_t size, const char *fmt, ...) | 1397 | int snprintf(char *buf, size_t size, const char *fmt, ...) |
1287 | { | 1398 | { |
1288 | va_list args; | 1399 | va_list args; |
1289 | int i; | 1400 | int i; |
1290 | 1401 | ||
1291 | va_start(args, fmt); | 1402 | va_start(args, fmt); |
1292 | i=vsnprintf(buf,size,fmt,args); | 1403 | i = vsnprintf(buf, size, fmt, args); |
1293 | va_end(args); | 1404 | va_end(args); |
1405 | |||
1294 | return i; | 1406 | return i; |
1295 | } | 1407 | } |
1296 | EXPORT_SYMBOL(snprintf); | 1408 | EXPORT_SYMBOL(snprintf); |
@@ -1306,7 +1418,7 @@ EXPORT_SYMBOL(snprintf); | |||
1306 | * the trailing '\0'. If @size is <= 0 the function returns 0. | 1418 | * the trailing '\0'. If @size is <= 0 the function returns 0. |
1307 | */ | 1419 | */ |
1308 | 1420 | ||
1309 | int scnprintf(char * buf, size_t size, const char *fmt, ...) | 1421 | int scnprintf(char *buf, size_t size, const char *fmt, ...) |
1310 | { | 1422 | { |
1311 | va_list args; | 1423 | va_list args; |
1312 | int i; | 1424 | int i; |
@@ -1314,6 +1426,7 @@ int scnprintf(char * buf, size_t size, const char *fmt, ...) | |||
1314 | va_start(args, fmt); | 1426 | va_start(args, fmt); |
1315 | i = vsnprintf(buf, size, fmt, args); | 1427 | i = vsnprintf(buf, size, fmt, args); |
1316 | va_end(args); | 1428 | va_end(args); |
1429 | |||
1317 | return (i >= size) ? (size - 1) : i; | 1430 | return (i >= size) ? (size - 1) : i; |
1318 | } | 1431 | } |
1319 | EXPORT_SYMBOL(scnprintf); | 1432 | EXPORT_SYMBOL(scnprintf); |
@@ -1351,14 +1464,15 @@ EXPORT_SYMBOL(vsprintf); | |||
1351 | * | 1464 | * |
1352 | * See the vsnprintf() documentation for format string extensions over C99. | 1465 | * See the vsnprintf() documentation for format string extensions over C99. |
1353 | */ | 1466 | */ |
1354 | int sprintf(char * buf, const char *fmt, ...) | 1467 | int sprintf(char *buf, const char *fmt, ...) |
1355 | { | 1468 | { |
1356 | va_list args; | 1469 | va_list args; |
1357 | int i; | 1470 | int i; |
1358 | 1471 | ||
1359 | va_start(args, fmt); | 1472 | va_start(args, fmt); |
1360 | i=vsnprintf(buf, INT_MAX, fmt, args); | 1473 | i = vsnprintf(buf, INT_MAX, fmt, args); |
1361 | va_end(args); | 1474 | va_end(args); |
1475 | |||
1362 | return i; | 1476 | return i; |
1363 | } | 1477 | } |
1364 | EXPORT_SYMBOL(sprintf); | 1478 | EXPORT_SYMBOL(sprintf); |
@@ -1391,7 +1505,6 @@ int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args) | |||
1391 | { | 1505 | { |
1392 | struct printf_spec spec = {0}; | 1506 | struct printf_spec spec = {0}; |
1393 | char *str, *end; | 1507 | char *str, *end; |
1394 | int read; | ||
1395 | 1508 | ||
1396 | str = (char *)bin_buf; | 1509 | str = (char *)bin_buf; |
1397 | end = (char *)(bin_buf + size); | 1510 | end = (char *)(bin_buf + size); |
@@ -1416,14 +1529,15 @@ do { \ | |||
1416 | str += sizeof(type); \ | 1529 | str += sizeof(type); \ |
1417 | } while (0) | 1530 | } while (0) |
1418 | 1531 | ||
1419 | |||
1420 | while (*fmt) { | 1532 | while (*fmt) { |
1421 | read = format_decode(fmt, &spec); | 1533 | int read = format_decode(fmt, &spec); |
1422 | 1534 | ||
1423 | fmt += read; | 1535 | fmt += read; |
1424 | 1536 | ||
1425 | switch (spec.type) { | 1537 | switch (spec.type) { |
1426 | case FORMAT_TYPE_NONE: | 1538 | case FORMAT_TYPE_NONE: |
1539 | case FORMAT_TYPE_INVALID: | ||
1540 | case FORMAT_TYPE_PERCENT_CHAR: | ||
1427 | break; | 1541 | break; |
1428 | 1542 | ||
1429 | case FORMAT_TYPE_WIDTH: | 1543 | case FORMAT_TYPE_WIDTH: |
@@ -1438,13 +1552,14 @@ do { \ | |||
1438 | case FORMAT_TYPE_STR: { | 1552 | case FORMAT_TYPE_STR: { |
1439 | const char *save_str = va_arg(args, char *); | 1553 | const char *save_str = va_arg(args, char *); |
1440 | size_t len; | 1554 | size_t len; |
1555 | |||
1441 | if ((unsigned long)save_str > (unsigned long)-PAGE_SIZE | 1556 | if ((unsigned long)save_str > (unsigned long)-PAGE_SIZE |
1442 | || (unsigned long)save_str < PAGE_SIZE) | 1557 | || (unsigned long)save_str < PAGE_SIZE) |
1443 | save_str = "<NULL>"; | 1558 | save_str = "(null)"; |
1444 | len = strlen(save_str); | 1559 | len = strlen(save_str) + 1; |
1445 | if (str + len + 1 < end) | 1560 | if (str + len < end) |
1446 | memcpy(str, save_str, len + 1); | 1561 | memcpy(str, save_str, len); |
1447 | str += len + 1; | 1562 | str += len; |
1448 | break; | 1563 | break; |
1449 | } | 1564 | } |
1450 | 1565 | ||
@@ -1455,19 +1570,13 @@ do { \ | |||
1455 | fmt++; | 1570 | fmt++; |
1456 | break; | 1571 | break; |
1457 | 1572 | ||
1458 | case FORMAT_TYPE_PERCENT_CHAR: | ||
1459 | break; | ||
1460 | |||
1461 | case FORMAT_TYPE_INVALID: | ||
1462 | break; | ||
1463 | |||
1464 | case FORMAT_TYPE_NRCHARS: { | 1573 | case FORMAT_TYPE_NRCHARS: { |
1465 | /* skip %n 's argument */ | 1574 | /* skip %n 's argument */ |
1466 | int qualifier = spec.qualifier; | 1575 | int qualifier = spec.qualifier; |
1467 | void *skip_arg; | 1576 | void *skip_arg; |
1468 | if (qualifier == 'l') | 1577 | if (qualifier == 'l') |
1469 | skip_arg = va_arg(args, long *); | 1578 | skip_arg = va_arg(args, long *); |
1470 | else if (qualifier == 'Z' || qualifier == 'z') | 1579 | else if (TOLOWER(qualifier) == 'z') |
1471 | skip_arg = va_arg(args, size_t *); | 1580 | skip_arg = va_arg(args, size_t *); |
1472 | else | 1581 | else |
1473 | skip_arg = va_arg(args, int *); | 1582 | skip_arg = va_arg(args, int *); |
@@ -1503,8 +1612,8 @@ do { \ | |||
1503 | } | 1612 | } |
1504 | } | 1613 | } |
1505 | } | 1614 | } |
1506 | return (u32 *)(PTR_ALIGN(str, sizeof(u32))) - bin_buf; | ||
1507 | 1615 | ||
1616 | return (u32 *)(PTR_ALIGN(str, sizeof(u32))) - bin_buf; | ||
1508 | #undef save_arg | 1617 | #undef save_arg |
1509 | } | 1618 | } |
1510 | EXPORT_SYMBOL_GPL(vbin_printf); | 1619 | EXPORT_SYMBOL_GPL(vbin_printf); |
@@ -1533,11 +1642,9 @@ EXPORT_SYMBOL_GPL(vbin_printf); | |||
1533 | */ | 1642 | */ |
1534 | int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf) | 1643 | int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf) |
1535 | { | 1644 | { |
1536 | unsigned long long num; | ||
1537 | char *str, *end, c; | ||
1538 | const char *args = (const char *)bin_buf; | ||
1539 | |||
1540 | struct printf_spec spec = {0}; | 1645 | struct printf_spec spec = {0}; |
1646 | char *str, *end; | ||
1647 | const char *args = (const char *)bin_buf; | ||
1541 | 1648 | ||
1542 | if (WARN_ON_ONCE((int) size < 0)) | 1649 | if (WARN_ON_ONCE((int) size < 0)) |
1543 | return 0; | 1650 | return 0; |
@@ -1567,10 +1674,8 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf) | |||
1567 | } | 1674 | } |
1568 | 1675 | ||
1569 | while (*fmt) { | 1676 | while (*fmt) { |
1570 | int read; | ||
1571 | const char *old_fmt = fmt; | 1677 | const char *old_fmt = fmt; |
1572 | 1678 | int read = format_decode(fmt, &spec); | |
1573 | read = format_decode(fmt, &spec); | ||
1574 | 1679 | ||
1575 | fmt += read; | 1680 | fmt += read; |
1576 | 1681 | ||
@@ -1594,7 +1699,9 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf) | |||
1594 | spec.precision = get_arg(int); | 1699 | spec.precision = get_arg(int); |
1595 | break; | 1700 | break; |
1596 | 1701 | ||
1597 | case FORMAT_TYPE_CHAR: | 1702 | case FORMAT_TYPE_CHAR: { |
1703 | char c; | ||
1704 | |||
1598 | if (!(spec.flags & LEFT)) { | 1705 | if (!(spec.flags & LEFT)) { |
1599 | while (--spec.field_width > 0) { | 1706 | while (--spec.field_width > 0) { |
1600 | if (str < end) | 1707 | if (str < end) |
@@ -1612,11 +1719,11 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf) | |||
1612 | ++str; | 1719 | ++str; |
1613 | } | 1720 | } |
1614 | break; | 1721 | break; |
1722 | } | ||
1615 | 1723 | ||
1616 | case FORMAT_TYPE_STR: { | 1724 | case FORMAT_TYPE_STR: { |
1617 | const char *str_arg = args; | 1725 | const char *str_arg = args; |
1618 | size_t len = strlen(str_arg); | 1726 | args += strlen(str_arg) + 1; |
1619 | args += len + 1; | ||
1620 | str = string(str, end, (char *)str_arg, spec); | 1727 | str = string(str, end, (char *)str_arg, spec); |
1621 | break; | 1728 | break; |
1622 | } | 1729 | } |
@@ -1628,11 +1735,6 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf) | |||
1628 | break; | 1735 | break; |
1629 | 1736 | ||
1630 | case FORMAT_TYPE_PERCENT_CHAR: | 1737 | case FORMAT_TYPE_PERCENT_CHAR: |
1631 | if (str < end) | ||
1632 | *str = '%'; | ||
1633 | ++str; | ||
1634 | break; | ||
1635 | |||
1636 | case FORMAT_TYPE_INVALID: | 1738 | case FORMAT_TYPE_INVALID: |
1637 | if (str < end) | 1739 | if (str < end) |
1638 | *str = '%'; | 1740 | *str = '%'; |
@@ -1643,15 +1745,15 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf) | |||
1643 | /* skip */ | 1745 | /* skip */ |
1644 | break; | 1746 | break; |
1645 | 1747 | ||
1646 | default: | 1748 | default: { |
1749 | unsigned long long num; | ||
1750 | |||
1647 | switch (spec.type) { | 1751 | switch (spec.type) { |
1648 | 1752 | ||
1649 | case FORMAT_TYPE_LONG_LONG: | 1753 | case FORMAT_TYPE_LONG_LONG: |
1650 | num = get_arg(long long); | 1754 | num = get_arg(long long); |
1651 | break; | 1755 | break; |
1652 | case FORMAT_TYPE_ULONG: | 1756 | case FORMAT_TYPE_ULONG: |
1653 | num = get_arg(unsigned long); | ||
1654 | break; | ||
1655 | case FORMAT_TYPE_LONG: | 1757 | case FORMAT_TYPE_LONG: |
1656 | num = get_arg(unsigned long); | 1758 | num = get_arg(unsigned long); |
1657 | break; | 1759 | break; |
@@ -1681,8 +1783,9 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf) | |||
1681 | } | 1783 | } |
1682 | 1784 | ||
1683 | str = number(str, end, num, spec); | 1785 | str = number(str, end, num, spec); |
1684 | } | 1786 | } /* default: */ |
1685 | } | 1787 | } /* switch(spec.type) */ |
1788 | } /* while(*fmt) */ | ||
1686 | 1789 | ||
1687 | if (size > 0) { | 1790 | if (size > 0) { |
1688 | if (str < end) | 1791 | if (str < end) |
@@ -1716,6 +1819,7 @@ int bprintf(u32 *bin_buf, size_t size, const char *fmt, ...) | |||
1716 | va_start(args, fmt); | 1819 | va_start(args, fmt); |
1717 | ret = vbin_printf(bin_buf, size, fmt, args); | 1820 | ret = vbin_printf(bin_buf, size, fmt, args); |
1718 | va_end(args); | 1821 | va_end(args); |
1822 | |||
1719 | return ret; | 1823 | return ret; |
1720 | } | 1824 | } |
1721 | EXPORT_SYMBOL_GPL(bprintf); | 1825 | EXPORT_SYMBOL_GPL(bprintf); |
@@ -1728,27 +1832,23 @@ EXPORT_SYMBOL_GPL(bprintf); | |||
1728 | * @fmt: format of buffer | 1832 | * @fmt: format of buffer |
1729 | * @args: arguments | 1833 | * @args: arguments |
1730 | */ | 1834 | */ |
1731 | int vsscanf(const char * buf, const char * fmt, va_list args) | 1835 | int vsscanf(const char *buf, const char *fmt, va_list args) |
1732 | { | 1836 | { |
1733 | const char *str = buf; | 1837 | const char *str = buf; |
1734 | char *next; | 1838 | char *next; |
1735 | char digit; | 1839 | char digit; |
1736 | int num = 0; | 1840 | int num = 0; |
1737 | int qualifier; | 1841 | int qualifier, base, field_width; |
1738 | int base; | 1842 | bool is_sign; |
1739 | int field_width; | ||
1740 | int is_sign = 0; | ||
1741 | 1843 | ||
1742 | while(*fmt && *str) { | 1844 | while (*fmt && *str) { |
1743 | /* skip any white space in format */ | 1845 | /* skip any white space in format */ |
1744 | /* white space in format matchs any amount of | 1846 | /* white space in format matchs any amount of |
1745 | * white space, including none, in the input. | 1847 | * white space, including none, in the input. |
1746 | */ | 1848 | */ |
1747 | if (isspace(*fmt)) { | 1849 | if (isspace(*fmt)) { |
1748 | while (isspace(*fmt)) | 1850 | fmt = skip_spaces(++fmt); |
1749 | ++fmt; | 1851 | str = skip_spaces(str); |
1750 | while (isspace(*str)) | ||
1751 | ++str; | ||
1752 | } | 1852 | } |
1753 | 1853 | ||
1754 | /* anything that is not a conversion must match exactly */ | 1854 | /* anything that is not a conversion must match exactly */ |
@@ -1761,12 +1861,12 @@ int vsscanf(const char * buf, const char * fmt, va_list args) | |||
1761 | if (!*fmt) | 1861 | if (!*fmt) |
1762 | break; | 1862 | break; |
1763 | ++fmt; | 1863 | ++fmt; |
1764 | 1864 | ||
1765 | /* skip this conversion. | 1865 | /* skip this conversion. |
1766 | * advance both strings to next white space | 1866 | * advance both strings to next white space |
1767 | */ | 1867 | */ |
1768 | if (*fmt == '*') { | 1868 | if (*fmt == '*') { |
1769 | while (!isspace(*fmt) && *fmt) | 1869 | while (!isspace(*fmt) && *fmt != '%' && *fmt) |
1770 | fmt++; | 1870 | fmt++; |
1771 | while (!isspace(*str) && *str) | 1871 | while (!isspace(*str) && *str) |
1772 | str++; | 1872 | str++; |
@@ -1780,8 +1880,8 @@ int vsscanf(const char * buf, const char * fmt, va_list args) | |||
1780 | 1880 | ||
1781 | /* get conversion qualifier */ | 1881 | /* get conversion qualifier */ |
1782 | qualifier = -1; | 1882 | qualifier = -1; |
1783 | if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || | 1883 | if (*fmt == 'h' || TOLOWER(*fmt) == 'l' || |
1784 | *fmt == 'Z' || *fmt == 'z') { | 1884 | TOLOWER(*fmt) == 'z') { |
1785 | qualifier = *fmt++; | 1885 | qualifier = *fmt++; |
1786 | if (unlikely(qualifier == *fmt)) { | 1886 | if (unlikely(qualifier == *fmt)) { |
1787 | if (qualifier == 'h') { | 1887 | if (qualifier == 'h') { |
@@ -1793,16 +1893,17 @@ int vsscanf(const char * buf, const char * fmt, va_list args) | |||
1793 | } | 1893 | } |
1794 | } | 1894 | } |
1795 | } | 1895 | } |
1796 | base = 10; | ||
1797 | is_sign = 0; | ||
1798 | 1896 | ||
1799 | if (!*fmt || !*str) | 1897 | if (!*fmt || !*str) |
1800 | break; | 1898 | break; |
1801 | 1899 | ||
1802 | switch(*fmt++) { | 1900 | base = 10; |
1901 | is_sign = 0; | ||
1902 | |||
1903 | switch (*fmt++) { | ||
1803 | case 'c': | 1904 | case 'c': |
1804 | { | 1905 | { |
1805 | char *s = (char *) va_arg(args,char*); | 1906 | char *s = (char *)va_arg(args, char*); |
1806 | if (field_width == -1) | 1907 | if (field_width == -1) |
1807 | field_width = 1; | 1908 | field_width = 1; |
1808 | do { | 1909 | do { |
@@ -1813,17 +1914,15 @@ int vsscanf(const char * buf, const char * fmt, va_list args) | |||
1813 | continue; | 1914 | continue; |
1814 | case 's': | 1915 | case 's': |
1815 | { | 1916 | { |
1816 | char *s = (char *) va_arg(args, char *); | 1917 | char *s = (char *)va_arg(args, char *); |
1817 | if(field_width == -1) | 1918 | if (field_width == -1) |
1818 | field_width = INT_MAX; | 1919 | field_width = INT_MAX; |
1819 | /* first, skip leading white space in buffer */ | 1920 | /* first, skip leading white space in buffer */ |
1820 | while (isspace(*str)) | 1921 | str = skip_spaces(str); |
1821 | str++; | ||
1822 | 1922 | ||
1823 | /* now copy until next white space */ | 1923 | /* now copy until next white space */ |
1824 | while (*str && !isspace(*str) && field_width--) { | 1924 | while (*str && !isspace(*str) && field_width--) |
1825 | *s++ = *str++; | 1925 | *s++ = *str++; |
1826 | } | ||
1827 | *s = '\0'; | 1926 | *s = '\0'; |
1828 | num++; | 1927 | num++; |
1829 | } | 1928 | } |
@@ -1831,7 +1930,7 @@ int vsscanf(const char * buf, const char * fmt, va_list args) | |||
1831 | case 'n': | 1930 | case 'n': |
1832 | /* return number of characters read so far */ | 1931 | /* return number of characters read so far */ |
1833 | { | 1932 | { |
1834 | int *i = (int *)va_arg(args,int*); | 1933 | int *i = (int *)va_arg(args, int*); |
1835 | *i = str - buf; | 1934 | *i = str - buf; |
1836 | } | 1935 | } |
1837 | continue; | 1936 | continue; |
@@ -1843,14 +1942,14 @@ int vsscanf(const char * buf, const char * fmt, va_list args) | |||
1843 | base = 16; | 1942 | base = 16; |
1844 | break; | 1943 | break; |
1845 | case 'i': | 1944 | case 'i': |
1846 | base = 0; | 1945 | base = 0; |
1847 | case 'd': | 1946 | case 'd': |
1848 | is_sign = 1; | 1947 | is_sign = 1; |
1849 | case 'u': | 1948 | case 'u': |
1850 | break; | 1949 | break; |
1851 | case '%': | 1950 | case '%': |
1852 | /* looking for '%' in str */ | 1951 | /* looking for '%' in str */ |
1853 | if (*str++ != '%') | 1952 | if (*str++ != '%') |
1854 | return num; | 1953 | return num; |
1855 | continue; | 1954 | continue; |
1856 | default: | 1955 | default: |
@@ -1861,71 +1960,70 @@ int vsscanf(const char * buf, const char * fmt, va_list args) | |||
1861 | /* have some sort of integer conversion. | 1960 | /* have some sort of integer conversion. |
1862 | * first, skip white space in buffer. | 1961 | * first, skip white space in buffer. |
1863 | */ | 1962 | */ |
1864 | while (isspace(*str)) | 1963 | str = skip_spaces(str); |
1865 | str++; | ||
1866 | 1964 | ||
1867 | digit = *str; | 1965 | digit = *str; |
1868 | if (is_sign && digit == '-') | 1966 | if (is_sign && digit == '-') |
1869 | digit = *(str + 1); | 1967 | digit = *(str + 1); |
1870 | 1968 | ||
1871 | if (!digit | 1969 | if (!digit |
1872 | || (base == 16 && !isxdigit(digit)) | 1970 | || (base == 16 && !isxdigit(digit)) |
1873 | || (base == 10 && !isdigit(digit)) | 1971 | || (base == 10 && !isdigit(digit)) |
1874 | || (base == 8 && (!isdigit(digit) || digit > '7')) | 1972 | || (base == 8 && (!isdigit(digit) || digit > '7')) |
1875 | || (base == 0 && !isdigit(digit))) | 1973 | || (base == 0 && !isdigit(digit))) |
1876 | break; | 1974 | break; |
1877 | 1975 | ||
1878 | switch(qualifier) { | 1976 | switch (qualifier) { |
1879 | case 'H': /* that's 'hh' in format */ | 1977 | case 'H': /* that's 'hh' in format */ |
1880 | if (is_sign) { | 1978 | if (is_sign) { |
1881 | signed char *s = (signed char *) va_arg(args,signed char *); | 1979 | signed char *s = (signed char *)va_arg(args, signed char *); |
1882 | *s = (signed char) simple_strtol(str,&next,base); | 1980 | *s = (signed char)simple_strtol(str, &next, base); |
1883 | } else { | 1981 | } else { |
1884 | unsigned char *s = (unsigned char *) va_arg(args, unsigned char *); | 1982 | unsigned char *s = (unsigned char *)va_arg(args, unsigned char *); |
1885 | *s = (unsigned char) simple_strtoul(str, &next, base); | 1983 | *s = (unsigned char)simple_strtoul(str, &next, base); |
1886 | } | 1984 | } |
1887 | break; | 1985 | break; |
1888 | case 'h': | 1986 | case 'h': |
1889 | if (is_sign) { | 1987 | if (is_sign) { |
1890 | short *s = (short *) va_arg(args,short *); | 1988 | short *s = (short *)va_arg(args, short *); |
1891 | *s = (short) simple_strtol(str,&next,base); | 1989 | *s = (short)simple_strtol(str, &next, base); |
1892 | } else { | 1990 | } else { |
1893 | unsigned short *s = (unsigned short *) va_arg(args, unsigned short *); | 1991 | unsigned short *s = (unsigned short *)va_arg(args, unsigned short *); |
1894 | *s = (unsigned short) simple_strtoul(str, &next, base); | 1992 | *s = (unsigned short)simple_strtoul(str, &next, base); |
1895 | } | 1993 | } |
1896 | break; | 1994 | break; |
1897 | case 'l': | 1995 | case 'l': |
1898 | if (is_sign) { | 1996 | if (is_sign) { |
1899 | long *l = (long *) va_arg(args,long *); | 1997 | long *l = (long *)va_arg(args, long *); |
1900 | *l = simple_strtol(str,&next,base); | 1998 | *l = simple_strtol(str, &next, base); |
1901 | } else { | 1999 | } else { |
1902 | unsigned long *l = (unsigned long*) va_arg(args,unsigned long*); | 2000 | unsigned long *l = (unsigned long *)va_arg(args, unsigned long *); |
1903 | *l = simple_strtoul(str,&next,base); | 2001 | *l = simple_strtoul(str, &next, base); |
1904 | } | 2002 | } |
1905 | break; | 2003 | break; |
1906 | case 'L': | 2004 | case 'L': |
1907 | if (is_sign) { | 2005 | if (is_sign) { |
1908 | long long *l = (long long*) va_arg(args,long long *); | 2006 | long long *l = (long long *)va_arg(args, long long *); |
1909 | *l = simple_strtoll(str,&next,base); | 2007 | *l = simple_strtoll(str, &next, base); |
1910 | } else { | 2008 | } else { |
1911 | unsigned long long *l = (unsigned long long*) va_arg(args,unsigned long long*); | 2009 | unsigned long long *l = (unsigned long long *)va_arg(args, unsigned long long *); |
1912 | *l = simple_strtoull(str,&next,base); | 2010 | *l = simple_strtoull(str, &next, base); |
1913 | } | 2011 | } |
1914 | break; | 2012 | break; |
1915 | case 'Z': | 2013 | case 'Z': |
1916 | case 'z': | 2014 | case 'z': |
1917 | { | 2015 | { |
1918 | size_t *s = (size_t*) va_arg(args,size_t*); | 2016 | size_t *s = (size_t *)va_arg(args, size_t *); |
1919 | *s = (size_t) simple_strtoul(str,&next,base); | 2017 | *s = (size_t)simple_strtoul(str, &next, base); |
1920 | } | 2018 | } |
1921 | break; | 2019 | break; |
1922 | default: | 2020 | default: |
1923 | if (is_sign) { | 2021 | if (is_sign) { |
1924 | int *i = (int *) va_arg(args, int*); | 2022 | int *i = (int *)va_arg(args, int *); |
1925 | *i = (int) simple_strtol(str,&next,base); | 2023 | *i = (int)simple_strtol(str, &next, base); |
1926 | } else { | 2024 | } else { |
1927 | unsigned int *i = (unsigned int*) va_arg(args, unsigned int*); | 2025 | unsigned int *i = (unsigned int *)va_arg(args, unsigned int*); |
1928 | *i = (unsigned int) simple_strtoul(str,&next,base); | 2026 | *i = (unsigned int)simple_strtoul(str, &next, base); |
1929 | } | 2027 | } |
1930 | break; | 2028 | break; |
1931 | } | 2029 | } |
@@ -1956,14 +2054,15 @@ EXPORT_SYMBOL(vsscanf); | |||
1956 | * @fmt: formatting of buffer | 2054 | * @fmt: formatting of buffer |
1957 | * @...: resulting arguments | 2055 | * @...: resulting arguments |
1958 | */ | 2056 | */ |
1959 | int sscanf(const char * buf, const char * fmt, ...) | 2057 | int sscanf(const char *buf, const char *fmt, ...) |
1960 | { | 2058 | { |
1961 | va_list args; | 2059 | va_list args; |
1962 | int i; | 2060 | int i; |
1963 | 2061 | ||
1964 | va_start(args,fmt); | 2062 | va_start(args, fmt); |
1965 | i = vsscanf(buf,fmt,args); | 2063 | i = vsscanf(buf, fmt, args); |
1966 | va_end(args); | 2064 | va_end(args); |
2065 | |||
1967 | return i; | 2066 | return i; |
1968 | } | 2067 | } |
1969 | EXPORT_SYMBOL(sscanf); | 2068 | EXPORT_SYMBOL(sscanf); |