4 * Copyright (C) 1991, 1992 Linus Torvalds
7 /* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
9 * Wirzenius wrote this portably, Torvalds fucked it up :-)
13 #include <linux/types.h>
14 #include <linux/string.h>
15 #include <linux/ctype.h>
16 #include <asm-generic/div64.h>
22 unsigned long simple_strtoul(const char *cp
,char **endp
,unsigned int base
)
24 unsigned long result
= 0,value
;
28 if ((*cp
== 'x') && isxdigit(cp
[1])) {
39 while (isxdigit(*cp
) && (value
= isdigit(*cp
) ? *cp
-'0' : (islower(*cp
)
40 ? toupper(*cp
) : *cp
)-'A'+10) < base
) {
41 result
= result
*base
+ value
;
48 EXPORT_SYMBOL(simple_strtoul
);
50 long simple_strtol(const char *cp
,char **endp
,unsigned int base
)
53 return -simple_strtoul(cp
+1,endp
,base
);
54 return simple_strtoul(cp
,endp
,base
);
56 EXPORT_SYMBOL(simple_strtol
);
58 #ifdef CFG_64BIT_STRTOUL
59 unsigned long long simple_strtoull (const char *cp
, char **endp
, unsigned int base
)
61 unsigned long long result
= 0, value
;
65 if ((*cp
== 'x') && isxdigit (cp
[1])) {
76 while (isxdigit (*cp
) && (value
= isdigit (*cp
)
78 : (islower (*cp
) ? toupper (*cp
) : *cp
) - 'A' + 10) < base
) {
79 result
= result
* base
+ value
;
86 #endif /* CFG_64BIT_STRTOUL */
88 /* we use this so that we can do without the ctype library */
89 #define is_digit(c) ((c) >= '0' && (c) <= '9')
91 static int skip_atoi(const char **s
)
96 i
= i
*10 + *((*s
)++) - '0';
100 #define ZEROPAD 1 /* pad with zero */
101 #define SIGN 2 /* unsigned/signed long */
102 #define PLUS 4 /* show plus */
103 #define SPACE 8 /* space if plus */
104 #define LEFT 16 /* left justified */
105 #define SMALL 32 /* Must be 32 == 0x20 */
106 #define SPECIAL 64 /* 0x */
108 static char *number(char *buf
, char *end
, unsigned long long num
, int base
, int size
, int precision
, int type
)
110 /* we are called with base 8, 10 or 16, only, thus don't need "G..." */
111 static const char digits
[16] = "0123456789ABCDEF"; /* "GHIJKLMNOPQRSTUVWXYZ"; */
116 int need_pfx
= ((type
& SPECIAL
) && base
!= 10);
119 /* locase = 0 or 0x20. ORing digits or letters with 'locase'
120 * produces same digits or (maybe lowercased) letters */
121 locase
= (type
& SMALL
);
126 if ((signed long long) num
< 0) {
128 num
= - (signed long long) num
;
130 } else if (type
& PLUS
) {
133 } else if (type
& SPACE
) {
143 /* generate full string in tmp[], in reverse order */
148 tmp
[i
++] = (digits
[do_div(num
,base
)] | locase
);
151 /* printing 100 using %2d gives "100", not "00" */
155 if (!(type
& (ZEROPAD
+LEFT
))) {
168 /* "0x" / "0" prefix */
175 *buf
= ('X' | locase
);
179 /* zero or space padding */
180 if (!(type
& LEFT
)) {
181 char c
= (type
& ZEROPAD
) ? '0' : ' ';
182 while (--size
>= 0) {
188 /* hmm even more zero padding? */
189 while (i
<= --precision
) {
194 /* actual digits of result */
200 /* trailing space padding */
201 while (--size
>= 0) {
210 #define PAGE_SIZE 4096
213 static char *string(char *buf
, char *end
, char *s
, int field_width
, int precision
, int flags
)
217 if ((unsigned long)s
< PAGE_SIZE
)
220 len
= strnlen(s
, precision
);
222 if (!(flags
& LEFT
)) {
223 while (len
< field_width
--) {
229 for (i
= 0; i
< len
; ++i
) {
234 while (len
< field_width
--) {
242 static char *symbol_string(char *buf
, char *end
, void *ptr
, int field_width
, int precision
, int flags
)
244 unsigned long value
= (unsigned long) ptr
;
245 #ifdef CONFIG_KALLSYMS
246 char sym
[KSYM_SYMBOL_LEN
];
247 sprint_symbol(sym
, value
);
248 return string(buf
, end
, sym
, field_width
, precision
, flags
);
250 field_width
= 2*sizeof(void *);
251 flags
|= SPECIAL
| SMALL
| ZEROPAD
;
252 return number(buf
, end
, value
, 16, field_width
, precision
, flags
);
257 * Show a '%p' thing. A kernel extension is that the '%p' is followed
258 * by an extra set of alphanumeric characters that are extended format
261 * Right now we handle:
263 * - 'S' For symbolic direct pointers
265 * Note: The difference between 'S' and 'F' is that on ia64 and ppc64
266 * function pointers are really function descriptors, which contain a
267 * pointer to the real address.
269 static char *pointer(const char *fmt
, char *buf
, char *end
, void *ptr
, int field_width
, int precision
, int flags
)
273 return symbol_string(buf
, end
, ptr
, field_width
, precision
, flags
);
276 if (field_width
== -1) {
277 field_width
= 2*sizeof(void *);
280 return number(buf
, end
, (unsigned long) ptr
, 16, field_width
, precision
, flags
);
284 * vsnprintf - Format a string and place it in a buffer
285 * @buf: The buffer to place the result into
286 * @size: The size of the buffer, including the trailing null space
287 * @fmt: The format string to use
288 * @args: Arguments for the format string
290 * This function follows C99 vsnprintf, but has some extensions:
291 * %pS output the name of a text symbol
292 * %pF output the name of a function pointer
293 * %pR output the address range in a struct resource
295 * The return value is the number of characters which would
296 * be generated for the given input, excluding the trailing
297 * '\0', as per ISO C99. If you want to have the exact
298 * number of characters written into @buf as return value
299 * (not including the trailing '\0'), use vscnprintf(). If the
300 * return is greater than or equal to @size, the resulting
301 * string is truncated.
303 * Call this function if you are already dealing with a va_list.
304 * You probably want snprintf() instead.
306 int vsnprintf(char *buf
, size_t size
, const char *fmt
, va_list args
)
308 unsigned long long num
;
312 int flags
; /* flags to number() */
314 int field_width
; /* width of output field */
315 int precision
; /* min. # of digits for integers; max
316 number of chars for from string */
317 int qualifier
; /* 'h', 'l', or 'L' for integer fields */
318 /* 'z' support added 23/7/1999 S.H. */
319 /* 'z' changed to 'Z' --davidm 1/25/99 */
320 /* 't' added for ptrdiff_t */
322 /* Reject out-of-range values early. Large positive sizes are
323 used for unknown buffer sizes. */
324 if (unlikely((int) size
< 0))
330 /* Make sure end is always >= buf */
336 for (; *fmt
; ++fmt
) {
347 ++fmt
; /* this also skips first '%' */
349 case '-': flags
|= LEFT
; goto repeat
;
350 case '+': flags
|= PLUS
; goto repeat
;
351 case ' ': flags
|= SPACE
; goto repeat
;
352 case '#': flags
|= SPECIAL
; goto repeat
;
353 case '0': flags
|= ZEROPAD
; goto repeat
;
356 /* get field width */
359 field_width
= skip_atoi(&fmt
);
360 else if (*fmt
== '*') {
362 /* it's the next argument */
363 field_width
= va_arg(args
, int);
364 if (field_width
< 0) {
365 field_width
= -field_width
;
370 /* get the precision */
375 precision
= skip_atoi(&fmt
);
376 else if (*fmt
== '*') {
378 /* it's the next argument */
379 precision
= va_arg(args
, int);
385 /* get the conversion qualifier */
387 if (*fmt
== 'h' || *fmt
== 'l' || *fmt
== 'L' ||
388 *fmt
=='Z' || *fmt
== 'z' || *fmt
== 't') {
391 if (qualifier
== 'l' && *fmt
== 'l') {
402 if (!(flags
& LEFT
)) {
403 while (--field_width
> 0) {
409 c
= (unsigned char) va_arg(args
, int);
413 while (--field_width
> 0) {
421 str
= string(str
, end
, va_arg(args
, char *), field_width
, precision
, flags
);
425 str
= pointer(fmt
+1, str
, end
,
426 va_arg(args
, void *),
427 field_width
, precision
, flags
);
428 /* Skip all alphanumeric pointer suffixes */
429 while (isalnum(fmt
[1]))
435 * What does C99 say about the overflow case here? */
436 if (qualifier
== 'l') {
437 long * ip
= va_arg(args
, long *);
439 } else if (qualifier
== 'Z' || qualifier
== 'z') {
440 size_t * ip
= va_arg(args
, size_t *);
443 int * ip
= va_arg(args
, int *);
454 /* integer number formats - set up the flags and "break" */
484 if (qualifier
== 'L')
485 num
= va_arg(args
, long long);
486 else if (qualifier
== 'l') {
487 num
= va_arg(args
, unsigned long);
489 num
= (signed long) num
;
490 } else if (qualifier
== 'Z' || qualifier
== 'z') {
491 num
= va_arg(args
, size_t);
492 } else if (qualifier
== 't') {
493 num
= va_arg(args
, ptrdiff_t);
494 } else if (qualifier
== 'h') {
495 num
= (unsigned short) va_arg(args
, int);
497 num
= (signed short) num
;
499 num
= va_arg(args
, unsigned int);
501 num
= (signed int) num
;
503 str
= number(str
, end
, num
, base
,
504 field_width
, precision
, flags
);
512 /* the trailing null byte doesn't count towards the total */
515 EXPORT_SYMBOL(vsnprintf
);
518 * vscnprintf - Format a string and place it in a buffer
519 * @buf: The buffer to place the result into
520 * @size: The size of the buffer, including the trailing null space
521 * @fmt: The format string to use
522 * @args: Arguments for the format string
524 * The return value is the number of characters which have been written into
525 * the @buf not including the trailing '\0'. If @size is <= 0 the function
528 * Call this function if you are already dealing with a va_list.
529 * You probably want scnprintf() instead.
531 * See the vsnprintf() documentation for format string extensions over C99.
533 int vscnprintf(char *buf
, size_t size
, const char *fmt
, va_list args
)
537 i
=vsnprintf(buf
,size
,fmt
,args
);
538 return (i
>= size
) ? (size
- 1) : i
;
540 EXPORT_SYMBOL(vscnprintf
);
543 * vsprintf - Format a string and place it in a buffer
544 * @buf: The buffer to place the result into
545 * @fmt: The format string to use
546 * @args: Arguments for the format string
548 * The function returns the number of characters written
549 * into @buf. Use vsnprintf() or vscnprintf() in order to avoid
552 * Call this function if you are already dealing with a va_list.
553 * You probably want sprintf() instead.
555 * See the vsnprintf() documentation for format string extensions over C99.
557 int vsprintf(char *buf
, const char *fmt
, va_list args
)
559 return vsnprintf(buf
, INT_MAX
, fmt
, args
);
561 EXPORT_SYMBOL(vsprintf
);
563 int sprintf(char * buf
, const char *fmt
, ...)
569 i
=vsprintf(buf
,fmt
,args
);
573 EXPORT_SYMBOL(sprintf
);
575 int snprintf(char * buf
, size_t size
, const char *fmt
, ...)
581 i
= vsnprintf(buf
, size
, fmt
, args
);
585 EXPORT_SYMBOL(sprintf
);
587 /* Simplified asprintf. */
588 char *vasprintf(const char *fmt
, va_list ap
)
595 len
= vsnprintf(NULL
, 0, fmt
, aq
);
602 vsnprintf(p
, len
+ 1, fmt
, ap
);
606 EXPORT_SYMBOL(vasprintf
);
608 char *asprintf(const char *fmt
, ...)
614 p
= vasprintf(fmt
, ap
);
619 EXPORT_SYMBOL(asprintf
);
621 void __noreturn
panic(const char *fmt
, ...)
628 #if defined (CONFIG_PANIC_HANG)
631 udelay(100000); /* allow messages to go out */
635 EXPORT_SYMBOL(panic
);