[PATCH] scnprintf(): fix a comment
[linux-2.6.git] / 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
26 #include <asm/page.h>           /* for PAGE_SIZE */
27 #include <asm/div64.h>
28
29 /**
30  * simple_strtoul - convert a string to an unsigned long
31  * @cp: The start of the string
32  * @endp: A pointer to the end of the parsed string will be placed here
33  * @base: The number base to use
34  */
35 unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
36 {
37         unsigned long result = 0,value;
38
39         if (!base) {
40                 base = 10;
41                 if (*cp == '0') {
42                         base = 8;
43                         cp++;
44                         if ((toupper(*cp) == 'X') && isxdigit(cp[1])) {
45                                 cp++;
46                                 base = 16;
47                         }
48                 }
49         } else if (base == 16) {
50                 if (cp[0] == '0' && toupper(cp[1]) == 'X')
51                         cp += 2;
52         }
53         while (isxdigit(*cp) &&
54                (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) {
55                 result = result*base + value;
56                 cp++;
57         }
58         if (endp)
59                 *endp = (char *)cp;
60         return result;
61 }
62
63 EXPORT_SYMBOL(simple_strtoul);
64
65 /**
66  * simple_strtol - convert a string to a signed long
67  * @cp: The start of the string
68  * @endp: A pointer to the end of the parsed string will be placed here
69  * @base: The number base to use
70  */
71 long simple_strtol(const char *cp,char **endp,unsigned int base)
72 {
73         if(*cp=='-')
74                 return -simple_strtoul(cp+1,endp,base);
75         return simple_strtoul(cp,endp,base);
76 }
77
78 EXPORT_SYMBOL(simple_strtol);
79
80 /**
81  * simple_strtoull - convert a string to an unsigned long long
82  * @cp: The start of the string
83  * @endp: A pointer to the end of the parsed string will be placed here
84  * @base: The number base to use
85  */
86 unsigned long long simple_strtoull(const char *cp,char **endp,unsigned int base)
87 {
88         unsigned long long result = 0,value;
89
90         if (!base) {
91                 base = 10;
92                 if (*cp == '0') {
93                         base = 8;
94                         cp++;
95                         if ((toupper(*cp) == 'X') && isxdigit(cp[1])) {
96                                 cp++;
97                                 base = 16;
98                         }
99                 }
100         } else if (base == 16) {
101                 if (cp[0] == '0' && toupper(cp[1]) == 'X')
102                         cp += 2;
103         }
104         while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)
105             ? toupper(*cp) : *cp)-'A'+10) < base) {
106                 result = result*base + value;
107                 cp++;
108         }
109         if (endp)
110                 *endp = (char *)cp;
111         return result;
112 }
113
114 EXPORT_SYMBOL(simple_strtoull);
115
116 /**
117  * simple_strtoll - convert a string to a signed long long
118  * @cp: The start of the string
119  * @endp: A pointer to the end of the parsed string will be placed here
120  * @base: The number base to use
121  */
122 long long simple_strtoll(const char *cp,char **endp,unsigned int base)
123 {
124         if(*cp=='-')
125                 return -simple_strtoull(cp+1,endp,base);
126         return simple_strtoull(cp,endp,base);
127 }
128
129 static int skip_atoi(const char **s)
130 {
131         int i=0;
132
133         while (isdigit(**s))
134                 i = i*10 + *((*s)++) - '0';
135         return i;
136 }
137
138 #define ZEROPAD 1               /* pad with zero */
139 #define SIGN    2               /* unsigned/signed long */
140 #define PLUS    4               /* show plus */
141 #define SPACE   8               /* space if plus */
142 #define LEFT    16              /* left justified */
143 #define SPECIAL 32              /* 0x */
144 #define LARGE   64              /* use 'ABCDEF' instead of 'abcdef' */
145
146 static char * number(char * buf, char * end, unsigned long long num, int base, int size, int precision, int type)
147 {
148         char c,sign,tmp[66];
149         const char *digits;
150         static const char small_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
151         static const char large_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
152         int i;
153
154         digits = (type & LARGE) ? large_digits : small_digits;
155         if (type & LEFT)
156                 type &= ~ZEROPAD;
157         if (base < 2 || base > 36)
158                 return NULL;
159         c = (type & ZEROPAD) ? '0' : ' ';
160         sign = 0;
161         if (type & SIGN) {
162                 if ((signed long long) num < 0) {
163                         sign = '-';
164                         num = - (signed long long) num;
165                         size--;
166                 } else if (type & PLUS) {
167                         sign = '+';
168                         size--;
169                 } else if (type & SPACE) {
170                         sign = ' ';
171                         size--;
172                 }
173         }
174         if (type & SPECIAL) {
175                 if (base == 16)
176                         size -= 2;
177                 else if (base == 8)
178                         size--;
179         }
180         i = 0;
181         if (num == 0)
182                 tmp[i++]='0';
183         else while (num != 0)
184                 tmp[i++] = digits[do_div(num,base)];
185         if (i > precision)
186                 precision = i;
187         size -= precision;
188         if (!(type&(ZEROPAD+LEFT))) {
189                 while(size-->0) {
190                         if (buf < end)
191                                 *buf = ' ';
192                         ++buf;
193                 }
194         }
195         if (sign) {
196                 if (buf < end)
197                         *buf = sign;
198                 ++buf;
199         }
200         if (type & SPECIAL) {
201                 if (base==8) {
202                         if (buf < end)
203                                 *buf = '0';
204                         ++buf;
205                 } else if (base==16) {
206                         if (buf < end)
207                                 *buf = '0';
208                         ++buf;
209                         if (buf < end)
210                                 *buf = digits[33];
211                         ++buf;
212                 }
213         }
214         if (!(type & LEFT)) {
215                 while (size-- > 0) {
216                         if (buf < end)
217                                 *buf = c;
218                         ++buf;
219                 }
220         }
221         while (i < precision--) {
222                 if (buf < end)
223                         *buf = '0';
224                 ++buf;
225         }
226         while (i-- > 0) {
227                 if (buf < end)
228                         *buf = tmp[i];
229                 ++buf;
230         }
231         while (size-- > 0) {
232                 if (buf < end)
233                         *buf = ' ';
234                 ++buf;
235         }
236         return buf;
237 }
238
239 /**
240  * vsnprintf - Format a string and place it in a buffer
241  * @buf: The buffer to place the result into
242  * @size: The size of the buffer, including the trailing null space
243  * @fmt: The format string to use
244  * @args: Arguments for the format string
245  *
246  * The return value is the number of characters which would
247  * be generated for the given input, excluding the trailing
248  * '\0', as per ISO C99. If you want to have the exact
249  * number of characters written into @buf as return value
250  * (not including the trailing '\0'), use vscnprintf(). If the
251  * return is greater than or equal to @size, the resulting
252  * string is truncated.
253  *
254  * Call this function if you are already dealing with a va_list.
255  * You probably want snprintf() instead.
256  */
257 int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
258 {
259         int len;
260         unsigned long long num;
261         int i, base;
262         char *str, *end, c;
263         const char *s;
264
265         int flags;              /* flags to number() */
266
267         int field_width;        /* width of output field */
268         int precision;          /* min. # of digits for integers; max
269                                    number of chars for from string */
270         int qualifier;          /* 'h', 'l', or 'L' for integer fields */
271                                 /* 'z' support added 23/7/1999 S.H.    */
272                                 /* 'z' changed to 'Z' --davidm 1/25/99 */
273                                 /* 't' added for ptrdiff_t */
274
275         /* Reject out-of-range values early.  Large positive sizes are
276            used for unknown buffer sizes. */
277         if (unlikely((int) size < 0)) {
278                 /* There can be only one.. */
279                 static int warn = 1;
280                 WARN_ON(warn);
281                 warn = 0;
282                 return 0;
283         }
284
285         str = buf;
286         end = buf + size;
287
288         /* Make sure end is always >= buf */
289         if (end < buf) {
290                 end = ((void *)-1);
291                 size = end - buf;
292         }
293
294         for (; *fmt ; ++fmt) {
295                 if (*fmt != '%') {
296                         if (str < end)
297                                 *str = *fmt;
298                         ++str;
299                         continue;
300                 }
301
302                 /* process flags */
303                 flags = 0;
304                 repeat:
305                         ++fmt;          /* this also skips first '%' */
306                         switch (*fmt) {
307                                 case '-': flags |= LEFT; goto repeat;
308                                 case '+': flags |= PLUS; goto repeat;
309                                 case ' ': flags |= SPACE; goto repeat;
310                                 case '#': flags |= SPECIAL; goto repeat;
311                                 case '0': flags |= ZEROPAD; goto repeat;
312                         }
313
314                 /* get field width */
315                 field_width = -1;
316                 if (isdigit(*fmt))
317                         field_width = skip_atoi(&fmt);
318                 else if (*fmt == '*') {
319                         ++fmt;
320                         /* it's the next argument */
321                         field_width = va_arg(args, int);
322                         if (field_width < 0) {
323                                 field_width = -field_width;
324                                 flags |= LEFT;
325                         }
326                 }
327
328                 /* get the precision */
329                 precision = -1;
330                 if (*fmt == '.') {
331                         ++fmt;  
332                         if (isdigit(*fmt))
333                                 precision = skip_atoi(&fmt);
334                         else if (*fmt == '*') {
335                                 ++fmt;
336                                 /* it's the next argument */
337                                 precision = va_arg(args, int);
338                         }
339                         if (precision < 0)
340                                 precision = 0;
341                 }
342
343                 /* get the conversion qualifier */
344                 qualifier = -1;
345                 if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
346                     *fmt =='Z' || *fmt == 'z' || *fmt == 't') {
347                         qualifier = *fmt;
348                         ++fmt;
349                         if (qualifier == 'l' && *fmt == 'l') {
350                                 qualifier = 'L';
351                                 ++fmt;
352                         }
353                 }
354
355                 /* default base */
356                 base = 10;
357
358                 switch (*fmt) {
359                         case 'c':
360                                 if (!(flags & LEFT)) {
361                                         while (--field_width > 0) {
362                                                 if (str < end)
363                                                         *str = ' ';
364                                                 ++str;
365                                         }
366                                 }
367                                 c = (unsigned char) va_arg(args, int);
368                                 if (str < end)
369                                         *str = c;
370                                 ++str;
371                                 while (--field_width > 0) {
372                                         if (str < end)
373                                                 *str = ' ';
374                                         ++str;
375                                 }
376                                 continue;
377
378                         case 's':
379                                 s = va_arg(args, char *);
380                                 if ((unsigned long)s < PAGE_SIZE)
381                                         s = "<NULL>";
382
383                                 len = strnlen(s, precision);
384
385                                 if (!(flags & LEFT)) {
386                                         while (len < field_width--) {
387                                                 if (str < end)
388                                                         *str = ' ';
389                                                 ++str;
390                                         }
391                                 }
392                                 for (i = 0; i < len; ++i) {
393                                         if (str < end)
394                                                 *str = *s;
395                                         ++str; ++s;
396                                 }
397                                 while (len < field_width--) {
398                                         if (str < end)
399                                                 *str = ' ';
400                                         ++str;
401                                 }
402                                 continue;
403
404                         case 'p':
405                                 if (field_width == -1) {
406                                         field_width = 2*sizeof(void *);
407                                         flags |= ZEROPAD;
408                                 }
409                                 str = number(str, end,
410                                                 (unsigned long) va_arg(args, void *),
411                                                 16, field_width, precision, flags);
412                                 continue;
413
414
415                         case 'n':
416                                 /* FIXME:
417                                 * What does C99 say about the overflow case here? */
418                                 if (qualifier == 'l') {
419                                         long * ip = va_arg(args, long *);
420                                         *ip = (str - buf);
421                                 } else if (qualifier == 'Z' || qualifier == 'z') {
422                                         size_t * ip = va_arg(args, size_t *);
423                                         *ip = (str - buf);
424                                 } else {
425                                         int * ip = va_arg(args, int *);
426                                         *ip = (str - buf);
427                                 }
428                                 continue;
429
430                         case '%':
431                                 if (str < end)
432                                         *str = '%';
433                                 ++str;
434                                 continue;
435
436                                 /* integer number formats - set up the flags and "break" */
437                         case 'o':
438                                 base = 8;
439                                 break;
440
441                         case 'X':
442                                 flags |= LARGE;
443                         case 'x':
444                                 base = 16;
445                                 break;
446
447                         case 'd':
448                         case 'i':
449                                 flags |= SIGN;
450                         case 'u':
451                                 break;
452
453                         default:
454                                 if (str < end)
455                                         *str = '%';
456                                 ++str;
457                                 if (*fmt) {
458                                         if (str < end)
459                                                 *str = *fmt;
460                                         ++str;
461                                 } else {
462                                         --fmt;
463                                 }
464                                 continue;
465                 }
466                 if (qualifier == 'L')
467                         num = va_arg(args, long long);
468                 else if (qualifier == 'l') {
469                         num = va_arg(args, unsigned long);
470                         if (flags & SIGN)
471                                 num = (signed long) num;
472                 } else if (qualifier == 'Z' || qualifier == 'z') {
473                         num = va_arg(args, size_t);
474                 } else if (qualifier == 't') {
475                         num = va_arg(args, ptrdiff_t);
476                 } else if (qualifier == 'h') {
477                         num = (unsigned short) va_arg(args, int);
478                         if (flags & SIGN)
479                                 num = (signed short) num;
480                 } else {
481                         num = va_arg(args, unsigned int);
482                         if (flags & SIGN)
483                                 num = (signed int) num;
484                 }
485                 str = number(str, end, num, base,
486                                 field_width, precision, flags);
487         }
488         if (size > 0) {
489                 if (str < end)
490                         *str = '\0';
491                 else
492                         end[-1] = '\0';
493         }
494         /* the trailing null byte doesn't count towards the total */
495         return str-buf;
496 }
497
498 EXPORT_SYMBOL(vsnprintf);
499
500 /**
501  * vscnprintf - Format a string and place it in a buffer
502  * @buf: The buffer to place the result into
503  * @size: The size of the buffer, including the trailing null space
504  * @fmt: The format string to use
505  * @args: Arguments for the format string
506  *
507  * The return value is the number of characters which have been written into
508  * the @buf not including the trailing '\0'. If @size is <= 0 the function
509  * returns 0.
510  *
511  * Call this function if you are already dealing with a va_list.
512  * You probably want scnprintf() instead.
513  */
514 int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
515 {
516         int i;
517
518         i=vsnprintf(buf,size,fmt,args);
519         return (i >= size) ? (size - 1) : i;
520 }
521
522 EXPORT_SYMBOL(vscnprintf);
523
524 /**
525  * snprintf - Format a string and place it in a buffer
526  * @buf: The buffer to place the result into
527  * @size: The size of the buffer, including the trailing null space
528  * @fmt: The format string to use
529  * @...: Arguments for the format string
530  *
531  * The return value is the number of characters which would be
532  * generated for the given input, excluding the trailing null,
533  * as per ISO C99.  If the return is greater than or equal to
534  * @size, the resulting string is truncated.
535  */
536 int snprintf(char * buf, size_t size, const char *fmt, ...)
537 {
538         va_list args;
539         int i;
540
541         va_start(args, fmt);
542         i=vsnprintf(buf,size,fmt,args);
543         va_end(args);
544         return i;
545 }
546
547 EXPORT_SYMBOL(snprintf);
548
549 /**
550  * scnprintf - Format a string and place it in a buffer
551  * @buf: The buffer to place the result into
552  * @size: The size of the buffer, including the trailing null space
553  * @fmt: The format string to use
554  * @...: Arguments for the format string
555  *
556  * The return value is the number of characters written into @buf not including
557  * the trailing '\0'. If @size is <= 0 the function returns 0.
558  */
559
560 int scnprintf(char * buf, size_t size, const char *fmt, ...)
561 {
562         va_list args;
563         int i;
564
565         va_start(args, fmt);
566         i = vsnprintf(buf, size, fmt, args);
567         va_end(args);
568         return (i >= size) ? (size - 1) : i;
569 }
570 EXPORT_SYMBOL(scnprintf);
571
572 /**
573  * vsprintf - Format a string and place it in a buffer
574  * @buf: The buffer to place the result into
575  * @fmt: The format string to use
576  * @args: Arguments for the format string
577  *
578  * The function returns the number of characters written
579  * into @buf. Use vsnprintf() or vscnprintf() in order to avoid
580  * buffer overflows.
581  *
582  * Call this function if you are already dealing with a va_list.
583  * You probably want sprintf() instead.
584  */
585 int vsprintf(char *buf, const char *fmt, va_list args)
586 {
587         return vsnprintf(buf, INT_MAX, fmt, args);
588 }
589
590 EXPORT_SYMBOL(vsprintf);
591
592 /**
593  * sprintf - Format a string and place it in a buffer
594  * @buf: The buffer to place the result into
595  * @fmt: The format string to use
596  * @...: Arguments for the format string
597  *
598  * The function returns the number of characters written
599  * into @buf. Use snprintf() or scnprintf() in order to avoid
600  * buffer overflows.
601  */
602 int sprintf(char * buf, const char *fmt, ...)
603 {
604         va_list args;
605         int i;
606
607         va_start(args, fmt);
608         i=vsnprintf(buf, INT_MAX, fmt, args);
609         va_end(args);
610         return i;
611 }
612
613 EXPORT_SYMBOL(sprintf);
614
615 /**
616  * vsscanf - Unformat a buffer into a list of arguments
617  * @buf:        input buffer
618  * @fmt:        format of buffer
619  * @args:       arguments
620  */
621 int vsscanf(const char * buf, const char * fmt, va_list args)
622 {
623         const char *str = buf;
624         char *next;
625         char digit;
626         int num = 0;
627         int qualifier;
628         int base;
629         int field_width;
630         int is_sign = 0;
631
632         while(*fmt && *str) {
633                 /* skip any white space in format */
634                 /* white space in format matchs any amount of
635                  * white space, including none, in the input.
636                  */
637                 if (isspace(*fmt)) {
638                         while (isspace(*fmt))
639                                 ++fmt;
640                         while (isspace(*str))
641                                 ++str;
642                 }
643
644                 /* anything that is not a conversion must match exactly */
645                 if (*fmt != '%' && *fmt) {
646                         if (*fmt++ != *str++)
647                                 break;
648                         continue;
649                 }
650
651                 if (!*fmt)
652                         break;
653                 ++fmt;
654                 
655                 /* skip this conversion.
656                  * advance both strings to next white space
657                  */
658                 if (*fmt == '*') {
659                         while (!isspace(*fmt) && *fmt)
660                                 fmt++;
661                         while (!isspace(*str) && *str)
662                                 str++;
663                         continue;
664                 }
665
666                 /* get field width */
667                 field_width = -1;
668                 if (isdigit(*fmt))
669                         field_width = skip_atoi(&fmt);
670
671                 /* get conversion qualifier */
672                 qualifier = -1;
673                 if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
674                     *fmt == 'Z' || *fmt == 'z') {
675                         qualifier = *fmt++;
676                         if (unlikely(qualifier == *fmt)) {
677                                 if (qualifier == 'h') {
678                                         qualifier = 'H';
679                                         fmt++;
680                                 } else if (qualifier == 'l') {
681                                         qualifier = 'L';
682                                         fmt++;
683                                 }
684                         }
685                 }
686                 base = 10;
687                 is_sign = 0;
688
689                 if (!*fmt || !*str)
690                         break;
691
692                 switch(*fmt++) {
693                 case 'c':
694                 {
695                         char *s = (char *) va_arg(args,char*);
696                         if (field_width == -1)
697                                 field_width = 1;
698                         do {
699                                 *s++ = *str++;
700                         } while (--field_width > 0 && *str);
701                         num++;
702                 }
703                 continue;
704                 case 's':
705                 {
706                         char *s = (char *) va_arg(args, char *);
707                         if(field_width == -1)
708                                 field_width = INT_MAX;
709                         /* first, skip leading white space in buffer */
710                         while (isspace(*str))
711                                 str++;
712
713                         /* now copy until next white space */
714                         while (*str && !isspace(*str) && field_width--) {
715                                 *s++ = *str++;
716                         }
717                         *s = '\0';
718                         num++;
719                 }
720                 continue;
721                 case 'n':
722                         /* return number of characters read so far */
723                 {
724                         int *i = (int *)va_arg(args,int*);
725                         *i = str - buf;
726                 }
727                 continue;
728                 case 'o':
729                         base = 8;
730                         break;
731                 case 'x':
732                 case 'X':
733                         base = 16;
734                         break;
735                 case 'i':
736                         base = 0;
737                 case 'd':
738                         is_sign = 1;
739                 case 'u':
740                         break;
741                 case '%':
742                         /* looking for '%' in str */
743                         if (*str++ != '%') 
744                                 return num;
745                         continue;
746                 default:
747                         /* invalid format; stop here */
748                         return num;
749                 }
750
751                 /* have some sort of integer conversion.
752                  * first, skip white space in buffer.
753                  */
754                 while (isspace(*str))
755                         str++;
756
757                 digit = *str;
758                 if (is_sign && digit == '-')
759                         digit = *(str + 1);
760
761                 if (!digit
762                     || (base == 16 && !isxdigit(digit))
763                     || (base == 10 && !isdigit(digit))
764                     || (base == 8 && (!isdigit(digit) || digit > '7'))
765                     || (base == 0 && !isdigit(digit)))
766                                 break;
767
768                 switch(qualifier) {
769                 case 'H':       /* that's 'hh' in format */
770                         if (is_sign) {
771                                 signed char *s = (signed char *) va_arg(args,signed char *);
772                                 *s = (signed char) simple_strtol(str,&next,base);
773                         } else {
774                                 unsigned char *s = (unsigned char *) va_arg(args, unsigned char *);
775                                 *s = (unsigned char) simple_strtoul(str, &next, base);
776                         }
777                         break;
778                 case 'h':
779                         if (is_sign) {
780                                 short *s = (short *) va_arg(args,short *);
781                                 *s = (short) simple_strtol(str,&next,base);
782                         } else {
783                                 unsigned short *s = (unsigned short *) va_arg(args, unsigned short *);
784                                 *s = (unsigned short) simple_strtoul(str, &next, base);
785                         }
786                         break;
787                 case 'l':
788                         if (is_sign) {
789                                 long *l = (long *) va_arg(args,long *);
790                                 *l = simple_strtol(str,&next,base);
791                         } else {
792                                 unsigned long *l = (unsigned long*) va_arg(args,unsigned long*);
793                                 *l = simple_strtoul(str,&next,base);
794                         }
795                         break;
796                 case 'L':
797                         if (is_sign) {
798                                 long long *l = (long long*) va_arg(args,long long *);
799                                 *l = simple_strtoll(str,&next,base);
800                         } else {
801                                 unsigned long long *l = (unsigned long long*) va_arg(args,unsigned long long*);
802                                 *l = simple_strtoull(str,&next,base);
803                         }
804                         break;
805                 case 'Z':
806                 case 'z':
807                 {
808                         size_t *s = (size_t*) va_arg(args,size_t*);
809                         *s = (size_t) simple_strtoul(str,&next,base);
810                 }
811                 break;
812                 default:
813                         if (is_sign) {
814                                 int *i = (int *) va_arg(args, int*);
815                                 *i = (int) simple_strtol(str,&next,base);
816                         } else {
817                                 unsigned int *i = (unsigned int*) va_arg(args, unsigned int*);
818                                 *i = (unsigned int) simple_strtoul(str,&next,base);
819                         }
820                         break;
821                 }
822                 num++;
823
824                 if (!next)
825                         break;
826                 str = next;
827         }
828         return num;
829 }
830
831 EXPORT_SYMBOL(vsscanf);
832
833 /**
834  * sscanf - Unformat a buffer into a list of arguments
835  * @buf:        input buffer
836  * @fmt:        formatting of buffer
837  * @...:        resulting arguments
838  */
839 int sscanf(const char * buf, const char * fmt, ...)
840 {
841         va_list args;
842         int i;
843
844         va_start(args,fmt);
845         i = vsscanf(buf,fmt,args);
846         va_end(args);
847         return i;
848 }
849
850 EXPORT_SYMBOL(sscanf);
851
852
853 /* Simplified asprintf. */
854 char *kasprintf(gfp_t gfp, const char *fmt, ...)
855 {
856         va_list ap;
857         unsigned int len;
858         char *p;
859
860         va_start(ap, fmt);
861         len = vsnprintf(NULL, 0, fmt, ap);
862         va_end(ap);
863
864         p = kmalloc(len+1, gfp);
865         if (!p)
866                 return NULL;
867         va_start(ap, fmt);
868         vsnprintf(p, len+1, fmt, ap);
869         va_end(ap);
870         return p;
871 }
872
873 EXPORT_SYMBOL(kasprintf);