Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[wrt350n-kernel.git] / lib / vsprintf.c
blob51448df8efcc1ae4f911882df8abe464cfa7a664
1 /*
2 * linux/lib/vsprintf.c
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 */
7 /* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
8 /*
9 * Wirzenius wrote this portably, Torvalds fucked it up :-)
12 /*
13 * Fri Jul 13 2001 Crutcher Dunnavant <crutcher+kernel@datastacks.com>
14 * - changed to provide snprintf and vsnprintf functions
15 * So Feb 1 16:51:32 CET 2004 Juergen Quade <quade@hsnr.de>
16 * - scnprintf and vscnprintf
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>
26 #include <asm/page.h> /* for PAGE_SIZE */
27 #include <asm/div64.h>
29 /* Works only for digits and letters, but small and fast */
30 #define TOLOWER(x) ((x) | 0x20)
32 /**
33 * simple_strtoul - convert a string to an unsigned long
34 * @cp: The start of the string
35 * @endp: A pointer to the end of the parsed string will be placed here
36 * @base: The number base to use
38 unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
40 unsigned long result = 0,value;
42 if (!base) {
43 base = 10;
44 if (*cp == '0') {
45 base = 8;
46 cp++;
47 if ((TOLOWER(*cp) == 'x') && isxdigit(cp[1])) {
48 cp++;
49 base = 16;
52 } else if (base == 16) {
53 if (cp[0] == '0' && TOLOWER(cp[1]) == 'x')
54 cp += 2;
56 while (isxdigit(*cp) &&
57 (value = isdigit(*cp) ? *cp-'0' : TOLOWER(*cp)-'a'+10) < base) {
58 result = result*base + value;
59 cp++;
61 if (endp)
62 *endp = (char *)cp;
63 return result;
66 EXPORT_SYMBOL(simple_strtoul);
68 /**
69 * simple_strtol - convert a string to a signed long
70 * @cp: The start of the string
71 * @endp: A pointer to the end of the parsed string will be placed here
72 * @base: The number base to use
74 long simple_strtol(const char *cp,char **endp,unsigned int base)
76 if(*cp=='-')
77 return -simple_strtoul(cp+1,endp,base);
78 return simple_strtoul(cp,endp,base);
81 EXPORT_SYMBOL(simple_strtol);
83 /**
84 * simple_strtoull - convert a string to an unsigned long long
85 * @cp: The start of the string
86 * @endp: A pointer to the end of the parsed string will be placed here
87 * @base: The number base to use
89 unsigned long long simple_strtoull(const char *cp,char **endp,unsigned int base)
91 unsigned long long result = 0,value;
93 if (!base) {
94 base = 10;
95 if (*cp == '0') {
96 base = 8;
97 cp++;
98 if ((TOLOWER(*cp) == 'x') && isxdigit(cp[1])) {
99 cp++;
100 base = 16;
103 } else if (base == 16) {
104 if (cp[0] == '0' && TOLOWER(cp[1]) == 'x')
105 cp += 2;
107 while (isxdigit(*cp)
108 && (value = isdigit(*cp) ? *cp-'0' : TOLOWER(*cp)-'a'+10) < base) {
109 result = result*base + value;
110 cp++;
112 if (endp)
113 *endp = (char *)cp;
114 return result;
117 EXPORT_SYMBOL(simple_strtoull);
120 * simple_strtoll - convert a string to a signed long long
121 * @cp: The start of the string
122 * @endp: A pointer to the end of the parsed string will be placed here
123 * @base: The number base to use
125 long long simple_strtoll(const char *cp,char **endp,unsigned int base)
127 if(*cp=='-')
128 return -simple_strtoull(cp+1,endp,base);
129 return simple_strtoull(cp,endp,base);
134 * strict_strtoul - convert a string to an unsigned long strictly
135 * @cp: The string to be converted
136 * @base: The number base to use
137 * @res: The converted result value
139 * strict_strtoul converts a string to an unsigned long only if the
140 * string is really an unsigned long string, any string containing
141 * any invalid char at the tail will be rejected and -EINVAL is returned,
142 * only a newline char at the tail is acceptible because people generally
143 * change a module parameter in the following way:
145 * echo 1024 > /sys/module/e1000/parameters/copybreak
147 * echo will append a newline to the tail.
149 * It returns 0 if conversion is successful and *res is set to the converted
150 * value, otherwise it returns -EINVAL and *res is set to 0.
152 * simple_strtoul just ignores the successive invalid characters and
153 * return the converted value of prefix part of the string.
155 int strict_strtoul(const char *cp, unsigned int base, unsigned long *res);
158 * strict_strtol - convert a string to a long strictly
159 * @cp: The string to be converted
160 * @base: The number base to use
161 * @res: The converted result value
163 * strict_strtol is similiar to strict_strtoul, but it allows the first
164 * character of a string is '-'.
166 * It returns 0 if conversion is successful and *res is set to the converted
167 * value, otherwise it returns -EINVAL and *res is set to 0.
169 int strict_strtol(const char *cp, unsigned int base, long *res);
172 * strict_strtoull - convert a string to an unsigned long long strictly
173 * @cp: The string to be converted
174 * @base: The number base to use
175 * @res: The converted result value
177 * strict_strtoull converts a string to an unsigned long long only if the
178 * string is really an unsigned long long string, any string containing
179 * any invalid char at the tail will be rejected and -EINVAL is returned,
180 * only a newline char at the tail is acceptible because people generally
181 * change a module parameter in the following way:
183 * echo 1024 > /sys/module/e1000/parameters/copybreak
185 * echo will append a newline to the tail of the string.
187 * It returns 0 if conversion is successful and *res is set to the converted
188 * value, otherwise it returns -EINVAL and *res is set to 0.
190 * simple_strtoull just ignores the successive invalid characters and
191 * return the converted value of prefix part of the string.
193 int strict_strtoull(const char *cp, unsigned int base, unsigned long long *res);
196 * strict_strtoll - convert a string to a long long strictly
197 * @cp: The string to be converted
198 * @base: The number base to use
199 * @res: The converted result value
201 * strict_strtoll is similiar to strict_strtoull, but it allows the first
202 * character of a string is '-'.
204 * It returns 0 if conversion is successful and *res is set to the converted
205 * value, otherwise it returns -EINVAL and *res is set to 0.
207 int strict_strtoll(const char *cp, unsigned int base, long long *res);
209 #define define_strict_strtoux(type, valtype) \
210 int strict_strtou##type(const char *cp, unsigned int base, valtype *res)\
212 char *tail; \
213 valtype val; \
214 size_t len; \
216 *res = 0; \
217 len = strlen(cp); \
218 if (len == 0) \
219 return -EINVAL; \
221 val = simple_strtoul(cp, &tail, base); \
222 if ((*tail == '\0') || \
223 ((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) {\
224 *res = val; \
225 return 0; \
228 return -EINVAL; \
231 #define define_strict_strtox(type, valtype) \
232 int strict_strto##type(const char *cp, unsigned int base, valtype *res) \
234 int ret; \
235 if (*cp == '-') { \
236 ret = strict_strtou##type(cp+1, base, res); \
237 <<<<<<< HEAD:lib/vsprintf.c
238 if (ret != 0) \
239 =======
240 if (!ret) \
241 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:lib/vsprintf.c
242 *res = -(*res); \
243 } else \
244 ret = strict_strtou##type(cp, base, res); \
246 return ret; \
249 define_strict_strtoux(l, unsigned long)
250 define_strict_strtox(l, long)
251 define_strict_strtoux(ll, unsigned long long)
252 define_strict_strtox(ll, long long)
254 EXPORT_SYMBOL(strict_strtoul);
255 EXPORT_SYMBOL(strict_strtol);
256 EXPORT_SYMBOL(strict_strtoll);
257 EXPORT_SYMBOL(strict_strtoull);
259 static int skip_atoi(const char **s)
261 int i=0;
263 while (isdigit(**s))
264 i = i*10 + *((*s)++) - '0';
265 return i;
268 /* Decimal conversion is by far the most typical, and is used
269 * for /proc and /sys data. This directly impacts e.g. top performance
270 * with many processes running. We optimize it for speed
271 * using code from
272 * http://www.cs.uiowa.edu/~jones/bcd/decimal.html
273 * (with permission from the author, Douglas W. Jones). */
275 /* Formats correctly any integer in [0,99999].
276 * Outputs from one to five digits depending on input.
277 * On i386 gcc 4.1.2 -O2: ~250 bytes of code. */
278 static char* put_dec_trunc(char *buf, unsigned q)
280 unsigned d3, d2, d1, d0;
281 d1 = (q>>4) & 0xf;
282 d2 = (q>>8) & 0xf;
283 d3 = (q>>12);
285 d0 = 6*(d3 + d2 + d1) + (q & 0xf);
286 q = (d0 * 0xcd) >> 11;
287 d0 = d0 - 10*q;
288 *buf++ = d0 + '0'; /* least significant digit */
289 d1 = q + 9*d3 + 5*d2 + d1;
290 if (d1 != 0) {
291 q = (d1 * 0xcd) >> 11;
292 d1 = d1 - 10*q;
293 *buf++ = d1 + '0'; /* next digit */
295 d2 = q + 2*d2;
296 if ((d2 != 0) || (d3 != 0)) {
297 q = (d2 * 0xd) >> 7;
298 d2 = d2 - 10*q;
299 *buf++ = d2 + '0'; /* next digit */
301 d3 = q + 4*d3;
302 if (d3 != 0) {
303 q = (d3 * 0xcd) >> 11;
304 d3 = d3 - 10*q;
305 *buf++ = d3 + '0'; /* next digit */
306 if (q != 0)
307 *buf++ = q + '0'; /* most sign. digit */
311 return buf;
313 /* Same with if's removed. Always emits five digits */
314 static char* put_dec_full(char *buf, unsigned q)
316 /* BTW, if q is in [0,9999], 8-bit ints will be enough, */
317 /* but anyway, gcc produces better code with full-sized ints */
318 unsigned d3, d2, d1, d0;
319 d1 = (q>>4) & 0xf;
320 d2 = (q>>8) & 0xf;
321 d3 = (q>>12);
323 /* Possible ways to approx. divide by 10 */
324 /* gcc -O2 replaces multiply with shifts and adds */
325 // (x * 0xcd) >> 11: 11001101 - shorter code than * 0x67 (on i386)
326 // (x * 0x67) >> 10: 1100111
327 // (x * 0x34) >> 9: 110100 - same
328 // (x * 0x1a) >> 8: 11010 - same
329 // (x * 0x0d) >> 7: 1101 - same, shortest code (on i386)
331 d0 = 6*(d3 + d2 + d1) + (q & 0xf);
332 q = (d0 * 0xcd) >> 11;
333 d0 = d0 - 10*q;
334 *buf++ = d0 + '0';
335 d1 = q + 9*d3 + 5*d2 + d1;
336 q = (d1 * 0xcd) >> 11;
337 d1 = d1 - 10*q;
338 *buf++ = d1 + '0';
340 d2 = q + 2*d2;
341 q = (d2 * 0xd) >> 7;
342 d2 = d2 - 10*q;
343 *buf++ = d2 + '0';
345 d3 = q + 4*d3;
346 q = (d3 * 0xcd) >> 11; /* - shorter code */
347 /* q = (d3 * 0x67) >> 10; - would also work */
348 d3 = d3 - 10*q;
349 *buf++ = d3 + '0';
350 *buf++ = q + '0';
351 return buf;
353 /* No inlining helps gcc to use registers better */
354 static noinline char* put_dec(char *buf, unsigned long long num)
356 while (1) {
357 unsigned rem;
358 if (num < 100000)
359 return put_dec_trunc(buf, num);
360 rem = do_div(num, 100000);
361 buf = put_dec_full(buf, rem);
365 #define ZEROPAD 1 /* pad with zero */
366 #define SIGN 2 /* unsigned/signed long */
367 #define PLUS 4 /* show plus */
368 #define SPACE 8 /* space if plus */
369 #define LEFT 16 /* left justified */
370 #define SMALL 32 /* Must be 32 == 0x20 */
371 #define SPECIAL 64 /* 0x */
373 static char *number(char *buf, char *end, unsigned long long num, int base, int size, int precision, int type)
375 /* we are called with base 8, 10 or 16, only, thus don't need "G..." */
376 static const char digits[16] = "0123456789ABCDEF"; /* "GHIJKLMNOPQRSTUVWXYZ"; */
378 char tmp[66];
379 char sign;
380 char locase;
381 int need_pfx = ((type & SPECIAL) && base != 10);
382 int i;
384 /* locase = 0 or 0x20. ORing digits or letters with 'locase'
385 * produces same digits or (maybe lowercased) letters */
386 locase = (type & SMALL);
387 if (type & LEFT)
388 type &= ~ZEROPAD;
389 sign = 0;
390 if (type & SIGN) {
391 if ((signed long long) num < 0) {
392 sign = '-';
393 num = - (signed long long) num;
394 size--;
395 } else if (type & PLUS) {
396 sign = '+';
397 size--;
398 } else if (type & SPACE) {
399 sign = ' ';
400 size--;
403 if (need_pfx) {
404 size--;
405 if (base == 16)
406 size--;
409 /* generate full string in tmp[], in reverse order */
410 i = 0;
411 if (num == 0)
412 tmp[i++] = '0';
413 /* Generic code, for any base:
414 else do {
415 tmp[i++] = (digits[do_div(num,base)] | locase);
416 } while (num != 0);
418 else if (base != 10) { /* 8 or 16 */
419 int mask = base - 1;
420 int shift = 3;
421 if (base == 16) shift = 4;
422 do {
423 tmp[i++] = (digits[((unsigned char)num) & mask] | locase);
424 num >>= shift;
425 } while (num);
426 } else { /* base 10 */
427 i = put_dec(tmp, num) - tmp;
430 /* printing 100 using %2d gives "100", not "00" */
431 if (i > precision)
432 precision = i;
433 /* leading space padding */
434 size -= precision;
435 if (!(type & (ZEROPAD+LEFT))) {
436 while(--size >= 0) {
437 if (buf < end)
438 *buf = ' ';
439 ++buf;
442 /* sign */
443 if (sign) {
444 if (buf < end)
445 *buf = sign;
446 ++buf;
448 /* "0x" / "0" prefix */
449 if (need_pfx) {
450 if (buf < end)
451 *buf = '0';
452 ++buf;
453 if (base == 16) {
454 if (buf < end)
455 *buf = ('X' | locase);
456 ++buf;
459 /* zero or space padding */
460 if (!(type & LEFT)) {
461 char c = (type & ZEROPAD) ? '0' : ' ';
462 while (--size >= 0) {
463 if (buf < end)
464 *buf = c;
465 ++buf;
468 /* hmm even more zero padding? */
469 while (i <= --precision) {
470 if (buf < end)
471 *buf = '0';
472 ++buf;
474 /* actual digits of result */
475 while (--i >= 0) {
476 if (buf < end)
477 *buf = tmp[i];
478 ++buf;
480 /* trailing space padding */
481 while (--size >= 0) {
482 if (buf < end)
483 *buf = ' ';
484 ++buf;
486 return buf;
490 * vsnprintf - Format a string and place it in a buffer
491 * @buf: The buffer to place the result into
492 * @size: The size of the buffer, including the trailing null space
493 * @fmt: The format string to use
494 * @args: Arguments for the format string
496 * The return value is the number of characters which would
497 * be generated for the given input, excluding the trailing
498 * '\0', as per ISO C99. If you want to have the exact
499 * number of characters written into @buf as return value
500 * (not including the trailing '\0'), use vscnprintf(). If the
501 * return is greater than or equal to @size, the resulting
502 * string is truncated.
504 * Call this function if you are already dealing with a va_list.
505 * You probably want snprintf() instead.
507 int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
509 int len;
510 unsigned long long num;
511 int i, base;
512 char *str, *end, c;
513 const char *s;
515 int flags; /* flags to number() */
517 int field_width; /* width of output field */
518 int precision; /* min. # of digits for integers; max
519 number of chars for from string */
520 int qualifier; /* 'h', 'l', or 'L' for integer fields */
521 /* 'z' support added 23/7/1999 S.H. */
522 /* 'z' changed to 'Z' --davidm 1/25/99 */
523 /* 't' added for ptrdiff_t */
525 /* Reject out-of-range values early. Large positive sizes are
526 used for unknown buffer sizes. */
527 if (unlikely((int) size < 0)) {
528 /* There can be only one.. */
529 static char warn = 1;
530 WARN_ON(warn);
531 warn = 0;
532 return 0;
535 str = buf;
536 end = buf + size;
538 /* Make sure end is always >= buf */
539 if (end < buf) {
540 end = ((void *)-1);
541 size = end - buf;
544 for (; *fmt ; ++fmt) {
545 if (*fmt != '%') {
546 if (str < end)
547 *str = *fmt;
548 ++str;
549 continue;
552 /* process flags */
553 flags = 0;
554 repeat:
555 ++fmt; /* this also skips first '%' */
556 switch (*fmt) {
557 case '-': flags |= LEFT; goto repeat;
558 case '+': flags |= PLUS; goto repeat;
559 case ' ': flags |= SPACE; goto repeat;
560 case '#': flags |= SPECIAL; goto repeat;
561 case '0': flags |= ZEROPAD; goto repeat;
564 /* get field width */
565 field_width = -1;
566 if (isdigit(*fmt))
567 field_width = skip_atoi(&fmt);
568 else if (*fmt == '*') {
569 ++fmt;
570 /* it's the next argument */
571 field_width = va_arg(args, int);
572 if (field_width < 0) {
573 field_width = -field_width;
574 flags |= LEFT;
578 /* get the precision */
579 precision = -1;
580 if (*fmt == '.') {
581 ++fmt;
582 if (isdigit(*fmt))
583 precision = skip_atoi(&fmt);
584 else if (*fmt == '*') {
585 ++fmt;
586 /* it's the next argument */
587 precision = va_arg(args, int);
589 if (precision < 0)
590 precision = 0;
593 /* get the conversion qualifier */
594 qualifier = -1;
595 if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
596 *fmt =='Z' || *fmt == 'z' || *fmt == 't') {
597 qualifier = *fmt;
598 ++fmt;
599 if (qualifier == 'l' && *fmt == 'l') {
600 qualifier = 'L';
601 ++fmt;
605 /* default base */
606 base = 10;
608 switch (*fmt) {
609 case 'c':
610 if (!(flags & LEFT)) {
611 while (--field_width > 0) {
612 if (str < end)
613 *str = ' ';
614 ++str;
617 c = (unsigned char) va_arg(args, int);
618 if (str < end)
619 *str = c;
620 ++str;
621 while (--field_width > 0) {
622 if (str < end)
623 *str = ' ';
624 ++str;
626 continue;
628 case 's':
629 s = va_arg(args, char *);
630 if ((unsigned long)s < PAGE_SIZE)
631 s = "<NULL>";
633 len = strnlen(s, precision);
635 if (!(flags & LEFT)) {
636 while (len < field_width--) {
637 if (str < end)
638 *str = ' ';
639 ++str;
642 for (i = 0; i < len; ++i) {
643 if (str < end)
644 *str = *s;
645 ++str; ++s;
647 while (len < field_width--) {
648 if (str < end)
649 *str = ' ';
650 ++str;
652 continue;
654 case 'p':
655 flags |= SMALL;
656 if (field_width == -1) {
657 field_width = 2*sizeof(void *);
658 flags |= ZEROPAD;
660 str = number(str, end,
661 (unsigned long) va_arg(args, void *),
662 16, field_width, precision, flags);
663 continue;
666 case 'n':
667 /* FIXME:
668 * What does C99 say about the overflow case here? */
669 if (qualifier == 'l') {
670 long * ip = va_arg(args, long *);
671 *ip = (str - buf);
672 } else if (qualifier == 'Z' || qualifier == 'z') {
673 size_t * ip = va_arg(args, size_t *);
674 *ip = (str - buf);
675 } else {
676 int * ip = va_arg(args, int *);
677 *ip = (str - buf);
679 continue;
681 case '%':
682 if (str < end)
683 *str = '%';
684 ++str;
685 continue;
687 /* integer number formats - set up the flags and "break" */
688 case 'o':
689 base = 8;
690 break;
692 case 'x':
693 flags |= SMALL;
694 case 'X':
695 base = 16;
696 break;
698 case 'd':
699 case 'i':
700 flags |= SIGN;
701 case 'u':
702 break;
704 default:
705 if (str < end)
706 *str = '%';
707 ++str;
708 if (*fmt) {
709 if (str < end)
710 *str = *fmt;
711 ++str;
712 } else {
713 --fmt;
715 continue;
717 if (qualifier == 'L')
718 num = va_arg(args, long long);
719 else if (qualifier == 'l') {
720 num = va_arg(args, unsigned long);
721 if (flags & SIGN)
722 num = (signed long) num;
723 } else if (qualifier == 'Z' || qualifier == 'z') {
724 num = va_arg(args, size_t);
725 } else if (qualifier == 't') {
726 num = va_arg(args, ptrdiff_t);
727 } else if (qualifier == 'h') {
728 num = (unsigned short) va_arg(args, int);
729 if (flags & SIGN)
730 num = (signed short) num;
731 } else {
732 num = va_arg(args, unsigned int);
733 if (flags & SIGN)
734 num = (signed int) num;
736 str = number(str, end, num, base,
737 field_width, precision, flags);
739 if (size > 0) {
740 if (str < end)
741 *str = '\0';
742 else
743 end[-1] = '\0';
745 /* the trailing null byte doesn't count towards the total */
746 return str-buf;
749 EXPORT_SYMBOL(vsnprintf);
752 * vscnprintf - Format a string and place it in a buffer
753 * @buf: The buffer to place the result into
754 * @size: The size of the buffer, including the trailing null space
755 * @fmt: The format string to use
756 * @args: Arguments for the format string
758 * The return value is the number of characters which have been written into
759 * the @buf not including the trailing '\0'. If @size is <= 0 the function
760 * returns 0.
762 * Call this function if you are already dealing with a va_list.
763 * You probably want scnprintf() instead.
765 int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
767 int i;
769 i=vsnprintf(buf,size,fmt,args);
770 return (i >= size) ? (size - 1) : i;
773 EXPORT_SYMBOL(vscnprintf);
776 * snprintf - Format a string and place it in a buffer
777 * @buf: The buffer to place the result into
778 * @size: The size of the buffer, including the trailing null space
779 * @fmt: The format string to use
780 * @...: Arguments for the format string
782 * The return value is the number of characters which would be
783 * generated for the given input, excluding the trailing null,
784 * as per ISO C99. If the return is greater than or equal to
785 * @size, the resulting string is truncated.
787 int snprintf(char * buf, size_t size, const char *fmt, ...)
789 va_list args;
790 int i;
792 va_start(args, fmt);
793 i=vsnprintf(buf,size,fmt,args);
794 va_end(args);
795 return i;
798 EXPORT_SYMBOL(snprintf);
801 * scnprintf - Format a string and place it in a buffer
802 * @buf: The buffer to place the result into
803 * @size: The size of the buffer, including the trailing null space
804 * @fmt: The format string to use
805 * @...: Arguments for the format string
807 * The return value is the number of characters written into @buf not including
808 * the trailing '\0'. If @size is <= 0 the function returns 0.
811 int scnprintf(char * buf, size_t size, const char *fmt, ...)
813 va_list args;
814 int i;
816 va_start(args, fmt);
817 i = vsnprintf(buf, size, fmt, args);
818 va_end(args);
819 return (i >= size) ? (size - 1) : i;
821 EXPORT_SYMBOL(scnprintf);
824 * vsprintf - Format a string and place it in a buffer
825 * @buf: The buffer to place the result into
826 * @fmt: The format string to use
827 * @args: Arguments for the format string
829 * The function returns the number of characters written
830 * into @buf. Use vsnprintf() or vscnprintf() in order to avoid
831 * buffer overflows.
833 * Call this function if you are already dealing with a va_list.
834 * You probably want sprintf() instead.
836 int vsprintf(char *buf, const char *fmt, va_list args)
838 return vsnprintf(buf, INT_MAX, fmt, args);
841 EXPORT_SYMBOL(vsprintf);
844 * sprintf - Format a string and place it in a buffer
845 * @buf: The buffer to place the result into
846 * @fmt: The format string to use
847 * @...: Arguments for the format string
849 * The function returns the number of characters written
850 * into @buf. Use snprintf() or scnprintf() in order to avoid
851 * buffer overflows.
853 int sprintf(char * buf, const char *fmt, ...)
855 va_list args;
856 int i;
858 va_start(args, fmt);
859 i=vsnprintf(buf, INT_MAX, fmt, args);
860 va_end(args);
861 return i;
864 EXPORT_SYMBOL(sprintf);
867 * vsscanf - Unformat a buffer into a list of arguments
868 * @buf: input buffer
869 * @fmt: format of buffer
870 * @args: arguments
872 int vsscanf(const char * buf, const char * fmt, va_list args)
874 const char *str = buf;
875 char *next;
876 char digit;
877 int num = 0;
878 int qualifier;
879 int base;
880 int field_width;
881 int is_sign = 0;
883 while(*fmt && *str) {
884 /* skip any white space in format */
885 /* white space in format matchs any amount of
886 * white space, including none, in the input.
888 if (isspace(*fmt)) {
889 while (isspace(*fmt))
890 ++fmt;
891 while (isspace(*str))
892 ++str;
895 /* anything that is not a conversion must match exactly */
896 if (*fmt != '%' && *fmt) {
897 if (*fmt++ != *str++)
898 break;
899 continue;
902 if (!*fmt)
903 break;
904 ++fmt;
906 /* skip this conversion.
907 * advance both strings to next white space
909 if (*fmt == '*') {
910 while (!isspace(*fmt) && *fmt)
911 fmt++;
912 while (!isspace(*str) && *str)
913 str++;
914 continue;
917 /* get field width */
918 field_width = -1;
919 if (isdigit(*fmt))
920 field_width = skip_atoi(&fmt);
922 /* get conversion qualifier */
923 qualifier = -1;
924 if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
925 *fmt == 'Z' || *fmt == 'z') {
926 qualifier = *fmt++;
927 if (unlikely(qualifier == *fmt)) {
928 if (qualifier == 'h') {
929 qualifier = 'H';
930 fmt++;
931 } else if (qualifier == 'l') {
932 qualifier = 'L';
933 fmt++;
937 base = 10;
938 is_sign = 0;
940 if (!*fmt || !*str)
941 break;
943 switch(*fmt++) {
944 case 'c':
946 char *s = (char *) va_arg(args,char*);
947 if (field_width == -1)
948 field_width = 1;
949 do {
950 *s++ = *str++;
951 } while (--field_width > 0 && *str);
952 num++;
954 continue;
955 case 's':
957 char *s = (char *) va_arg(args, char *);
958 if(field_width == -1)
959 field_width = INT_MAX;
960 /* first, skip leading white space in buffer */
961 while (isspace(*str))
962 str++;
964 /* now copy until next white space */
965 while (*str && !isspace(*str) && field_width--) {
966 *s++ = *str++;
968 *s = '\0';
969 num++;
971 continue;
972 case 'n':
973 /* return number of characters read so far */
975 int *i = (int *)va_arg(args,int*);
976 *i = str - buf;
978 continue;
979 case 'o':
980 base = 8;
981 break;
982 case 'x':
983 case 'X':
984 base = 16;
985 break;
986 case 'i':
987 base = 0;
988 case 'd':
989 is_sign = 1;
990 case 'u':
991 break;
992 case '%':
993 /* looking for '%' in str */
994 if (*str++ != '%')
995 return num;
996 continue;
997 default:
998 /* invalid format; stop here */
999 return num;
1002 /* have some sort of integer conversion.
1003 * first, skip white space in buffer.
1005 while (isspace(*str))
1006 str++;
1008 digit = *str;
1009 if (is_sign && digit == '-')
1010 digit = *(str + 1);
1012 if (!digit
1013 || (base == 16 && !isxdigit(digit))
1014 || (base == 10 && !isdigit(digit))
1015 || (base == 8 && (!isdigit(digit) || digit > '7'))
1016 || (base == 0 && !isdigit(digit)))
1017 break;
1019 switch(qualifier) {
1020 case 'H': /* that's 'hh' in format */
1021 if (is_sign) {
1022 signed char *s = (signed char *) va_arg(args,signed char *);
1023 *s = (signed char) simple_strtol(str,&next,base);
1024 } else {
1025 unsigned char *s = (unsigned char *) va_arg(args, unsigned char *);
1026 *s = (unsigned char) simple_strtoul(str, &next, base);
1028 break;
1029 case 'h':
1030 if (is_sign) {
1031 short *s = (short *) va_arg(args,short *);
1032 *s = (short) simple_strtol(str,&next,base);
1033 } else {
1034 unsigned short *s = (unsigned short *) va_arg(args, unsigned short *);
1035 *s = (unsigned short) simple_strtoul(str, &next, base);
1037 break;
1038 case 'l':
1039 if (is_sign) {
1040 long *l = (long *) va_arg(args,long *);
1041 *l = simple_strtol(str,&next,base);
1042 } else {
1043 unsigned long *l = (unsigned long*) va_arg(args,unsigned long*);
1044 *l = simple_strtoul(str,&next,base);
1046 break;
1047 case 'L':
1048 if (is_sign) {
1049 long long *l = (long long*) va_arg(args,long long *);
1050 *l = simple_strtoll(str,&next,base);
1051 } else {
1052 unsigned long long *l = (unsigned long long*) va_arg(args,unsigned long long*);
1053 *l = simple_strtoull(str,&next,base);
1055 break;
1056 case 'Z':
1057 case 'z':
1059 size_t *s = (size_t*) va_arg(args,size_t*);
1060 *s = (size_t) simple_strtoul(str,&next,base);
1062 break;
1063 default:
1064 if (is_sign) {
1065 int *i = (int *) va_arg(args, int*);
1066 *i = (int) simple_strtol(str,&next,base);
1067 } else {
1068 unsigned int *i = (unsigned int*) va_arg(args, unsigned int*);
1069 *i = (unsigned int) simple_strtoul(str,&next,base);
1071 break;
1073 num++;
1075 if (!next)
1076 break;
1077 str = next;
1081 * Now we've come all the way through so either the input string or the
1082 * format ended. In the former case, there can be a %n at the current
1083 * position in the format that needs to be filled.
1085 if (*fmt == '%' && *(fmt + 1) == 'n') {
1086 int *p = (int *)va_arg(args, int *);
1087 *p = str - buf;
1090 return num;
1093 EXPORT_SYMBOL(vsscanf);
1096 * sscanf - Unformat a buffer into a list of arguments
1097 * @buf: input buffer
1098 * @fmt: formatting of buffer
1099 * @...: resulting arguments
1101 int sscanf(const char * buf, const char * fmt, ...)
1103 va_list args;
1104 int i;
1106 va_start(args,fmt);
1107 i = vsscanf(buf,fmt,args);
1108 va_end(args);
1109 return i;
1112 EXPORT_SYMBOL(sscanf);