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. If the return is 558 * greater than or equal to @size, the resulting string is truncated. 559 */ 560 561 int scnprintf(char * buf, size_t size, const char *fmt, ...) 562 { 563 va_list args; 564 int i; 565 566 va_start(args, fmt); 567 i = vsnprintf(buf, size, fmt, args); 568 va_end(args); 569 return (i >= size) ? (size - 1) : i; 570 } 571 EXPORT_SYMBOL(scnprintf); 572 573 /** 574 * vsprintf - Format a string and place it in a buffer 575 * @buf: The buffer to place the result into 576 * @fmt: The format string to use 577 * @args: Arguments for the format string 578 * 579 * The function returns the number of characters written 580 * into @buf. Use vsnprintf or vscnprintf in order to avoid 581 * buffer overflows. 582 * 583 * Call this function if you are already dealing with a va_list. 584 * You probably want sprintf instead. 585 */ 586 int vsprintf(char *buf, const char *fmt, va_list args) 587 { 588 return vsnprintf(buf, INT_MAX, fmt, args); 589 } 590 591 EXPORT_SYMBOL(vsprintf); 592 593 /** 594 * sprintf - Format a string and place it in a buffer 595 * @buf: The buffer to place the result into 596 * @fmt: The format string to use 597 * @...: Arguments for the format string 598 * 599 * The function returns the number of characters written 600 * into @buf. Use snprintf or scnprintf in order to avoid 601 * buffer overflows. 602 */ 603 int sprintf(char * buf, const char *fmt, ...) 604 { 605 va_list args; 606 int i; 607 608 va_start(args, fmt); 609 i=vsnprintf(buf, INT_MAX, fmt, args); 610 va_end(args); 611 return i; 612 } 613 614 EXPORT_SYMBOL(sprintf); 615 616 /** 617 * vsscanf - Unformat a buffer into a list of arguments 618 * @buf: input buffer 619 * @fmt: format of buffer 620 * @args: arguments 621 */ 622 int vsscanf(const char * buf, const char * fmt, va_list args) 623 { 624 const char *str = buf; 625 char *next; 626 char digit; 627 int num = 0; 628 int qualifier; 629 int base; 630 int field_width; 631 int is_sign = 0; 632 633 while(*fmt && *str) { 634 /* skip any white space in format */ 635 /* white space in format matchs any amount of 636 * white space, including none, in the input. 637 */ 638 if (isspace(*fmt)) { 639 while (isspace(*fmt)) 640 ++fmt; 641 while (isspace(*str)) 642 ++str; 643 } 644 645 /* anything that is not a conversion must match exactly */ 646 if (*fmt != '%' && *fmt) { 647 if (*fmt++ != *str++) 648 break; 649 continue; 650 } 651 652 if (!*fmt) 653 break; 654 ++fmt; 655 656 /* skip this conversion. 657 * advance both strings to next white space 658 */ 659 if (*fmt == '*') { 660 while (!isspace(*fmt) && *fmt) 661 fmt++; 662 while (!isspace(*str) && *str) 663 str++; 664 continue; 665 } 666 667 /* get field width */ 668 field_width = -1; 669 if (isdigit(*fmt)) 670 field_width = skip_atoi(&fmt); 671 672 /* get conversion qualifier */ 673 qualifier = -1; 674 if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || 675 *fmt == 'Z' || *fmt == 'z') { 676 qualifier = *fmt++; 677 if (unlikely(qualifier == *fmt)) { 678 if (qualifier == 'h') { 679 qualifier = 'H'; 680 fmt++; 681 } else if (qualifier == 'l') { 682 qualifier = 'L'; 683 fmt++; 684 } 685 } 686 } 687 base = 10; 688 is_sign = 0; 689 690 if (!*fmt || !*str) 691 break; 692 693 switch(*fmt++) { 694 case 'c': 695 { 696 char *s = (char *) va_arg(args,char*); 697 if (field_width == -1) 698 field_width = 1; 699 do { 700 *s++ = *str++; 701 } while (--field_width > 0 && *str); 702 num++; 703 } 704 continue; 705 case 's': 706 { 707 char *s = (char *) va_arg(args, char *); 708 if(field_width == -1) 709 field_width = INT_MAX; 710 /* first, skip leading white space in buffer */ 711 while (isspace(*str)) 712 str++; 713 714 /* now copy until next white space */ 715 while (*str && !isspace(*str) && field_width--) { 716 *s++ = *str++; 717 } 718 *s = '\0'; 719 num++; 720 } 721 continue; 722 case 'n': 723 /* return number of characters read so far */ 724 { 725 int *i = (int *)va_arg(args,int*); 726 *i = str - buf; 727 } 728 continue; 729 case 'o': 730 base = 8; 731 break; 732 case 'x': 733 case 'X': 734 base = 16; 735 break; 736 case 'i': 737 base = 0; 738 case 'd': 739 is_sign = 1; 740 case 'u': 741 break; 742 case '%': 743 /* looking for '%' in str */ 744 if (*str++ != '%') 745 return num; 746 continue; 747 default: 748 /* invalid format; stop here */ 749 return num; 750 } 751 752 /* have some sort of integer conversion. 753 * first, skip white space in buffer. 754 */ 755 while (isspace(*str)) 756 str++; 757 758 digit = *str; 759 if (is_sign && digit == '-') 760 digit = *(str + 1); 761 762 if (!digit 763 || (base == 16 && !isxdigit(digit)) 764 || (base == 10 && !isdigit(digit)) 765 || (base == 8 && (!isdigit(digit) || digit > '7')) 766 || (base == 0 && !isdigit(digit))) 767 break; 768 769 switch(qualifier) { 770 case 'H': /* that's 'hh' in format */ 771 if (is_sign) { 772 signed char *s = (signed char *) va_arg(args,signed char *); 773 *s = (signed char) simple_strtol(str,&next,base); 774 } else { 775 unsigned char *s = (unsigned char *) va_arg(args, unsigned char *); 776 *s = (unsigned char) simple_strtoul(str, &next, base); 777 } 778 break; 779 case 'h': 780 if (is_sign) { 781 short *s = (short *) va_arg(args,short *); 782 *s = (short) simple_strtol(str,&next,base); 783 } else { 784 unsigned short *s = (unsigned short *) va_arg(args, unsigned short *); 785 *s = (unsigned short) simple_strtoul(str, &next, base); 786 } 787 break; 788 case 'l': 789 if (is_sign) { 790 long *l = (long *) va_arg(args,long *); 791 *l = simple_strtol(str,&next,base); 792 } else { 793 unsigned long *l = (unsigned long*) va_arg(args,unsigned long*); 794 *l = simple_strtoul(str,&next,base); 795 } 796 break; 797 case 'L': 798 if (is_sign) { 799 long long *l = (long long*) va_arg(args,long long *); 800 *l = simple_strtoll(str,&next,base); 801 } else { 802 unsigned long long *l = (unsigned long long*) va_arg(args,unsigned long long*); 803 *l = simple_strtoull(str,&next,base); 804 } 805 break; 806 case 'Z': 807 case 'z': 808 { 809 size_t *s = (size_t*) va_arg(args,size_t*); 810 *s = (size_t) simple_strtoul(str,&next,base); 811 } 812 break; 813 default: 814 if (is_sign) { 815 int *i = (int *) va_arg(args, int*); 816 *i = (int) simple_strtol(str,&next,base); 817 } else { 818 unsigned int *i = (unsigned int*) va_arg(args, unsigned int*); 819 *i = (unsigned int) simple_strtoul(str,&next,base); 820 } 821 break; 822 } 823 num++; 824 825 if (!next) 826 break; 827 str = next; 828 } 829 return num; 830 } 831 832 EXPORT_SYMBOL(vsscanf); 833 834 /** 835 * sscanf - Unformat a buffer into a list of arguments 836 * @buf: input buffer 837 * @fmt: formatting of buffer 838 * @...: resulting arguments 839 */ 840 int sscanf(const char * buf, const char * fmt, ...) 841 { 842 va_list args; 843 int i; 844 845 va_start(args,fmt); 846 i = vsscanf(buf,fmt,args); 847 va_end(args); 848 return i; 849 } 850 851 EXPORT_SYMBOL(sscanf); 852 853 854 /* Simplified asprintf. */ 855 char *kasprintf(gfp_t gfp, const char *fmt, ...) 856 { 857 va_list ap; 858 unsigned int len; 859 char *p; 860 861 va_start(ap, fmt); 862 len = vsnprintf(NULL, 0, fmt, ap); 863 va_end(ap); 864 865 p = kmalloc(len+1, gfp); 866 if (!p) 867 return NULL; 868 va_start(ap, fmt); 869 vsnprintf(p, len+1, fmt, ap); 870 va_end(ap); 871 return p; 872 } 873 874 EXPORT_SYMBOL(kasprintf); 875