fbdev: width and height are unsigned
[linux-2.6] / lib / vsprintf.c
1 /*
2  *  linux/lib/vsprintf.c
3  *
4  *  Copyright (C) 1991, 1992  Linus Torvalds
5  */
6
7 /* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
8 /*
9  * Wirzenius wrote this portably, Torvalds fucked it up :-)
10  */
11
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
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
28 #include <asm/page.h>           /* for PAGE_SIZE */
29 #include <asm/div64.h>
30
31 /* Works only for digits and letters, but small and fast */
32 #define TOLOWER(x) ((x) | 0x20)
33
34 /**
35  * simple_strtoul - convert a string to an unsigned long
36  * @cp: The start of the string
37  * @endp: A pointer to the end of the parsed string will be placed here
38  * @base: The number base to use
39  */
40 unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
41 {
42         unsigned long result = 0,value;
43
44         if (!base) {
45                 base = 10;
46                 if (*cp == '0') {
47                         base = 8;
48                         cp++;
49                         if ((TOLOWER(*cp) == 'x') && isxdigit(cp[1])) {
50                                 cp++;
51                                 base = 16;
52                         }
53                 }
54         } else if (base == 16) {
55                 if (cp[0] == '0' && TOLOWER(cp[1]) == 'x')
56                         cp += 2;
57         }
58         while (isxdigit(*cp) &&
59                (value = isdigit(*cp) ? *cp-'0' : TOLOWER(*cp)-'a'+10) < base) {
60                 result = result*base + value;
61                 cp++;
62         }
63         if (endp)
64                 *endp = (char *)cp;
65         return result;
66 }
67
68 EXPORT_SYMBOL(simple_strtoul);
69
70 /**
71  * simple_strtol - convert a string to a signed long
72  * @cp: The start of the string
73  * @endp: A pointer to the end of the parsed string will be placed here
74  * @base: The number base to use
75  */
76 long simple_strtol(const char *cp,char **endp,unsigned int base)
77 {
78         if(*cp=='-')
79                 return -simple_strtoul(cp+1,endp,base);
80         return simple_strtoul(cp,endp,base);
81 }
82
83 EXPORT_SYMBOL(simple_strtol);
84
85 /**
86  * simple_strtoull - convert a string to an unsigned long long
87  * @cp: The start of the string
88  * @endp: A pointer to the end of the parsed string will be placed here
89  * @base: The number base to use
90  */
91 unsigned long long simple_strtoull(const char *cp,char **endp,unsigned int base)
92 {
93         unsigned long long result = 0,value;
94
95         if (!base) {
96                 base = 10;
97                 if (*cp == '0') {
98                         base = 8;
99                         cp++;
100                         if ((TOLOWER(*cp) == 'x') && isxdigit(cp[1])) {
101                                 cp++;
102                                 base = 16;
103                         }
104                 }
105         } else if (base == 16) {
106                 if (cp[0] == '0' && TOLOWER(cp[1]) == 'x')
107                         cp += 2;
108         }
109         while (isxdigit(*cp)
110          && (value = isdigit(*cp) ? *cp-'0' : TOLOWER(*cp)-'a'+10) < base) {
111                 result = result*base + value;
112                 cp++;
113         }
114         if (endp)
115                 *endp = (char *)cp;
116         return result;
117 }
118
119 EXPORT_SYMBOL(simple_strtoull);
120
121 /**
122  * simple_strtoll - convert a string to a signed long long
123  * @cp: The start of the string
124  * @endp: A pointer to the end of the parsed string will be placed here
125  * @base: The number base to use
126  */
127 long long simple_strtoll(const char *cp,char **endp,unsigned int base)
128 {
129         if(*cp=='-')
130                 return -simple_strtoull(cp+1,endp,base);
131         return simple_strtoull(cp,endp,base);
132 }
133
134
135 /**
136  * strict_strtoul - convert a string to an unsigned long strictly
137  * @cp: The string to be converted
138  * @base: The number base to use
139  * @res: The converted result value
140  *
141  * strict_strtoul converts a string to an unsigned long only if the
142  * string is really an unsigned long string, any string containing
143  * any invalid char at the tail will be rejected and -EINVAL is returned,
144  * only a newline char at the tail is acceptible because people generally
145  * change a module parameter in the following way:
146  *
147  *      echo 1024 > /sys/module/e1000/parameters/copybreak
148  *
149  * echo will append a newline to the tail.
150  *
151  * It returns 0 if conversion is successful and *res is set to the converted
152  * value, otherwise it returns -EINVAL and *res is set to 0.
153  *
154  * simple_strtoul just ignores the successive invalid characters and
155  * return the converted value of prefix part of the string.
156  */
157 int strict_strtoul(const char *cp, unsigned int base, unsigned long *res);
158
159 /**
160  * strict_strtol - convert a string to a long strictly
161  * @cp: The string to be converted
162  * @base: The number base to use
163  * @res: The converted result value
164  *
165  * strict_strtol is similiar to strict_strtoul, but it allows the first
166  * character of a string is '-'.
167  *
168  * It returns 0 if conversion is successful and *res is set to the converted
169  * value, otherwise it returns -EINVAL and *res is set to 0.
170  */
171 int strict_strtol(const char *cp, unsigned int base, long *res);
172
173 /**
174  * strict_strtoull - convert a string to an unsigned long long strictly
175  * @cp: The string to be converted
176  * @base: The number base to use
177  * @res: The converted result value
178  *
179  * strict_strtoull converts a string to an unsigned long long only if the
180  * string is really an unsigned long long string, any string containing
181  * any invalid char at the tail will be rejected and -EINVAL is returned,
182  * only a newline char at the tail is acceptible because people generally
183  * change a module parameter in the following way:
184  *
185  *      echo 1024 > /sys/module/e1000/parameters/copybreak
186  *
187  * echo will append a newline to the tail of the string.
188  *
189  * It returns 0 if conversion is successful and *res is set to the converted
190  * value, otherwise it returns -EINVAL and *res is set to 0.
191  *
192  * simple_strtoull just ignores the successive invalid characters and
193  * return the converted value of prefix part of the string.
194  */
195 int strict_strtoull(const char *cp, unsigned int base, unsigned long long *res);
196
197 /**
198  * strict_strtoll - convert a string to a long long strictly
199  * @cp: The string to be converted
200  * @base: The number base to use
201  * @res: The converted result value
202  *
203  * strict_strtoll is similiar to strict_strtoull, but it allows the first
204  * character of a string is '-'.
205  *
206  * It returns 0 if conversion is successful and *res is set to the converted
207  * value, otherwise it returns -EINVAL and *res is set to 0.
208  */
209 int strict_strtoll(const char *cp, unsigned int base, long long *res);
210
211 #define define_strict_strtoux(type, valtype)                            \
212 int strict_strtou##type(const char *cp, unsigned int base, valtype *res)\
213 {                                                                       \
214         char *tail;                                                     \
215         valtype val;                                                    \
216         size_t len;                                                     \
217                                                                         \
218         *res = 0;                                                       \
219         len = strlen(cp);                                               \
220         if (len == 0)                                                   \
221                 return -EINVAL;                                         \
222                                                                         \
223         val = simple_strtoul(cp, &tail, base);                          \
224         if ((*tail == '\0') ||                                          \
225                 ((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) {\
226                 *res = val;                                             \
227                 return 0;                                               \
228         }                                                               \
229                                                                         \
230         return -EINVAL;                                                 \
231 }                                                                       \
232
233 #define define_strict_strtox(type, valtype)                             \
234 int strict_strto##type(const char *cp, unsigned int base, valtype *res) \
235 {                                                                       \
236         int ret;                                                        \
237         if (*cp == '-') {                                               \
238                 ret = strict_strtou##type(cp+1, base, res);             \
239                 if (!ret)                                               \
240                         *res = -(*res);                                 \
241         } else                                                          \
242                 ret = strict_strtou##type(cp, base, res);               \
243                                                                         \
244         return ret;                                                     \
245 }                                                                       \
246
247 define_strict_strtoux(l, unsigned long)
248 define_strict_strtox(l, long)
249 define_strict_strtoux(ll, unsigned long long)
250 define_strict_strtox(ll, long long)
251
252 EXPORT_SYMBOL(strict_strtoul);
253 EXPORT_SYMBOL(strict_strtol);
254 EXPORT_SYMBOL(strict_strtoll);
255 EXPORT_SYMBOL(strict_strtoull);
256
257 static int skip_atoi(const char **s)
258 {
259         int i=0;
260
261         while (isdigit(**s))
262                 i = i*10 + *((*s)++) - '0';
263         return i;
264 }
265
266 /* Decimal conversion is by far the most typical, and is used
267  * for /proc and /sys data. This directly impacts e.g. top performance
268  * with many processes running. We optimize it for speed
269  * using code from
270  * http://www.cs.uiowa.edu/~jones/bcd/decimal.html
271  * (with permission from the author, Douglas W. Jones). */
272
273 /* Formats correctly any integer in [0,99999].
274  * Outputs from one to five digits depending on input.
275  * On i386 gcc 4.1.2 -O2: ~250 bytes of code. */
276 static char* put_dec_trunc(char *buf, unsigned q)
277 {
278         unsigned d3, d2, d1, d0;
279         d1 = (q>>4) & 0xf;
280         d2 = (q>>8) & 0xf;
281         d3 = (q>>12);
282
283         d0 = 6*(d3 + d2 + d1) + (q & 0xf);
284         q = (d0 * 0xcd) >> 11;
285         d0 = d0 - 10*q;
286         *buf++ = d0 + '0'; /* least significant digit */
287         d1 = q + 9*d3 + 5*d2 + d1;
288         if (d1 != 0) {
289                 q = (d1 * 0xcd) >> 11;
290                 d1 = d1 - 10*q;
291                 *buf++ = d1 + '0'; /* next digit */
292
293                 d2 = q + 2*d2;
294                 if ((d2 != 0) || (d3 != 0)) {
295                         q = (d2 * 0xd) >> 7;
296                         d2 = d2 - 10*q;
297                         *buf++ = d2 + '0'; /* next digit */
298
299                         d3 = q + 4*d3;
300                         if (d3 != 0) {
301                                 q = (d3 * 0xcd) >> 11;
302                                 d3 = d3 - 10*q;
303                                 *buf++ = d3 + '0';  /* next digit */
304                                 if (q != 0)
305                                         *buf++ = q + '0';  /* most sign. digit */
306                         }
307                 }
308         }
309         return buf;
310 }
311 /* Same with if's removed. Always emits five digits */
312 static char* put_dec_full(char *buf, unsigned q)
313 {
314         /* BTW, if q is in [0,9999], 8-bit ints will be enough, */
315         /* but anyway, gcc produces better code with full-sized ints */
316         unsigned d3, d2, d1, d0;
317         d1 = (q>>4) & 0xf;
318         d2 = (q>>8) & 0xf;
319         d3 = (q>>12);
320
321         /* Possible ways to approx. divide by 10 */
322         /* gcc -O2 replaces multiply with shifts and adds */
323         // (x * 0xcd) >> 11: 11001101 - shorter code than * 0x67 (on i386)
324         // (x * 0x67) >> 10:  1100111
325         // (x * 0x34) >> 9:    110100 - same
326         // (x * 0x1a) >> 8:     11010 - same
327         // (x * 0x0d) >> 7:      1101 - same, shortest code (on i386)
328
329         d0 = 6*(d3 + d2 + d1) + (q & 0xf);
330         q = (d0 * 0xcd) >> 11;
331         d0 = d0 - 10*q;
332         *buf++ = d0 + '0';
333         d1 = q + 9*d3 + 5*d2 + d1;
334                 q = (d1 * 0xcd) >> 11;
335                 d1 = d1 - 10*q;
336                 *buf++ = d1 + '0';
337
338                 d2 = q + 2*d2;
339                         q = (d2 * 0xd) >> 7;
340                         d2 = d2 - 10*q;
341                         *buf++ = d2 + '0';
342
343                         d3 = q + 4*d3;
344                                 q = (d3 * 0xcd) >> 11; /* - shorter code */
345                                 /* q = (d3 * 0x67) >> 10; - would also work */
346                                 d3 = d3 - 10*q;
347                                 *buf++ = d3 + '0';
348                                         *buf++ = q + '0';
349         return buf;
350 }
351 /* No inlining helps gcc to use registers better */
352 static noinline char* put_dec(char *buf, unsigned long long num)
353 {
354         while (1) {
355                 unsigned rem;
356                 if (num < 100000)
357                         return put_dec_trunc(buf, num);
358                 rem = do_div(num, 100000);
359                 buf = put_dec_full(buf, rem);
360         }
361 }
362
363 #define ZEROPAD 1               /* pad with zero */
364 #define SIGN    2               /* unsigned/signed long */
365 #define PLUS    4               /* show plus */
366 #define SPACE   8               /* space if plus */
367 #define LEFT    16              /* left justified */
368 #define SMALL   32              /* Must be 32 == 0x20 */
369 #define SPECIAL 64              /* 0x */
370
371 static char *number(char *buf, char *end, unsigned long long num, int base, int size, int precision, int type)
372 {
373         /* we are called with base 8, 10 or 16, only, thus don't need "G..."  */
374         static const char digits[16] = "0123456789ABCDEF"; /* "GHIJKLMNOPQRSTUVWXYZ"; */
375
376         char tmp[66];
377         char sign;
378         char locase;
379         int need_pfx = ((type & SPECIAL) && base != 10);
380         int i;
381
382         /* locase = 0 or 0x20. ORing digits or letters with 'locase'
383          * produces same digits or (maybe lowercased) letters */
384         locase = (type & SMALL);
385         if (type & LEFT)
386                 type &= ~ZEROPAD;
387         sign = 0;
388         if (type & SIGN) {
389                 if ((signed long long) num < 0) {
390                         sign = '-';
391                         num = - (signed long long) num;
392                         size--;
393                 } else if (type & PLUS) {
394                         sign = '+';
395                         size--;
396                 } else if (type & SPACE) {
397                         sign = ' ';
398                         size--;
399                 }
400         }
401         if (need_pfx) {
402                 size--;
403                 if (base == 16)
404                         size--;
405         }
406
407         /* generate full string in tmp[], in reverse order */
408         i = 0;
409         if (num == 0)
410                 tmp[i++] = '0';
411         /* Generic code, for any base:
412         else do {
413                 tmp[i++] = (digits[do_div(num,base)] | locase);
414         } while (num != 0);
415         */
416         else if (base != 10) { /* 8 or 16 */
417                 int mask = base - 1;
418                 int shift = 3;
419                 if (base == 16) shift = 4;
420                 do {
421                         tmp[i++] = (digits[((unsigned char)num) & mask] | locase);
422                         num >>= shift;
423                 } while (num);
424         } else { /* base 10 */
425                 i = put_dec(tmp, num) - tmp;
426         }
427
428         /* printing 100 using %2d gives "100", not "00" */
429         if (i > precision)
430                 precision = i;
431         /* leading space padding */
432         size -= precision;
433         if (!(type & (ZEROPAD+LEFT))) {
434                 while(--size >= 0) {
435                         if (buf < end)
436                                 *buf = ' ';
437                         ++buf;
438                 }
439         }
440         /* sign */
441         if (sign) {
442                 if (buf < end)
443                         *buf = sign;
444                 ++buf;
445         }
446         /* "0x" / "0" prefix */
447         if (need_pfx) {
448                 if (buf < end)
449                         *buf = '0';
450                 ++buf;
451                 if (base == 16) {
452                         if (buf < end)
453                                 *buf = ('X' | locase);
454                         ++buf;
455                 }
456         }
457         /* zero or space padding */
458         if (!(type & LEFT)) {
459                 char c = (type & ZEROPAD) ? '0' : ' ';
460                 while (--size >= 0) {
461                         if (buf < end)
462                                 *buf = c;
463                         ++buf;
464                 }
465         }
466         /* hmm even more zero padding? */
467         while (i <= --precision) {
468                 if (buf < end)
469                         *buf = '0';
470                 ++buf;
471         }
472         /* actual digits of result */
473         while (--i >= 0) {
474                 if (buf < end)
475                         *buf = tmp[i];
476                 ++buf;
477         }
478         /* trailing space padding */
479         while (--size >= 0) {
480                 if (buf < end)
481                         *buf = ' ';
482                 ++buf;
483         }
484         return buf;
485 }
486
487 static char *string(char *buf, char *end, char *s, int field_width, int precision, int flags)
488 {
489         int len, i;
490
491         if ((unsigned long)s < PAGE_SIZE)
492                 s = "<NULL>";
493
494         len = strnlen(s, precision);
495
496         if (!(flags & LEFT)) {
497                 while (len < field_width--) {
498                         if (buf < end)
499                                 *buf = ' ';
500                         ++buf;
501                 }
502         }
503         for (i = 0; i < len; ++i) {
504                 if (buf < end)
505                         *buf = *s;
506                 ++buf; ++s;
507         }
508         while (len < field_width--) {
509                 if (buf < end)
510                         *buf = ' ';
511                 ++buf;
512         }
513         return buf;
514 }
515
516 static inline void *dereference_function_descriptor(void *ptr)
517 {
518 #if defined(CONFIG_IA64) || defined(CONFIG_PPC64)
519         void *p;
520         if (!probe_kernel_address(ptr, p))
521                 ptr = p;
522 #endif
523         return ptr;
524 }
525
526 static char *symbol_string(char *buf, char *end, void *ptr, int field_width, int precision, int flags)
527 {
528         unsigned long value = (unsigned long) ptr;
529 #ifdef CONFIG_KALLSYMS
530         char sym[KSYM_SYMBOL_LEN];
531         sprint_symbol(sym, value);
532         return string(buf, end, sym, field_width, precision, flags);
533 #else
534         field_width = 2*sizeof(void *);
535         flags |= SPECIAL | SMALL | ZEROPAD;
536         return number(buf, end, value, 16, field_width, precision, flags);
537 #endif
538 }
539
540 /*
541  * Show a '%p' thing.  A kernel extension is that the '%p' is followed
542  * by an extra set of alphanumeric characters that are extended format
543  * specifiers.
544  *
545  * Right now we just handle 'F' (for symbolic Function descriptor pointers)
546  * and 'S' (for Symbolic direct pointers), but this can easily be
547  * extended in the future (network address types etc).
548  *
549  * The difference between 'S' and 'F' is that on ia64 and ppc64 function
550  * pointers are really function descriptors, which contain a pointer the
551  * real address. 
552  */
553 static char *pointer(const char *fmt, char *buf, char *end, void *ptr, int field_width, int precision, int flags)
554 {
555         switch (*fmt) {
556         case 'F':
557                 ptr = dereference_function_descriptor(ptr);
558                 /* Fallthrough */
559         case 'S':
560                 return symbol_string(buf, end, ptr, field_width, precision, flags);
561         }
562         flags |= SMALL;
563         if (field_width == -1) {
564                 field_width = 2*sizeof(void *);
565                 flags |= ZEROPAD;
566         }
567         return number(buf, end, (unsigned long) ptr, 16, field_width, precision, flags);
568 }
569
570 /**
571  * vsnprintf - Format a string and place it in a buffer
572  * @buf: The buffer to place the result into
573  * @size: The size of the buffer, including the trailing null space
574  * @fmt: The format string to use
575  * @args: Arguments for the format string
576  *
577  * The return value is the number of characters which would
578  * be generated for the given input, excluding the trailing
579  * '\0', as per ISO C99. If you want to have the exact
580  * number of characters written into @buf as return value
581  * (not including the trailing '\0'), use vscnprintf(). If the
582  * return is greater than or equal to @size, the resulting
583  * string is truncated.
584  *
585  * Call this function if you are already dealing with a va_list.
586  * You probably want snprintf() instead.
587  */
588 int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
589 {
590         unsigned long long num;
591         int base;
592         char *str, *end, c;
593
594         int flags;              /* flags to number() */
595
596         int field_width;        /* width of output field */
597         int precision;          /* min. # of digits for integers; max
598                                    number of chars for from string */
599         int qualifier;          /* 'h', 'l', or 'L' for integer fields */
600                                 /* 'z' support added 23/7/1999 S.H.    */
601                                 /* 'z' changed to 'Z' --davidm 1/25/99 */
602                                 /* 't' added for ptrdiff_t */
603
604         /* Reject out-of-range values early.  Large positive sizes are
605            used for unknown buffer sizes. */
606         if (unlikely((int) size < 0)) {
607                 /* There can be only one.. */
608                 static char warn = 1;
609                 WARN_ON(warn);
610                 warn = 0;
611                 return 0;
612         }
613
614         str = buf;
615         end = buf + size;
616
617         /* Make sure end is always >= buf */
618         if (end < buf) {
619                 end = ((void *)-1);
620                 size = end - buf;
621         }
622
623         for (; *fmt ; ++fmt) {
624                 if (*fmt != '%') {
625                         if (str < end)
626                                 *str = *fmt;
627                         ++str;
628                         continue;
629                 }
630
631                 /* process flags */
632                 flags = 0;
633                 repeat:
634                         ++fmt;          /* this also skips first '%' */
635                         switch (*fmt) {
636                                 case '-': flags |= LEFT; goto repeat;
637                                 case '+': flags |= PLUS; goto repeat;
638                                 case ' ': flags |= SPACE; goto repeat;
639                                 case '#': flags |= SPECIAL; goto repeat;
640                                 case '0': flags |= ZEROPAD; goto repeat;
641                         }
642
643                 /* get field width */
644                 field_width = -1;
645                 if (isdigit(*fmt))
646                         field_width = skip_atoi(&fmt);
647                 else if (*fmt == '*') {
648                         ++fmt;
649                         /* it's the next argument */
650                         field_width = va_arg(args, int);
651                         if (field_width < 0) {
652                                 field_width = -field_width;
653                                 flags |= LEFT;
654                         }
655                 }
656
657                 /* get the precision */
658                 precision = -1;
659                 if (*fmt == '.') {
660                         ++fmt;  
661                         if (isdigit(*fmt))
662                                 precision = skip_atoi(&fmt);
663                         else if (*fmt == '*') {
664                                 ++fmt;
665                                 /* it's the next argument */
666                                 precision = va_arg(args, int);
667                         }
668                         if (precision < 0)
669                                 precision = 0;
670                 }
671
672                 /* get the conversion qualifier */
673                 qualifier = -1;
674                 if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
675                     *fmt =='Z' || *fmt == 'z' || *fmt == 't') {
676                         qualifier = *fmt;
677                         ++fmt;
678                         if (qualifier == 'l' && *fmt == 'l') {
679                                 qualifier = 'L';
680                                 ++fmt;
681                         }
682                 }
683
684                 /* default base */
685                 base = 10;
686
687                 switch (*fmt) {
688                         case 'c':
689                                 if (!(flags & LEFT)) {
690                                         while (--field_width > 0) {
691                                                 if (str < end)
692                                                         *str = ' ';
693                                                 ++str;
694                                         }
695                                 }
696                                 c = (unsigned char) va_arg(args, int);
697                                 if (str < end)
698                                         *str = c;
699                                 ++str;
700                                 while (--field_width > 0) {
701                                         if (str < end)
702                                                 *str = ' ';
703                                         ++str;
704                                 }
705                                 continue;
706
707                         case 's':
708                                 str = string(str, end, va_arg(args, char *), field_width, precision, flags);
709                                 continue;
710
711                         case 'p':
712                                 str = pointer(fmt+1, str, end,
713                                                 va_arg(args, void *),
714                                                 field_width, precision, flags);
715                                 /* Skip all alphanumeric pointer suffixes */
716                                 while (isalnum(fmt[1]))
717                                         fmt++;
718                                 continue;
719
720                         case 'n':
721                                 /* FIXME:
722                                 * What does C99 say about the overflow case here? */
723                                 if (qualifier == 'l') {
724                                         long * ip = va_arg(args, long *);
725                                         *ip = (str - buf);
726                                 } else if (qualifier == 'Z' || qualifier == 'z') {
727                                         size_t * ip = va_arg(args, size_t *);
728                                         *ip = (str - buf);
729                                 } else {
730                                         int * ip = va_arg(args, int *);
731                                         *ip = (str - buf);
732                                 }
733                                 continue;
734
735                         case '%':
736                                 if (str < end)
737                                         *str = '%';
738                                 ++str;
739                                 continue;
740
741                                 /* integer number formats - set up the flags and "break" */
742                         case 'o':
743                                 base = 8;
744                                 break;
745
746                         case 'x':
747                                 flags |= SMALL;
748                         case 'X':
749                                 base = 16;
750                                 break;
751
752                         case 'd':
753                         case 'i':
754                                 flags |= SIGN;
755                         case 'u':
756                                 break;
757
758                         default:
759                                 if (str < end)
760                                         *str = '%';
761                                 ++str;
762                                 if (*fmt) {
763                                         if (str < end)
764                                                 *str = *fmt;
765                                         ++str;
766                                 } else {
767                                         --fmt;
768                                 }
769                                 continue;
770                 }
771                 if (qualifier == 'L')
772                         num = va_arg(args, long long);
773                 else if (qualifier == 'l') {
774                         num = va_arg(args, unsigned long);
775                         if (flags & SIGN)
776                                 num = (signed long) num;
777                 } else if (qualifier == 'Z' || qualifier == 'z') {
778                         num = va_arg(args, size_t);
779                 } else if (qualifier == 't') {
780                         num = va_arg(args, ptrdiff_t);
781                 } else if (qualifier == 'h') {
782                         num = (unsigned short) va_arg(args, int);
783                         if (flags & SIGN)
784                                 num = (signed short) num;
785                 } else {
786                         num = va_arg(args, unsigned int);
787                         if (flags & SIGN)
788                                 num = (signed int) num;
789                 }
790                 str = number(str, end, num, base,
791                                 field_width, precision, flags);
792         }
793         if (size > 0) {
794                 if (str < end)
795                         *str = '\0';
796                 else
797                         end[-1] = '\0';
798         }
799         /* the trailing null byte doesn't count towards the total */
800         return str-buf;
801 }
802
803 EXPORT_SYMBOL(vsnprintf);
804
805 /**
806  * vscnprintf - Format a string and place it in a buffer
807  * @buf: The buffer to place the result into
808  * @size: The size of the buffer, including the trailing null space
809  * @fmt: The format string to use
810  * @args: Arguments for the format string
811  *
812  * The return value is the number of characters which have been written into
813  * the @buf not including the trailing '\0'. If @size is <= 0 the function
814  * returns 0.
815  *
816  * Call this function if you are already dealing with a va_list.
817  * You probably want scnprintf() instead.
818  */
819 int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
820 {
821         int i;
822
823         i=vsnprintf(buf,size,fmt,args);
824         return (i >= size) ? (size - 1) : i;
825 }
826
827 EXPORT_SYMBOL(vscnprintf);
828
829 /**
830  * snprintf - Format a string and place it in a buffer
831  * @buf: The buffer to place the result into
832  * @size: The size of the buffer, including the trailing null space
833  * @fmt: The format string to use
834  * @...: Arguments for the format string
835  *
836  * The return value is the number of characters which would be
837  * generated for the given input, excluding the trailing null,
838  * as per ISO C99.  If the return is greater than or equal to
839  * @size, the resulting string is truncated.
840  */
841 int snprintf(char * buf, size_t size, const char *fmt, ...)
842 {
843         va_list args;
844         int i;
845
846         va_start(args, fmt);
847         i=vsnprintf(buf,size,fmt,args);
848         va_end(args);
849         return i;
850 }
851
852 EXPORT_SYMBOL(snprintf);
853
854 /**
855  * scnprintf - Format a string and place it in a buffer
856  * @buf: The buffer to place the result into
857  * @size: The size of the buffer, including the trailing null space
858  * @fmt: The format string to use
859  * @...: Arguments for the format string
860  *
861  * The return value is the number of characters written into @buf not including
862  * the trailing '\0'. If @size is <= 0 the function returns 0.
863  */
864
865 int scnprintf(char * buf, size_t size, const char *fmt, ...)
866 {
867         va_list args;
868         int i;
869
870         va_start(args, fmt);
871         i = vsnprintf(buf, size, fmt, args);
872         va_end(args);
873         return (i >= size) ? (size - 1) : i;
874 }
875 EXPORT_SYMBOL(scnprintf);
876
877 /**
878  * vsprintf - Format a string and place it in a buffer
879  * @buf: The buffer to place the result into
880  * @fmt: The format string to use
881  * @args: Arguments for the format string
882  *
883  * The function returns the number of characters written
884  * into @buf. Use vsnprintf() or vscnprintf() in order to avoid
885  * buffer overflows.
886  *
887  * Call this function if you are already dealing with a va_list.
888  * You probably want sprintf() instead.
889  */
890 int vsprintf(char *buf, const char *fmt, va_list args)
891 {
892         return vsnprintf(buf, INT_MAX, fmt, args);
893 }
894
895 EXPORT_SYMBOL(vsprintf);
896
897 /**
898  * sprintf - Format a string and place it in a buffer
899  * @buf: The buffer to place the result into
900  * @fmt: The format string to use
901  * @...: Arguments for the format string
902  *
903  * The function returns the number of characters written
904  * into @buf. Use snprintf() or scnprintf() in order to avoid
905  * buffer overflows.
906  */
907 int sprintf(char * buf, const char *fmt, ...)
908 {
909         va_list args;
910         int i;
911
912         va_start(args, fmt);
913         i=vsnprintf(buf, INT_MAX, fmt, args);
914         va_end(args);
915         return i;
916 }
917
918 EXPORT_SYMBOL(sprintf);
919
920 /**
921  * vsscanf - Unformat a buffer into a list of arguments
922  * @buf:        input buffer
923  * @fmt:        format of buffer
924  * @args:       arguments
925  */
926 int vsscanf(const char * buf, const char * fmt, va_list args)
927 {
928         const char *str = buf;
929         char *next;
930         char digit;
931         int num = 0;
932         int qualifier;
933         int base;
934         int field_width;
935         int is_sign = 0;
936
937         while(*fmt && *str) {
938                 /* skip any white space in format */
939                 /* white space in format matchs any amount of
940                  * white space, including none, in the input.
941                  */
942                 if (isspace(*fmt)) {
943                         while (isspace(*fmt))
944                                 ++fmt;
945                         while (isspace(*str))
946                                 ++str;
947                 }
948
949                 /* anything that is not a conversion must match exactly */
950                 if (*fmt != '%' && *fmt) {
951                         if (*fmt++ != *str++)
952                                 break;
953                         continue;
954                 }
955
956                 if (!*fmt)
957                         break;
958                 ++fmt;
959                 
960                 /* skip this conversion.
961                  * advance both strings to next white space
962                  */
963                 if (*fmt == '*') {
964                         while (!isspace(*fmt) && *fmt)
965                                 fmt++;
966                         while (!isspace(*str) && *str)
967                                 str++;
968                         continue;
969                 }
970
971                 /* get field width */
972                 field_width = -1;
973                 if (isdigit(*fmt))
974                         field_width = skip_atoi(&fmt);
975
976                 /* get conversion qualifier */
977                 qualifier = -1;
978                 if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
979                     *fmt == 'Z' || *fmt == 'z') {
980                         qualifier = *fmt++;
981                         if (unlikely(qualifier == *fmt)) {
982                                 if (qualifier == 'h') {
983                                         qualifier = 'H';
984                                         fmt++;
985                                 } else if (qualifier == 'l') {
986                                         qualifier = 'L';
987                                         fmt++;
988                                 }
989                         }
990                 }
991                 base = 10;
992                 is_sign = 0;
993
994                 if (!*fmt || !*str)
995                         break;
996
997                 switch(*fmt++) {
998                 case 'c':
999                 {
1000                         char *s = (char *) va_arg(args,char*);
1001                         if (field_width == -1)
1002                                 field_width = 1;
1003                         do {
1004                                 *s++ = *str++;
1005                         } while (--field_width > 0 && *str);
1006                         num++;
1007                 }
1008                 continue;
1009                 case 's':
1010                 {
1011                         char *s = (char *) va_arg(args, char *);
1012                         if(field_width == -1)
1013                                 field_width = INT_MAX;
1014                         /* first, skip leading white space in buffer */
1015                         while (isspace(*str))
1016                                 str++;
1017
1018                         /* now copy until next white space */
1019                         while (*str && !isspace(*str) && field_width--) {
1020                                 *s++ = *str++;
1021                         }
1022                         *s = '\0';
1023                         num++;
1024                 }
1025                 continue;
1026                 case 'n':
1027                         /* return number of characters read so far */
1028                 {
1029                         int *i = (int *)va_arg(args,int*);
1030                         *i = str - buf;
1031                 }
1032                 continue;
1033                 case 'o':
1034                         base = 8;
1035                         break;
1036                 case 'x':
1037                 case 'X':
1038                         base = 16;
1039                         break;
1040                 case 'i':
1041                         base = 0;
1042                 case 'd':
1043                         is_sign = 1;
1044                 case 'u':
1045                         break;
1046                 case '%':
1047                         /* looking for '%' in str */
1048                         if (*str++ != '%') 
1049                                 return num;
1050                         continue;
1051                 default:
1052                         /* invalid format; stop here */
1053                         return num;
1054                 }
1055
1056                 /* have some sort of integer conversion.
1057                  * first, skip white space in buffer.
1058                  */
1059                 while (isspace(*str))
1060                         str++;
1061
1062                 digit = *str;
1063                 if (is_sign && digit == '-')
1064                         digit = *(str + 1);
1065
1066                 if (!digit
1067                     || (base == 16 && !isxdigit(digit))
1068                     || (base == 10 && !isdigit(digit))
1069                     || (base == 8 && (!isdigit(digit) || digit > '7'))
1070                     || (base == 0 && !isdigit(digit)))
1071                                 break;
1072
1073                 switch(qualifier) {
1074                 case 'H':       /* that's 'hh' in format */
1075                         if (is_sign) {
1076                                 signed char *s = (signed char *) va_arg(args,signed char *);
1077                                 *s = (signed char) simple_strtol(str,&next,base);
1078                         } else {
1079                                 unsigned char *s = (unsigned char *) va_arg(args, unsigned char *);
1080                                 *s = (unsigned char) simple_strtoul(str, &next, base);
1081                         }
1082                         break;
1083                 case 'h':
1084                         if (is_sign) {
1085                                 short *s = (short *) va_arg(args,short *);
1086                                 *s = (short) simple_strtol(str,&next,base);
1087                         } else {
1088                                 unsigned short *s = (unsigned short *) va_arg(args, unsigned short *);
1089                                 *s = (unsigned short) simple_strtoul(str, &next, base);
1090                         }
1091                         break;
1092                 case 'l':
1093                         if (is_sign) {
1094                                 long *l = (long *) va_arg(args,long *);
1095                                 *l = simple_strtol(str,&next,base);
1096                         } else {
1097                                 unsigned long *l = (unsigned long*) va_arg(args,unsigned long*);
1098                                 *l = simple_strtoul(str,&next,base);
1099                         }
1100                         break;
1101                 case 'L':
1102                         if (is_sign) {
1103                                 long long *l = (long long*) va_arg(args,long long *);
1104                                 *l = simple_strtoll(str,&next,base);
1105                         } else {
1106                                 unsigned long long *l = (unsigned long long*) va_arg(args,unsigned long long*);
1107                                 *l = simple_strtoull(str,&next,base);
1108                         }
1109                         break;
1110                 case 'Z':
1111                 case 'z':
1112                 {
1113                         size_t *s = (size_t*) va_arg(args,size_t*);
1114                         *s = (size_t) simple_strtoul(str,&next,base);
1115                 }
1116                 break;
1117                 default:
1118                         if (is_sign) {
1119                                 int *i = (int *) va_arg(args, int*);
1120                                 *i = (int) simple_strtol(str,&next,base);
1121                         } else {
1122                                 unsigned int *i = (unsigned int*) va_arg(args, unsigned int*);
1123                                 *i = (unsigned int) simple_strtoul(str,&next,base);
1124                         }
1125                         break;
1126                 }
1127                 num++;
1128
1129                 if (!next)
1130                         break;
1131                 str = next;
1132         }
1133
1134         /*
1135          * Now we've come all the way through so either the input string or the
1136          * format ended. In the former case, there can be a %n at the current
1137          * position in the format that needs to be filled.
1138          */
1139         if (*fmt == '%' && *(fmt + 1) == 'n') {
1140                 int *p = (int *)va_arg(args, int *);
1141                 *p = str - buf;
1142         }
1143
1144         return num;
1145 }
1146
1147 EXPORT_SYMBOL(vsscanf);
1148
1149 /**
1150  * sscanf - Unformat a buffer into a list of arguments
1151  * @buf:        input buffer
1152  * @fmt:        formatting of buffer
1153  * @...:        resulting arguments
1154  */
1155 int sscanf(const char * buf, const char * fmt, ...)
1156 {
1157         va_list args;
1158         int i;
1159
1160         va_start(args,fmt);
1161         i = vsscanf(buf,fmt,args);
1162         va_end(args);
1163         return i;
1164 }
1165
1166 EXPORT_SYMBOL(sscanf);