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