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