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