1 // SPDX-License-Identifier: GPL-2.0-only 2 /* -*- linux-c -*- ------------------------------------------------------- * 3 * 4 * Copyright (C) 1991, 1992 Linus Torvalds 5 * Copyright 2007 rPath, Inc. - All Rights Reserved 6 * 7 * ----------------------------------------------------------------------- */ 8 9 /* 10 * Oh, it's a waste of space, but oh-so-yummy for debugging. 11 */ 12 13 #include <stdarg.h> 14 15 #include <linux/compiler.h> 16 #include <linux/ctype.h> 17 #include <linux/limits.h> 18 #include <linux/string.h> 19 20 static int skip_atoi(const char **s) 21 { 22 int i = 0; 23 24 while (isdigit(**s)) 25 i = i * 10 + *((*s)++) - '0'; 26 return i; 27 } 28 29 /* 30 * put_dec_full4 handles numbers in the range 0 <= r < 10000. 31 * The multiplier 0xccd is round(2^15/10), and the approximation 32 * r/10 == (r * 0xccd) >> 15 is exact for all r < 16389. 33 */ 34 static 35 void put_dec_full4(char *buf, unsigned int r) 36 { 37 int i; 38 39 for (i = 0; i < 3; i++) { 40 unsigned int q = (r * 0xccd) >> 15; 41 *buf++ = '0' + (r - q * 10); 42 r = q; 43 } 44 *buf++ = '0' + r; 45 } 46 47 /* put_dec is copied from lib/vsprintf.c with small modifications */ 48 49 /* 50 * Call put_dec_full4 on x % 10000, return x / 10000. 51 * The approximation x/10000 == (x * 0x346DC5D7) >> 43 52 * holds for all x < 1,128,869,999. The largest value this 53 * helper will ever be asked to convert is 1,125,520,955. 54 * (second call in the put_dec code, assuming n is all-ones). 55 */ 56 static 57 unsigned int put_dec_helper4(char *buf, unsigned int x) 58 { 59 unsigned int q = (x * 0x346DC5D7ULL) >> 43; 60 61 put_dec_full4(buf, x - q * 10000); 62 return q; 63 } 64 65 /* Based on code by Douglas W. Jones found at 66 * <http://www.cs.uiowa.edu/~jones/bcd/decimal.html#sixtyfour> 67 * (with permission from the author). 68 * Performs no 64-bit division and hence should be fast on 32-bit machines. 69 */ 70 static 71 int put_dec(char *buf, unsigned long long n) 72 { 73 unsigned int d3, d2, d1, q, h; 74 char *p = buf; 75 76 d1 = ((unsigned int)n >> 16); /* implicit "& 0xffff" */ 77 h = (n >> 32); 78 d2 = (h ) & 0xffff; 79 d3 = (h >> 16); /* implicit "& 0xffff" */ 80 81 /* n = 2^48 d3 + 2^32 d2 + 2^16 d1 + d0 82 = 281_4749_7671_0656 d3 + 42_9496_7296 d2 + 6_5536 d1 + d0 */ 83 q = 656 * d3 + 7296 * d2 + 5536 * d1 + ((unsigned int)n & 0xffff); 84 q = put_dec_helper4(p, q); 85 p += 4; 86 87 q += 7671 * d3 + 9496 * d2 + 6 * d1; 88 q = put_dec_helper4(p, q); 89 p += 4; 90 91 q += 4749 * d3 + 42 * d2; 92 q = put_dec_helper4(p, q); 93 p += 4; 94 95 q += 281 * d3; 96 q = put_dec_helper4(p, q); 97 p += 4; 98 99 put_dec_full4(p, q); 100 p += 4; 101 102 /* strip off the extra 0's we printed */ 103 while (p > buf && p[-1] == '0') 104 --p; 105 106 return p - buf; 107 } 108 109 #define ZEROPAD 1 /* pad with zero */ 110 #define SIGN 2 /* unsigned/signed long */ 111 #define PLUS 4 /* show plus */ 112 #define SPACE 8 /* space if plus */ 113 #define LEFT 16 /* left justified */ 114 #define SMALL 32 /* Must be 32 == 0x20 */ 115 #define SPECIAL 64 /* 0x */ 116 117 static char *number(char *str, long long num, int base, int size, int precision, 118 int type) 119 { 120 /* we are called with base 8, 10 or 16, only, thus don't need "G..." */ 121 static const char digits[16] = "0123456789ABCDEF"; /* "GHIJKLMNOPQRSTUVWXYZ"; */ 122 123 char tmp[66]; 124 char c, sign, locase; 125 int i; 126 127 /* locase = 0 or 0x20. ORing digits or letters with 'locase' 128 * produces same digits or (maybe lowercased) letters */ 129 locase = (type & SMALL); 130 if (type & LEFT) 131 type &= ~ZEROPAD; 132 c = (type & ZEROPAD) ? '0' : ' '; 133 sign = 0; 134 if (type & SIGN) { 135 if (num < 0) { 136 sign = '-'; 137 num = -num; 138 size--; 139 } else if (type & PLUS) { 140 sign = '+'; 141 size--; 142 } else if (type & SPACE) { 143 sign = ' '; 144 size--; 145 } 146 } 147 if (type & SPECIAL) { 148 if (base == 16) 149 size -= 2; 150 else if (base == 8) 151 size--; 152 } 153 i = 0; 154 if (num == 0) 155 tmp[i++] = '0'; 156 else { 157 switch (base) { 158 case 10: 159 i += put_dec(&tmp[i], num); 160 break; 161 case 8: 162 while (num != 0) { 163 tmp[i++] = '0' + (num & 07); 164 num = (unsigned long long)num >> 3; 165 } 166 break; 167 case 16: 168 while (num != 0) { 169 tmp[i++] = digits[num & 0xf] | locase; 170 num = (unsigned long long)num >> 4; 171 } 172 break; 173 default: 174 unreachable(); 175 } 176 } 177 178 if (i > precision) 179 precision = i; 180 size -= precision; 181 if (!(type & (ZEROPAD + LEFT))) 182 while (size-- > 0) 183 *str++ = ' '; 184 if (sign) 185 *str++ = sign; 186 if (type & SPECIAL) { 187 if (base == 8) { 188 *str++ = '0'; 189 } else if (base == 16) { 190 *str++ = '0'; 191 *str++ = ('X' | locase); 192 } 193 } 194 if (!(type & LEFT)) 195 while (size-- > 0) 196 *str++ = c; 197 while (i < precision--) 198 *str++ = '0'; 199 while (i-- > 0) 200 *str++ = tmp[i]; 201 while (size-- > 0) 202 *str++ = ' '; 203 return str; 204 } 205 206 static 207 int get_flags(const char **fmt) 208 { 209 int flags = 0; 210 211 do { 212 switch (**fmt) { 213 case '-': 214 flags |= LEFT; 215 break; 216 case '+': 217 flags |= PLUS; 218 break; 219 case ' ': 220 flags |= SPACE; 221 break; 222 case '#': 223 flags |= SPECIAL; 224 break; 225 case '0': 226 flags |= ZEROPAD; 227 break; 228 default: 229 return flags; 230 } 231 ++(*fmt); 232 } while (1); 233 } 234 235 static 236 int get_int(const char **fmt, va_list *ap) 237 { 238 if (isdigit(**fmt)) 239 return skip_atoi(fmt); 240 if (**fmt == '*') { 241 ++(*fmt); 242 /* it's the next argument */ 243 return va_arg(*ap, int); 244 } 245 return 0; 246 } 247 248 static 249 unsigned long long get_number(int sign, int qualifier, va_list *ap) 250 { 251 if (sign) { 252 switch (qualifier) { 253 case 'L': 254 return va_arg(*ap, long long); 255 case 'l': 256 return va_arg(*ap, long); 257 case 'h': 258 return (short)va_arg(*ap, int); 259 case 'H': 260 return (signed char)va_arg(*ap, int); 261 default: 262 return va_arg(*ap, int); 263 }; 264 } else { 265 switch (qualifier) { 266 case 'L': 267 return va_arg(*ap, unsigned long long); 268 case 'l': 269 return va_arg(*ap, unsigned long); 270 case 'h': 271 return (unsigned short)va_arg(*ap, int); 272 case 'H': 273 return (unsigned char)va_arg(*ap, int); 274 default: 275 return va_arg(*ap, unsigned int); 276 } 277 } 278 } 279 280 int vsprintf(char *buf, const char *fmt, va_list ap) 281 { 282 int len; 283 unsigned long long num; 284 int i, base; 285 char *str; 286 const char *s; 287 288 int flags; /* flags to number() */ 289 290 int field_width; /* width of output field */ 291 int precision; /* min. # of digits for integers; max 292 number of chars for from string */ 293 int qualifier; /* 'h', 'hh', 'l' or 'll' for integer fields */ 294 295 va_list args; 296 297 /* 298 * We want to pass our input va_list to helper functions by reference, 299 * but there's an annoying edge case. If va_list was originally passed 300 * to us by value, we could just pass &ap down to the helpers. This is 301 * the case on, for example, X86_32. 302 * However, on X86_64 (and possibly others), va_list is actually a 303 * size-1 array containing a structure. Our function parameter ap has 304 * decayed from T[1] to T*, and &ap has type T** rather than T(*)[1], 305 * which is what will be expected by a function taking a va_list * 306 * parameter. 307 * One standard way to solve this mess is by creating a copy in a local 308 * variable of type va_list and then passing a pointer to that local 309 * copy instead, which is what we do here. 310 */ 311 va_copy(args, ap); 312 313 for (str = buf; *fmt; ++fmt) { 314 if (*fmt != '%' || *++fmt == '%') { 315 *str++ = *fmt; 316 continue; 317 } 318 319 /* process flags */ 320 flags = get_flags(&fmt); 321 322 /* get field width */ 323 field_width = get_int(&fmt, &args); 324 if (field_width < 0) { 325 field_width = -field_width; 326 flags |= LEFT; 327 } 328 329 /* get the precision */ 330 precision = -1; 331 if (*fmt == '.') { 332 ++fmt; 333 precision = get_int(&fmt, &args); 334 if (precision >= 0) 335 flags &= ~ZEROPAD; 336 } 337 338 /* get the conversion qualifier */ 339 qualifier = -1; 340 if (*fmt == 'h' || *fmt == 'l') { 341 qualifier = *fmt; 342 ++fmt; 343 if (qualifier == *fmt) { 344 qualifier -= 'a'-'A'; 345 ++fmt; 346 } 347 } 348 349 switch (*fmt) { 350 case 'c': 351 if (!(flags & LEFT)) 352 while (--field_width > 0) 353 *str++ = ' '; 354 *str++ = (unsigned char)va_arg(args, int); 355 while (--field_width > 0) 356 *str++ = ' '; 357 continue; 358 359 case 's': 360 if (precision < 0) 361 precision = INT_MAX; 362 s = va_arg(args, char *); 363 if (!s) 364 s = precision < 6 ? "" : "(null)"; 365 len = strnlen(s, precision); 366 367 if (!(flags & LEFT)) 368 while (len < field_width--) 369 *str++ = ' '; 370 for (i = 0; i < len; ++i) 371 *str++ = *s++; 372 while (len < field_width--) 373 *str++ = ' '; 374 continue; 375 376 /* integer number formats - set up the flags and "break" */ 377 case 'o': 378 base = 8; 379 break; 380 381 case 'p': 382 if (precision < 0) 383 precision = 2 * sizeof(void *); 384 fallthrough; 385 case 'x': 386 flags |= SMALL; 387 fallthrough; 388 case 'X': 389 base = 16; 390 break; 391 392 case 'd': 393 case 'i': 394 flags |= SIGN; 395 fallthrough; 396 case 'u': 397 base = 10; 398 break; 399 400 default: 401 *str++ = '%'; 402 if (*fmt) 403 *str++ = *fmt; 404 else 405 --fmt; 406 continue; 407 } 408 if (*fmt == 'p') { 409 num = (unsigned long)va_arg(args, void *); 410 } else { 411 num = get_number(flags & SIGN, qualifier, &args); 412 } 413 str = number(str, num, base, field_width, precision, flags); 414 } 415 *str = '\0'; 416 417 va_end(args); 418 419 return str - buf; 420 } 421 422 int sprintf(char *buf, const char *fmt, ...) 423 { 424 va_list args; 425 int i; 426 427 va_start(args, fmt); 428 i = vsprintf(buf, fmt, args); 429 va_end(args); 430 return i; 431 } 432