1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#include <stdarg.h>
20#include <linux/module.h>
21#include <linux/types.h>
22#include <linux/string.h>
23#include <linux/ctype.h>
24#include <linux/kernel.h>
25#include <linux/kallsyms.h>
26#include <linux/uaccess.h>
27#include <linux/ioport.h>
28#include <net/addrconf.h>
29
30#include <asm/page.h>
31#include <asm/div64.h>
32#include <asm/sections.h>
33
34
35#define TOLOWER(x) ((x) | 0x20)
36
37static unsigned int simple_guess_base(const char *cp)
38{
39 if (cp[0] == '0') {
40 if (TOLOWER(cp[1]) == 'x' && isxdigit(cp[2]))
41 return 16;
42 else
43 return 8;
44 } else {
45 return 10;
46 }
47}
48
49
50
51
52
53
54
55unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base)
56{
57 unsigned long long result = 0;
58
59 if (!base)
60 base = simple_guess_base(cp);
61
62 if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x')
63 cp += 2;
64
65 while (isxdigit(*cp)) {
66 unsigned int value;
67
68 value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10;
69 if (value >= base)
70 break;
71 result = result * base + value;
72 cp++;
73 }
74 if (endp)
75 *endp = (char *)cp;
76
77 return result;
78}
79EXPORT_SYMBOL(simple_strtoull);
80
81
82
83
84
85
86
87unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base)
88{
89 return simple_strtoull(cp, endp, base);
90}
91EXPORT_SYMBOL(simple_strtoul);
92
93
94
95
96
97
98
99long simple_strtol(const char *cp, char **endp, unsigned int base)
100{
101 if (*cp == '-')
102 return -simple_strtoul(cp + 1, endp, base);
103
104 return simple_strtoul(cp, endp, base);
105}
106EXPORT_SYMBOL(simple_strtol);
107
108
109
110
111
112
113
114long long simple_strtoll(const char *cp, char **endp, unsigned int base)
115{
116 if (*cp == '-')
117 return -simple_strtoull(cp + 1, endp, base);
118
119 return simple_strtoull(cp, endp, base);
120}
121EXPORT_SYMBOL(simple_strtoll);
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145int strict_strtoul(const char *cp, unsigned int base, unsigned long *res)
146{
147 char *tail;
148 unsigned long val;
149 size_t len;
150
151 *res = 0;
152 len = strlen(cp);
153 if (len == 0)
154 return -EINVAL;
155
156 val = simple_strtoul(cp, &tail, base);
157 if (tail == cp)
158 return -EINVAL;
159
160 if ((*tail == '\0') ||
161 ((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) {
162 *res = val;
163 return 0;
164 }
165
166 return -EINVAL;
167}
168EXPORT_SYMBOL(strict_strtoul);
169
170
171
172
173
174
175
176
177
178
179
180
181
182int strict_strtol(const char *cp, unsigned int base, long *res)
183{
184 int ret;
185 if (*cp == '-') {
186 ret = strict_strtoul(cp + 1, base, (unsigned long *)res);
187 if (!ret)
188 *res = -(*res);
189 } else {
190 ret = strict_strtoul(cp, base, (unsigned long *)res);
191 }
192
193 return ret;
194}
195EXPORT_SYMBOL(strict_strtol);
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219int strict_strtoull(const char *cp, unsigned int base, unsigned long long *res)
220{
221 char *tail;
222 unsigned long long val;
223 size_t len;
224
225 *res = 0;
226 len = strlen(cp);
227 if (len == 0)
228 return -EINVAL;
229
230 val = simple_strtoull(cp, &tail, base);
231 if (tail == cp)
232 return -EINVAL;
233 if ((*tail == '\0') ||
234 ((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) {
235 *res = val;
236 return 0;
237 }
238
239 return -EINVAL;
240}
241EXPORT_SYMBOL(strict_strtoull);
242
243
244
245
246
247
248
249
250
251
252
253
254
255int strict_strtoll(const char *cp, unsigned int base, long long *res)
256{
257 int ret;
258 if (*cp == '-') {
259 ret = strict_strtoull(cp + 1, base, (unsigned long long *)res);
260 if (!ret)
261 *res = -(*res);
262 } else {
263 ret = strict_strtoull(cp, base, (unsigned long long *)res);
264 }
265
266 return ret;
267}
268EXPORT_SYMBOL(strict_strtoll);
269
270static noinline_for_stack
271int skip_atoi(const char **s)
272{
273 int i = 0;
274
275 while (isdigit(**s))
276 i = i*10 + *((*s)++) - '0';
277
278 return i;
279}
280
281
282
283
284
285
286
287
288
289
290
291static noinline_for_stack
292char *put_dec_trunc(char *buf, unsigned q)
293{
294 unsigned d3, d2, d1, d0;
295 d1 = (q>>4) & 0xf;
296 d2 = (q>>8) & 0xf;
297 d3 = (q>>12);
298
299 d0 = 6*(d3 + d2 + d1) + (q & 0xf);
300 q = (d0 * 0xcd) >> 11;
301 d0 = d0 - 10*q;
302 *buf++ = d0 + '0';
303 d1 = q + 9*d3 + 5*d2 + d1;
304 if (d1 != 0) {
305 q = (d1 * 0xcd) >> 11;
306 d1 = d1 - 10*q;
307 *buf++ = d1 + '0';
308
309 d2 = q + 2*d2;
310 if ((d2 != 0) || (d3 != 0)) {
311 q = (d2 * 0xd) >> 7;
312 d2 = d2 - 10*q;
313 *buf++ = d2 + '0';
314
315 d3 = q + 4*d3;
316 if (d3 != 0) {
317 q = (d3 * 0xcd) >> 11;
318 d3 = d3 - 10*q;
319 *buf++ = d3 + '0';
320 if (q != 0)
321 *buf++ = q + '0';
322 }
323 }
324 }
325
326 return buf;
327}
328
329static noinline_for_stack
330char *put_dec_full(char *buf, unsigned q)
331{
332
333
334 unsigned d3, d2, d1, d0;
335 d1 = (q>>4) & 0xf;
336 d2 = (q>>8) & 0xf;
337 d3 = (q>>12);
338
339
340
341
342
343
344
345
346
347
348 d0 = 6*(d3 + d2 + d1) + (q & 0xf);
349 q = (d0 * 0xcd) >> 11;
350 d0 = d0 - 10*q;
351 *buf++ = d0 + '0';
352 d1 = q + 9*d3 + 5*d2 + d1;
353 q = (d1 * 0xcd) >> 11;
354 d1 = d1 - 10*q;
355 *buf++ = d1 + '0';
356
357 d2 = q + 2*d2;
358 q = (d2 * 0xd) >> 7;
359 d2 = d2 - 10*q;
360 *buf++ = d2 + '0';
361
362 d3 = q + 4*d3;
363 q = (d3 * 0xcd) >> 11;
364
365 d3 = d3 - 10*q;
366 *buf++ = d3 + '0';
367 *buf++ = q + '0';
368
369 return buf;
370}
371
372static noinline_for_stack
373char *put_dec(char *buf, unsigned long long num)
374{
375 while (1) {
376 unsigned rem;
377 if (num < 100000)
378 return put_dec_trunc(buf, num);
379 rem = do_div(num, 100000);
380 buf = put_dec_full(buf, rem);
381 }
382}
383
384#define ZEROPAD 1
385#define SIGN 2
386#define PLUS 4
387#define SPACE 8
388#define LEFT 16
389#define SMALL 32
390#define SPECIAL 64
391
392enum format_type {
393 FORMAT_TYPE_NONE,
394 FORMAT_TYPE_WIDTH,
395 FORMAT_TYPE_PRECISION,
396 FORMAT_TYPE_CHAR,
397 FORMAT_TYPE_STR,
398 FORMAT_TYPE_PTR,
399 FORMAT_TYPE_PERCENT_CHAR,
400 FORMAT_TYPE_INVALID,
401 FORMAT_TYPE_LONG_LONG,
402 FORMAT_TYPE_ULONG,
403 FORMAT_TYPE_LONG,
404 FORMAT_TYPE_UBYTE,
405 FORMAT_TYPE_BYTE,
406 FORMAT_TYPE_USHORT,
407 FORMAT_TYPE_SHORT,
408 FORMAT_TYPE_UINT,
409 FORMAT_TYPE_INT,
410 FORMAT_TYPE_NRCHARS,
411 FORMAT_TYPE_SIZE_T,
412 FORMAT_TYPE_PTRDIFF
413};
414
415struct printf_spec {
416 u8 type;
417 u8 flags;
418 u8 base;
419 u8 qualifier;
420 s16 field_width;
421 s16 precision;
422};
423
424static noinline_for_stack
425char *number(char *buf, char *end, unsigned long long num,
426 struct printf_spec spec)
427{
428
429 static const char digits[16] = "0123456789ABCDEF";
430
431 char tmp[66];
432 char sign;
433 char locase;
434 int need_pfx = ((spec.flags & SPECIAL) && spec.base != 10);
435 int i;
436
437
438
439 locase = (spec.flags & SMALL);
440 if (spec.flags & LEFT)
441 spec.flags &= ~ZEROPAD;
442 sign = 0;
443 if (spec.flags & SIGN) {
444 if ((signed long long)num < 0) {
445 sign = '-';
446 num = -(signed long long)num;
447 spec.field_width--;
448 } else if (spec.flags & PLUS) {
449 sign = '+';
450 spec.field_width--;
451 } else if (spec.flags & SPACE) {
452 sign = ' ';
453 spec.field_width--;
454 }
455 }
456 if (need_pfx) {
457 spec.field_width--;
458 if (spec.base == 16)
459 spec.field_width--;
460 }
461
462
463 i = 0;
464 if (num == 0)
465 tmp[i++] = '0';
466
467
468
469
470
471 else if (spec.base != 10) {
472 int mask = spec.base - 1;
473 int shift = 3;
474
475 if (spec.base == 16)
476 shift = 4;
477 do {
478 tmp[i++] = (digits[((unsigned char)num) & mask] | locase);
479 num >>= shift;
480 } while (num);
481 } else {
482 i = put_dec(tmp, num) - tmp;
483 }
484
485
486 if (i > spec.precision)
487 spec.precision = i;
488
489 spec.field_width -= spec.precision;
490 if (!(spec.flags & (ZEROPAD+LEFT))) {
491 while (--spec.field_width >= 0) {
492 if (buf < end)
493 *buf = ' ';
494 ++buf;
495 }
496 }
497
498 if (sign) {
499 if (buf < end)
500 *buf = sign;
501 ++buf;
502 }
503
504 if (need_pfx) {
505 if (buf < end)
506 *buf = '0';
507 ++buf;
508 if (spec.base == 16) {
509 if (buf < end)
510 *buf = ('X' | locase);
511 ++buf;
512 }
513 }
514
515 if (!(spec.flags & LEFT)) {
516 char c = (spec.flags & ZEROPAD) ? '0' : ' ';
517 while (--spec.field_width >= 0) {
518 if (buf < end)
519 *buf = c;
520 ++buf;
521 }
522 }
523
524 while (i <= --spec.precision) {
525 if (buf < end)
526 *buf = '0';
527 ++buf;
528 }
529
530 while (--i >= 0) {
531 if (buf < end)
532 *buf = tmp[i];
533 ++buf;
534 }
535
536 while (--spec.field_width >= 0) {
537 if (buf < end)
538 *buf = ' ';
539 ++buf;
540 }
541
542 return buf;
543}
544
545static noinline_for_stack
546char *string(char *buf, char *end, const char *s, struct printf_spec spec)
547{
548 int len, i;
549
550 if ((unsigned long)s < PAGE_SIZE)
551 s = "(null)";
552
553 len = strnlen(s, spec.precision);
554
555 if (!(spec.flags & LEFT)) {
556 while (len < spec.field_width--) {
557 if (buf < end)
558 *buf = ' ';
559 ++buf;
560 }
561 }
562 for (i = 0; i < len; ++i) {
563 if (buf < end)
564 *buf = *s;
565 ++buf; ++s;
566 }
567 while (len < spec.field_width--) {
568 if (buf < end)
569 *buf = ' ';
570 ++buf;
571 }
572
573 return buf;
574}
575
576static noinline_for_stack
577char *symbol_string(char *buf, char *end, void *ptr,
578 struct printf_spec spec, char ext)
579{
580 unsigned long value = (unsigned long) ptr;
581#ifdef CONFIG_KALLSYMS
582 char sym[KSYM_SYMBOL_LEN];
583 if (ext != 'f' && ext != 's')
584 sprint_symbol(sym, value);
585 else
586 kallsyms_lookup(value, NULL, NULL, NULL, sym);
587
588 return string(buf, end, sym, spec);
589#else
590 spec.field_width = 2 * sizeof(void *);
591 spec.flags |= SPECIAL | SMALL | ZEROPAD;
592 spec.base = 16;
593
594 return number(buf, end, value, spec);
595#endif
596}
597
598static noinline_for_stack
599char *resource_string(char *buf, char *end, struct resource *res,
600 struct printf_spec spec, const char *fmt)
601{
602#ifndef IO_RSRC_PRINTK_SIZE
603#define IO_RSRC_PRINTK_SIZE 6
604#endif
605
606#ifndef MEM_RSRC_PRINTK_SIZE
607#define MEM_RSRC_PRINTK_SIZE 10
608#endif
609 static const struct printf_spec io_spec = {
610 .base = 16,
611 .field_width = IO_RSRC_PRINTK_SIZE,
612 .precision = -1,
613 .flags = SPECIAL | SMALL | ZEROPAD,
614 };
615 static const struct printf_spec mem_spec = {
616 .base = 16,
617 .field_width = MEM_RSRC_PRINTK_SIZE,
618 .precision = -1,
619 .flags = SPECIAL | SMALL | ZEROPAD,
620 };
621 static const struct printf_spec bus_spec = {
622 .base = 16,
623 .field_width = 2,
624 .precision = -1,
625 .flags = SMALL | ZEROPAD,
626 };
627 static const struct printf_spec dec_spec = {
628 .base = 10,
629 .precision = -1,
630 .flags = 0,
631 };
632 static const struct printf_spec str_spec = {
633 .field_width = -1,
634 .precision = 10,
635 .flags = LEFT,
636 };
637 static const struct printf_spec flag_spec = {
638 .base = 16,
639 .precision = -1,
640 .flags = SPECIAL | SMALL,
641 };
642
643
644
645#define RSRC_BUF_SIZE ((2 * sizeof(resource_size_t)) + 4)
646#define FLAG_BUF_SIZE (2 * sizeof(res->flags))
647#define DECODED_BUF_SIZE sizeof("[mem - 64bit pref window disabled]")
648#define RAW_BUF_SIZE sizeof("[mem - flags 0x]")
649 char sym[max(2*RSRC_BUF_SIZE + DECODED_BUF_SIZE,
650 2*RSRC_BUF_SIZE + FLAG_BUF_SIZE + RAW_BUF_SIZE)];
651
652 char *p = sym, *pend = sym + sizeof(sym);
653 int decode = (fmt[0] == 'R') ? 1 : 0;
654 const struct printf_spec *specp;
655
656 *p++ = '[';
657 if (res->flags & IORESOURCE_IO) {
658 p = string(p, pend, "io ", str_spec);
659 specp = &io_spec;
660 } else if (res->flags & IORESOURCE_MEM) {
661 p = string(p, pend, "mem ", str_spec);
662 specp = &mem_spec;
663 } else if (res->flags & IORESOURCE_IRQ) {
664 p = string(p, pend, "irq ", str_spec);
665 specp = &dec_spec;
666 } else if (res->flags & IORESOURCE_DMA) {
667 p = string(p, pend, "dma ", str_spec);
668 specp = &dec_spec;
669 } else if (res->flags & IORESOURCE_BUS) {
670 p = string(p, pend, "bus ", str_spec);
671 specp = &bus_spec;
672 } else {
673 p = string(p, pend, "??? ", str_spec);
674 specp = &mem_spec;
675 decode = 0;
676 }
677 p = number(p, pend, res->start, *specp);
678 if (res->start != res->end) {
679 *p++ = '-';
680 p = number(p, pend, res->end, *specp);
681 }
682 if (decode) {
683 if (res->flags & IORESOURCE_MEM_64)
684 p = string(p, pend, " 64bit", str_spec);
685 if (res->flags & IORESOURCE_PREFETCH)
686 p = string(p, pend, " pref", str_spec);
687 if (res->flags & IORESOURCE_WINDOW)
688 p = string(p, pend, " window", str_spec);
689 if (res->flags & IORESOURCE_DISABLED)
690 p = string(p, pend, " disabled", str_spec);
691 } else {
692 p = string(p, pend, " flags ", str_spec);
693 p = number(p, pend, res->flags, flag_spec);
694 }
695 *p++ = ']';
696 *p = '\0';
697
698 return string(buf, end, sym, spec);
699}
700
701static noinline_for_stack
702char *mac_address_string(char *buf, char *end, u8 *addr,
703 struct printf_spec spec, const char *fmt)
704{
705 char mac_addr[sizeof("xx:xx:xx:xx:xx:xx")];
706 char *p = mac_addr;
707 int i;
708 char separator;
709
710 if (fmt[1] == 'F') {
711 separator = '-';
712 } else {
713 separator = ':';
714 }
715
716 for (i = 0; i < 6; i++) {
717 p = pack_hex_byte(p, addr[i]);
718 if (fmt[0] == 'M' && i != 5)
719 *p++ = separator;
720 }
721 *p = '\0';
722
723 return string(buf, end, mac_addr, spec);
724}
725
726static noinline_for_stack
727char *ip4_string(char *p, const u8 *addr, const char *fmt)
728{
729 int i;
730 bool leading_zeros = (fmt[0] == 'i');
731 int index;
732 int step;
733
734 switch (fmt[2]) {
735 case 'h':
736#ifdef __BIG_ENDIAN
737 index = 0;
738 step = 1;
739#else
740 index = 3;
741 step = -1;
742#endif
743 break;
744 case 'l':
745 index = 3;
746 step = -1;
747 break;
748 case 'n':
749 case 'b':
750 default:
751 index = 0;
752 step = 1;
753 break;
754 }
755 for (i = 0; i < 4; i++) {
756 char temp[3];
757 int digits = put_dec_trunc(temp, addr[index]) - temp;
758 if (leading_zeros) {
759 if (digits < 3)
760 *p++ = '0';
761 if (digits < 2)
762 *p++ = '0';
763 }
764
765 while (digits--)
766 *p++ = temp[digits];
767 if (i < 3)
768 *p++ = '.';
769 index += step;
770 }
771 *p = '\0';
772
773 return p;
774}
775
776static noinline_for_stack
777char *ip6_compressed_string(char *p, const char *addr)
778{
779 int i, j, range;
780 unsigned char zerolength[8];
781 int longest = 1;
782 int colonpos = -1;
783 u16 word;
784 u8 hi, lo;
785 bool needcolon = false;
786 bool useIPv4;
787 struct in6_addr in6;
788
789 memcpy(&in6, addr, sizeof(struct in6_addr));
790
791 useIPv4 = ipv6_addr_v4mapped(&in6) || ipv6_addr_is_isatap(&in6);
792
793 memset(zerolength, 0, sizeof(zerolength));
794
795 if (useIPv4)
796 range = 6;
797 else
798 range = 8;
799
800
801 for (i = 0; i < range; i++) {
802 for (j = i; j < range; j++) {
803 if (in6.s6_addr16[j] != 0)
804 break;
805 zerolength[i]++;
806 }
807 }
808 for (i = 0; i < range; i++) {
809 if (zerolength[i] > longest) {
810 longest = zerolength[i];
811 colonpos = i;
812 }
813 }
814
815
816 for (i = 0; i < range; i++) {
817 if (i == colonpos) {
818 if (needcolon || i == 0)
819 *p++ = ':';
820 *p++ = ':';
821 needcolon = false;
822 i += longest - 1;
823 continue;
824 }
825 if (needcolon) {
826 *p++ = ':';
827 needcolon = false;
828 }
829
830 word = ntohs(in6.s6_addr16[i]);
831 hi = word >> 8;
832 lo = word & 0xff;
833 if (hi) {
834 if (hi > 0x0f)
835 p = pack_hex_byte(p, hi);
836 else
837 *p++ = hex_asc_lo(hi);
838 p = pack_hex_byte(p, lo);
839 }
840 else if (lo > 0x0f)
841 p = pack_hex_byte(p, lo);
842 else
843 *p++ = hex_asc_lo(lo);
844 needcolon = true;
845 }
846
847 if (useIPv4) {
848 if (needcolon)
849 *p++ = ':';
850 p = ip4_string(p, &in6.s6_addr[12], "I4");
851 }
852 *p = '\0';
853
854 return p;
855}
856
857static noinline_for_stack
858char *ip6_string(char *p, const char *addr, const char *fmt)
859{
860 int i;
861
862 for (i = 0; i < 8; i++) {
863 p = pack_hex_byte(p, *addr++);
864 p = pack_hex_byte(p, *addr++);
865 if (fmt[0] == 'I' && i != 7)
866 *p++ = ':';
867 }
868 *p = '\0';
869
870 return p;
871}
872
873static noinline_for_stack
874char *ip6_addr_string(char *buf, char *end, const u8 *addr,
875 struct printf_spec spec, const char *fmt)
876{
877 char ip6_addr[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255")];
878
879 if (fmt[0] == 'I' && fmt[2] == 'c')
880 ip6_compressed_string(ip6_addr, addr);
881 else
882 ip6_string(ip6_addr, addr, fmt);
883
884 return string(buf, end, ip6_addr, spec);
885}
886
887static noinline_for_stack
888char *ip4_addr_string(char *buf, char *end, const u8 *addr,
889 struct printf_spec spec, const char *fmt)
890{
891 char ip4_addr[sizeof("255.255.255.255")];
892
893 ip4_string(ip4_addr, addr, fmt);
894
895 return string(buf, end, ip4_addr, spec);
896}
897
898static noinline_for_stack
899char *uuid_string(char *buf, char *end, const u8 *addr,
900 struct printf_spec spec, const char *fmt)
901{
902 char uuid[sizeof("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")];
903 char *p = uuid;
904 int i;
905 static const u8 be[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
906 static const u8 le[16] = {3,2,1,0,5,4,7,6,8,9,10,11,12,13,14,15};
907 const u8 *index = be;
908 bool uc = false;
909
910 switch (*(++fmt)) {
911 case 'L':
912 uc = true;
913 case 'l':
914 index = le;
915 break;
916 case 'B':
917 uc = true;
918 break;
919 }
920
921 for (i = 0; i < 16; i++) {
922 p = pack_hex_byte(p, addr[index[i]]);
923 switch (i) {
924 case 3:
925 case 5:
926 case 7:
927 case 9:
928 *p++ = '-';
929 break;
930 }
931 }
932
933 *p = 0;
934
935 if (uc) {
936 p = uuid;
937 do {
938 *p = toupper(*p);
939 } while (*(++p));
940 }
941
942 return string(buf, end, uuid, spec);
943}
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988static noinline_for_stack
989char *pointer(const char *fmt, char *buf, char *end, void *ptr,
990 struct printf_spec spec)
991{
992 if (!ptr)
993 return string(buf, end, "(null)", spec);
994
995 switch (*fmt) {
996 case 'F':
997 case 'f':
998 ptr = dereference_function_descriptor(ptr);
999
1000 case 'S':
1001 case 's':
1002 return symbol_string(buf, end, ptr, spec, *fmt);
1003 case 'R':
1004 case 'r':
1005 return resource_string(buf, end, ptr, spec, fmt);
1006 case 'M':
1007 case 'm':
1008
1009 return mac_address_string(buf, end, ptr, spec, fmt);
1010 case 'I':
1011
1012
1013
1014
1015 case 'i':
1016
1017
1018
1019 switch (fmt[1]) {
1020 case '6':
1021 return ip6_addr_string(buf, end, ptr, spec, fmt);
1022 case '4':
1023 return ip4_addr_string(buf, end, ptr, spec, fmt);
1024 }
1025 break;
1026 case 'U':
1027 return uuid_string(buf, end, ptr, spec, fmt);
1028 }
1029 spec.flags |= SMALL;
1030 if (spec.field_width == -1) {
1031 spec.field_width = 2*sizeof(void *);
1032 spec.flags |= ZEROPAD;
1033 }
1034 spec.base = 16;
1035
1036 return number(buf, end, (unsigned long) ptr, spec);
1037}
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059static noinline_for_stack
1060int format_decode(const char *fmt, struct printf_spec *spec)
1061{
1062 const char *start = fmt;
1063
1064
1065 if (spec->type == FORMAT_TYPE_WIDTH) {
1066 if (spec->field_width < 0) {
1067 spec->field_width = -spec->field_width;
1068 spec->flags |= LEFT;
1069 }
1070 spec->type = FORMAT_TYPE_NONE;
1071 goto precision;
1072 }
1073
1074
1075 if (spec->type == FORMAT_TYPE_PRECISION) {
1076 if (spec->precision < 0)
1077 spec->precision = 0;
1078
1079 spec->type = FORMAT_TYPE_NONE;
1080 goto qualifier;
1081 }
1082
1083
1084 spec->type = FORMAT_TYPE_NONE;
1085
1086 for (; *fmt ; ++fmt) {
1087 if (*fmt == '%')
1088 break;
1089 }
1090
1091
1092 if (fmt != start || !*fmt)
1093 return fmt - start;
1094
1095
1096 spec->flags = 0;
1097
1098 while (1) {
1099 bool found = true;
1100
1101 ++fmt;
1102
1103 switch (*fmt) {
1104 case '-': spec->flags |= LEFT; break;
1105 case '+': spec->flags |= PLUS; break;
1106 case ' ': spec->flags |= SPACE; break;
1107 case '#': spec->flags |= SPECIAL; break;
1108 case '0': spec->flags |= ZEROPAD; break;
1109 default: found = false;
1110 }
1111
1112 if (!found)
1113 break;
1114 }
1115
1116
1117 spec->field_width = -1;
1118
1119 if (isdigit(*fmt))
1120 spec->field_width = skip_atoi(&fmt);
1121 else if (*fmt == '*') {
1122
1123 spec->type = FORMAT_TYPE_WIDTH;
1124 return ++fmt - start;
1125 }
1126
1127precision:
1128
1129 spec->precision = -1;
1130 if (*fmt == '.') {
1131 ++fmt;
1132 if (isdigit(*fmt)) {
1133 spec->precision = skip_atoi(&fmt);
1134 if (spec->precision < 0)
1135 spec->precision = 0;
1136 } else if (*fmt == '*') {
1137
1138 spec->type = FORMAT_TYPE_PRECISION;
1139 return ++fmt - start;
1140 }
1141 }
1142
1143qualifier:
1144
1145 spec->qualifier = -1;
1146 if (*fmt == 'h' || TOLOWER(*fmt) == 'l' ||
1147 TOLOWER(*fmt) == 'z' || *fmt == 't') {
1148 spec->qualifier = *fmt++;
1149 if (unlikely(spec->qualifier == *fmt)) {
1150 if (spec->qualifier == 'l') {
1151 spec->qualifier = 'L';
1152 ++fmt;
1153 } else if (spec->qualifier == 'h') {
1154 spec->qualifier = 'H';
1155 ++fmt;
1156 }
1157 }
1158 }
1159
1160
1161 spec->base = 10;
1162 switch (*fmt) {
1163 case 'c':
1164 spec->type = FORMAT_TYPE_CHAR;
1165 return ++fmt - start;
1166
1167 case 's':
1168 spec->type = FORMAT_TYPE_STR;
1169 return ++fmt - start;
1170
1171 case 'p':
1172 spec->type = FORMAT_TYPE_PTR;
1173 return fmt - start;
1174
1175
1176 case 'n':
1177 spec->type = FORMAT_TYPE_NRCHARS;
1178 return ++fmt - start;
1179
1180 case '%':
1181 spec->type = FORMAT_TYPE_PERCENT_CHAR;
1182 return ++fmt - start;
1183
1184
1185 case 'o':
1186 spec->base = 8;
1187 break;
1188
1189 case 'x':
1190 spec->flags |= SMALL;
1191
1192 case 'X':
1193 spec->base = 16;
1194 break;
1195
1196 case 'd':
1197 case 'i':
1198 spec->flags |= SIGN;
1199 case 'u':
1200 break;
1201
1202 default:
1203 spec->type = FORMAT_TYPE_INVALID;
1204 return fmt - start;
1205 }
1206
1207 if (spec->qualifier == 'L')
1208 spec->type = FORMAT_TYPE_LONG_LONG;
1209 else if (spec->qualifier == 'l') {
1210 if (spec->flags & SIGN)
1211 spec->type = FORMAT_TYPE_LONG;
1212 else
1213 spec->type = FORMAT_TYPE_ULONG;
1214 } else if (TOLOWER(spec->qualifier) == 'z') {
1215 spec->type = FORMAT_TYPE_SIZE_T;
1216 } else if (spec->qualifier == 't') {
1217 spec->type = FORMAT_TYPE_PTRDIFF;
1218 } else if (spec->qualifier == 'H') {
1219 if (spec->flags & SIGN)
1220 spec->type = FORMAT_TYPE_BYTE;
1221 else
1222 spec->type = FORMAT_TYPE_UBYTE;
1223 } else if (spec->qualifier == 'h') {
1224 if (spec->flags & SIGN)
1225 spec->type = FORMAT_TYPE_SHORT;
1226 else
1227 spec->type = FORMAT_TYPE_USHORT;
1228 } else {
1229 if (spec->flags & SIGN)
1230 spec->type = FORMAT_TYPE_INT;
1231 else
1232 spec->type = FORMAT_TYPE_UINT;
1233 }
1234
1235 return ++fmt - start;
1236}
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
1276{
1277 unsigned long long num;
1278 char *str, *end;
1279 struct printf_spec spec = {0};
1280
1281
1282
1283 if (WARN_ON_ONCE((int) size < 0))
1284 return 0;
1285
1286 str = buf;
1287 end = buf + size;
1288
1289
1290 if (end < buf) {
1291 end = ((void *)-1);
1292 size = end - buf;
1293 }
1294
1295 while (*fmt) {
1296 const char *old_fmt = fmt;
1297 int read = format_decode(fmt, &spec);
1298
1299 fmt += read;
1300
1301 switch (spec.type) {
1302 case FORMAT_TYPE_NONE: {
1303 int copy = read;
1304 if (str < end) {
1305 if (copy > end - str)
1306 copy = end - str;
1307 memcpy(str, old_fmt, copy);
1308 }
1309 str += read;
1310 break;
1311 }
1312
1313 case FORMAT_TYPE_WIDTH:
1314 spec.field_width = va_arg(args, int);
1315 break;
1316
1317 case FORMAT_TYPE_PRECISION:
1318 spec.precision = va_arg(args, int);
1319 break;
1320
1321 case FORMAT_TYPE_CHAR: {
1322 char c;
1323
1324 if (!(spec.flags & LEFT)) {
1325 while (--spec.field_width > 0) {
1326 if (str < end)
1327 *str = ' ';
1328 ++str;
1329
1330 }
1331 }
1332 c = (unsigned char) va_arg(args, int);
1333 if (str < end)
1334 *str = c;
1335 ++str;
1336 while (--spec.field_width > 0) {
1337 if (str < end)
1338 *str = ' ';
1339 ++str;
1340 }
1341 break;
1342 }
1343
1344 case FORMAT_TYPE_STR:
1345 str = string(str, end, va_arg(args, char *), spec);
1346 break;
1347
1348 case FORMAT_TYPE_PTR:
1349 str = pointer(fmt+1, str, end, va_arg(args, void *),
1350 spec);
1351 while (isalnum(*fmt))
1352 fmt++;
1353 break;
1354
1355 case FORMAT_TYPE_PERCENT_CHAR:
1356 if (str < end)
1357 *str = '%';
1358 ++str;
1359 break;
1360
1361 case FORMAT_TYPE_INVALID:
1362 if (str < end)
1363 *str = '%';
1364 ++str;
1365 break;
1366
1367 case FORMAT_TYPE_NRCHARS: {
1368 u8 qualifier = spec.qualifier;
1369
1370 if (qualifier == 'l') {
1371 long *ip = va_arg(args, long *);
1372 *ip = (str - buf);
1373 } else if (TOLOWER(qualifier) == 'z') {
1374 size_t *ip = va_arg(args, size_t *);
1375 *ip = (str - buf);
1376 } else {
1377 int *ip = va_arg(args, int *);
1378 *ip = (str - buf);
1379 }
1380 break;
1381 }
1382
1383 default:
1384 switch (spec.type) {
1385 case FORMAT_TYPE_LONG_LONG:
1386 num = va_arg(args, long long);
1387 break;
1388 case FORMAT_TYPE_ULONG:
1389 num = va_arg(args, unsigned long);
1390 break;
1391 case FORMAT_TYPE_LONG:
1392 num = va_arg(args, long);
1393 break;
1394 case FORMAT_TYPE_SIZE_T:
1395 num = va_arg(args, size_t);
1396 break;
1397 case FORMAT_TYPE_PTRDIFF:
1398 num = va_arg(args, ptrdiff_t);
1399 break;
1400 case FORMAT_TYPE_UBYTE:
1401 num = (unsigned char) va_arg(args, int);
1402 break;
1403 case FORMAT_TYPE_BYTE:
1404 num = (signed char) va_arg(args, int);
1405 break;
1406 case FORMAT_TYPE_USHORT:
1407 num = (unsigned short) va_arg(args, int);
1408 break;
1409 case FORMAT_TYPE_SHORT:
1410 num = (short) va_arg(args, int);
1411 break;
1412 case FORMAT_TYPE_INT:
1413 num = (int) va_arg(args, int);
1414 break;
1415 default:
1416 num = va_arg(args, unsigned int);
1417 }
1418
1419 str = number(str, end, num, spec);
1420 }
1421 }
1422
1423 if (size > 0) {
1424 if (str < end)
1425 *str = '\0';
1426 else
1427 end[-1] = '\0';
1428 }
1429
1430
1431 return str-buf;
1432
1433}
1434EXPORT_SYMBOL(vsnprintf);
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
1453{
1454 int i;
1455
1456 i = vsnprintf(buf, size, fmt, args);
1457
1458 return (i >= size) ? (size - 1) : i;
1459}
1460EXPORT_SYMBOL(vscnprintf);
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476int snprintf(char *buf, size_t size, const char *fmt, ...)
1477{
1478 va_list args;
1479 int i;
1480
1481 va_start(args, fmt);
1482 i = vsnprintf(buf, size, fmt, args);
1483 va_end(args);
1484
1485 return i;
1486}
1487EXPORT_SYMBOL(snprintf);
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500int scnprintf(char *buf, size_t size, const char *fmt, ...)
1501{
1502 va_list args;
1503 int i;
1504
1505 va_start(args, fmt);
1506 i = vsnprintf(buf, size, fmt, args);
1507 va_end(args);
1508
1509 return (i >= size) ? (size - 1) : i;
1510}
1511EXPORT_SYMBOL(scnprintf);
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528int vsprintf(char *buf, const char *fmt, va_list args)
1529{
1530 return vsnprintf(buf, INT_MAX, fmt, args);
1531}
1532EXPORT_SYMBOL(vsprintf);
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546int sprintf(char *buf, const char *fmt, ...)
1547{
1548 va_list args;
1549 int i;
1550
1551 va_start(args, fmt);
1552 i = vsnprintf(buf, INT_MAX, fmt, args);
1553 va_end(args);
1554
1555 return i;
1556}
1557EXPORT_SYMBOL(sprintf);
1558
1559#ifdef CONFIG_BINARY_PRINTF
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args)
1584{
1585 struct printf_spec spec = {0};
1586 char *str, *end;
1587
1588 str = (char *)bin_buf;
1589 end = (char *)(bin_buf + size);
1590
1591#define save_arg(type) \
1592do { \
1593 if (sizeof(type) == 8) { \
1594 unsigned long long value; \
1595 str = PTR_ALIGN(str, sizeof(u32)); \
1596 value = va_arg(args, unsigned long long); \
1597 if (str + sizeof(type) <= end) { \
1598 *(u32 *)str = *(u32 *)&value; \
1599 *(u32 *)(str + 4) = *((u32 *)&value + 1); \
1600 } \
1601 } else { \
1602 unsigned long value; \
1603 str = PTR_ALIGN(str, sizeof(type)); \
1604 value = va_arg(args, int); \
1605 if (str + sizeof(type) <= end) \
1606 *(typeof(type) *)str = (type)value; \
1607 } \
1608 str += sizeof(type); \
1609} while (0)
1610
1611 while (*fmt) {
1612 int read = format_decode(fmt, &spec);
1613
1614 fmt += read;
1615
1616 switch (spec.type) {
1617 case FORMAT_TYPE_NONE:
1618 case FORMAT_TYPE_INVALID:
1619 case FORMAT_TYPE_PERCENT_CHAR:
1620 break;
1621
1622 case FORMAT_TYPE_WIDTH:
1623 case FORMAT_TYPE_PRECISION:
1624 save_arg(int);
1625 break;
1626
1627 case FORMAT_TYPE_CHAR:
1628 save_arg(char);
1629 break;
1630
1631 case FORMAT_TYPE_STR: {
1632 const char *save_str = va_arg(args, char *);
1633 size_t len;
1634
1635 if ((unsigned long)save_str > (unsigned long)-PAGE_SIZE
1636 || (unsigned long)save_str < PAGE_SIZE)
1637 save_str = "(null)";
1638 len = strlen(save_str) + 1;
1639 if (str + len < end)
1640 memcpy(str, save_str, len);
1641 str += len;
1642 break;
1643 }
1644
1645 case FORMAT_TYPE_PTR:
1646 save_arg(void *);
1647
1648 while (isalnum(*fmt))
1649 fmt++;
1650 break;
1651
1652 case FORMAT_TYPE_NRCHARS: {
1653
1654 u8 qualifier = spec.qualifier;
1655 void *skip_arg;
1656 if (qualifier == 'l')
1657 skip_arg = va_arg(args, long *);
1658 else if (TOLOWER(qualifier) == 'z')
1659 skip_arg = va_arg(args, size_t *);
1660 else
1661 skip_arg = va_arg(args, int *);
1662 break;
1663 }
1664
1665 default:
1666 switch (spec.type) {
1667
1668 case FORMAT_TYPE_LONG_LONG:
1669 save_arg(long long);
1670 break;
1671 case FORMAT_TYPE_ULONG:
1672 case FORMAT_TYPE_LONG:
1673 save_arg(unsigned long);
1674 break;
1675 case FORMAT_TYPE_SIZE_T:
1676 save_arg(size_t);
1677 break;
1678 case FORMAT_TYPE_PTRDIFF:
1679 save_arg(ptrdiff_t);
1680 break;
1681 case FORMAT_TYPE_UBYTE:
1682 case FORMAT_TYPE_BYTE:
1683 save_arg(char);
1684 break;
1685 case FORMAT_TYPE_USHORT:
1686 case FORMAT_TYPE_SHORT:
1687 save_arg(short);
1688 break;
1689 default:
1690 save_arg(int);
1691 }
1692 }
1693 }
1694
1695 return (u32 *)(PTR_ALIGN(str, sizeof(u32))) - bin_buf;
1696#undef save_arg
1697}
1698EXPORT_SYMBOL_GPL(vbin_printf);
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
1723{
1724 struct printf_spec spec = {0};
1725 char *str, *end;
1726 const char *args = (const char *)bin_buf;
1727
1728 if (WARN_ON_ONCE((int) size < 0))
1729 return 0;
1730
1731 str = buf;
1732 end = buf + size;
1733
1734#define get_arg(type) \
1735({ \
1736 typeof(type) value; \
1737 if (sizeof(type) == 8) { \
1738 args = PTR_ALIGN(args, sizeof(u32)); \
1739 *(u32 *)&value = *(u32 *)args; \
1740 *((u32 *)&value + 1) = *(u32 *)(args + 4); \
1741 } else { \
1742 args = PTR_ALIGN(args, sizeof(type)); \
1743 value = *(typeof(type) *)args; \
1744 } \
1745 args += sizeof(type); \
1746 value; \
1747})
1748
1749
1750 if (end < buf) {
1751 end = ((void *)-1);
1752 size = end - buf;
1753 }
1754
1755 while (*fmt) {
1756 const char *old_fmt = fmt;
1757 int read = format_decode(fmt, &spec);
1758
1759 fmt += read;
1760
1761 switch (spec.type) {
1762 case FORMAT_TYPE_NONE: {
1763 int copy = read;
1764 if (str < end) {
1765 if (copy > end - str)
1766 copy = end - str;
1767 memcpy(str, old_fmt, copy);
1768 }
1769 str += read;
1770 break;
1771 }
1772
1773 case FORMAT_TYPE_WIDTH:
1774 spec.field_width = get_arg(int);
1775 break;
1776
1777 case FORMAT_TYPE_PRECISION:
1778 spec.precision = get_arg(int);
1779 break;
1780
1781 case FORMAT_TYPE_CHAR: {
1782 char c;
1783
1784 if (!(spec.flags & LEFT)) {
1785 while (--spec.field_width > 0) {
1786 if (str < end)
1787 *str = ' ';
1788 ++str;
1789 }
1790 }
1791 c = (unsigned char) get_arg(char);
1792 if (str < end)
1793 *str = c;
1794 ++str;
1795 while (--spec.field_width > 0) {
1796 if (str < end)
1797 *str = ' ';
1798 ++str;
1799 }
1800 break;
1801 }
1802
1803 case FORMAT_TYPE_STR: {
1804 const char *str_arg = args;
1805 args += strlen(str_arg) + 1;
1806 str = string(str, end, (char *)str_arg, spec);
1807 break;
1808 }
1809
1810 case FORMAT_TYPE_PTR:
1811 str = pointer(fmt+1, str, end, get_arg(void *), spec);
1812 while (isalnum(*fmt))
1813 fmt++;
1814 break;
1815
1816 case FORMAT_TYPE_PERCENT_CHAR:
1817 case FORMAT_TYPE_INVALID:
1818 if (str < end)
1819 *str = '%';
1820 ++str;
1821 break;
1822
1823 case FORMAT_TYPE_NRCHARS:
1824
1825 break;
1826
1827 default: {
1828 unsigned long long num;
1829
1830 switch (spec.type) {
1831
1832 case FORMAT_TYPE_LONG_LONG:
1833 num = get_arg(long long);
1834 break;
1835 case FORMAT_TYPE_ULONG:
1836 case FORMAT_TYPE_LONG:
1837 num = get_arg(unsigned long);
1838 break;
1839 case FORMAT_TYPE_SIZE_T:
1840 num = get_arg(size_t);
1841 break;
1842 case FORMAT_TYPE_PTRDIFF:
1843 num = get_arg(ptrdiff_t);
1844 break;
1845 case FORMAT_TYPE_UBYTE:
1846 num = get_arg(unsigned char);
1847 break;
1848 case FORMAT_TYPE_BYTE:
1849 num = get_arg(signed char);
1850 break;
1851 case FORMAT_TYPE_USHORT:
1852 num = get_arg(unsigned short);
1853 break;
1854 case FORMAT_TYPE_SHORT:
1855 num = get_arg(short);
1856 break;
1857 case FORMAT_TYPE_UINT:
1858 num = get_arg(unsigned int);
1859 break;
1860 default:
1861 num = get_arg(int);
1862 }
1863
1864 str = number(str, end, num, spec);
1865 }
1866 }
1867 }
1868
1869 if (size > 0) {
1870 if (str < end)
1871 *str = '\0';
1872 else
1873 end[-1] = '\0';
1874 }
1875
1876#undef get_arg
1877
1878
1879 return str - buf;
1880}
1881EXPORT_SYMBOL_GPL(bstr_printf);
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893int bprintf(u32 *bin_buf, size_t size, const char *fmt, ...)
1894{
1895 va_list args;
1896 int ret;
1897
1898 va_start(args, fmt);
1899 ret = vbin_printf(bin_buf, size, fmt, args);
1900 va_end(args);
1901
1902 return ret;
1903}
1904EXPORT_SYMBOL_GPL(bprintf);
1905
1906#endif
1907
1908
1909
1910
1911
1912
1913
1914int vsscanf(const char *buf, const char *fmt, va_list args)
1915{
1916 const char *str = buf;
1917 char *next;
1918 char digit;
1919 int num = 0;
1920 u8 qualifier;
1921 u8 base;
1922 s16 field_width;
1923 bool is_sign;
1924
1925 while (*fmt && *str) {
1926
1927
1928
1929
1930 if (isspace(*fmt)) {
1931 fmt = skip_spaces(++fmt);
1932 str = skip_spaces(str);
1933 }
1934
1935
1936 if (*fmt != '%' && *fmt) {
1937 if (*fmt++ != *str++)
1938 break;
1939 continue;
1940 }
1941
1942 if (!*fmt)
1943 break;
1944 ++fmt;
1945
1946
1947
1948
1949 if (*fmt == '*') {
1950 while (!isspace(*fmt) && *fmt != '%' && *fmt)
1951 fmt++;
1952 while (!isspace(*str) && *str)
1953 str++;
1954 continue;
1955 }
1956
1957
1958 field_width = -1;
1959 if (isdigit(*fmt))
1960 field_width = skip_atoi(&fmt);
1961
1962
1963 qualifier = -1;
1964 if (*fmt == 'h' || TOLOWER(*fmt) == 'l' ||
1965 TOLOWER(*fmt) == 'z') {
1966 qualifier = *fmt++;
1967 if (unlikely(qualifier == *fmt)) {
1968 if (qualifier == 'h') {
1969 qualifier = 'H';
1970 fmt++;
1971 } else if (qualifier == 'l') {
1972 qualifier = 'L';
1973 fmt++;
1974 }
1975 }
1976 }
1977
1978 if (!*fmt || !*str)
1979 break;
1980
1981 base = 10;
1982 is_sign = 0;
1983
1984 switch (*fmt++) {
1985 case 'c':
1986 {
1987 char *s = (char *)va_arg(args, char*);
1988 if (field_width == -1)
1989 field_width = 1;
1990 do {
1991 *s++ = *str++;
1992 } while (--field_width > 0 && *str);
1993 num++;
1994 }
1995 continue;
1996 case 's':
1997 {
1998 char *s = (char *)va_arg(args, char *);
1999 if (field_width == -1)
2000 field_width = SHRT_MAX;
2001
2002 str = skip_spaces(str);
2003
2004
2005 while (*str && !isspace(*str) && field_width--)
2006 *s++ = *str++;
2007 *s = '\0';
2008 num++;
2009 }
2010 continue;
2011 case 'n':
2012
2013 {
2014 int *i = (int *)va_arg(args, int*);
2015 *i = str - buf;
2016 }
2017 continue;
2018 case 'o':
2019 base = 8;
2020 break;
2021 case 'x':
2022 case 'X':
2023 base = 16;
2024 break;
2025 case 'i':
2026 base = 0;
2027 case 'd':
2028 is_sign = 1;
2029 case 'u':
2030 break;
2031 case '%':
2032
2033 if (*str++ != '%')
2034 return num;
2035 continue;
2036 default:
2037
2038 return num;
2039 }
2040
2041
2042
2043
2044 str = skip_spaces(str);
2045
2046 digit = *str;
2047 if (is_sign && digit == '-')
2048 digit = *(str + 1);
2049
2050 if (!digit
2051 || (base == 16 && !isxdigit(digit))
2052 || (base == 10 && !isdigit(digit))
2053 || (base == 8 && (!isdigit(digit) || digit > '7'))
2054 || (base == 0 && !isdigit(digit)))
2055 break;
2056
2057 switch (qualifier) {
2058 case 'H':
2059 if (is_sign) {
2060 signed char *s = (signed char *)va_arg(args, signed char *);
2061 *s = (signed char)simple_strtol(str, &next, base);
2062 } else {
2063 unsigned char *s = (unsigned char *)va_arg(args, unsigned char *);
2064 *s = (unsigned char)simple_strtoul(str, &next, base);
2065 }
2066 break;
2067 case 'h':
2068 if (is_sign) {
2069 short *s = (short *)va_arg(args, short *);
2070 *s = (short)simple_strtol(str, &next, base);
2071 } else {
2072 unsigned short *s = (unsigned short *)va_arg(args, unsigned short *);
2073 *s = (unsigned short)simple_strtoul(str, &next, base);
2074 }
2075 break;
2076 case 'l':
2077 if (is_sign) {
2078 long *l = (long *)va_arg(args, long *);
2079 *l = simple_strtol(str, &next, base);
2080 } else {
2081 unsigned long *l = (unsigned long *)va_arg(args, unsigned long *);
2082 *l = simple_strtoul(str, &next, base);
2083 }
2084 break;
2085 case 'L':
2086 if (is_sign) {
2087 long long *l = (long long *)va_arg(args, long long *);
2088 *l = simple_strtoll(str, &next, base);
2089 } else {
2090 unsigned long long *l = (unsigned long long *)va_arg(args, unsigned long long *);
2091 *l = simple_strtoull(str, &next, base);
2092 }
2093 break;
2094 case 'Z':
2095 case 'z':
2096 {
2097 size_t *s = (size_t *)va_arg(args, size_t *);
2098 *s = (size_t)simple_strtoul(str, &next, base);
2099 }
2100 break;
2101 default:
2102 if (is_sign) {
2103 int *i = (int *)va_arg(args, int *);
2104 *i = (int)simple_strtol(str, &next, base);
2105 } else {
2106 unsigned int *i = (unsigned int *)va_arg(args, unsigned int*);
2107 *i = (unsigned int)simple_strtoul(str, &next, base);
2108 }
2109 break;
2110 }
2111 num++;
2112
2113 if (!next)
2114 break;
2115 str = next;
2116 }
2117
2118
2119
2120
2121
2122
2123 if (*fmt == '%' && *(fmt + 1) == 'n') {
2124 int *p = (int *)va_arg(args, int *);
2125 *p = str - buf;
2126 }
2127
2128 return num;
2129}
2130EXPORT_SYMBOL(vsscanf);
2131
2132
2133
2134
2135
2136
2137
2138int sscanf(const char *buf, const char *fmt, ...)
2139{
2140 va_list args;
2141 int i;
2142
2143 va_start(args, fmt);
2144 i = vsscanf(buf, fmt, args);
2145 va_end(args);
2146
2147 return i;
2148}
2149EXPORT_SYMBOL(sscanf);
2150