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) {
209 #define PAGE_SIZE 4096
211 static char *string(char *buf
, char *end
, char *s
, int field_width
, int precision
, int flags
)
215 if ((unsigned long)s
< PAGE_SIZE
)
218 len
= strnlen(s
, precision
);
220 if (!(flags
& LEFT
)) {
221 while (len
< field_width
--) {
227 for (i
= 0; i
< len
; ++i
) {
232 while (len
< field_width
--) {
240 static char *symbol_string(char *buf
, char *end
, void *ptr
, int field_width
, int precision
, int flags
)
242 unsigned long value
= (unsigned long) ptr
;
243 #ifdef CONFIG_KALLSYMS
244 char sym
[KSYM_SYMBOL_LEN
];
245 sprint_symbol(sym
, value
);
246 return string(buf
, end
, sym
, field_width
, precision
, flags
);
248 field_width
= 2*sizeof(void *);
249 flags
|= SPECIAL
| SMALL
| ZEROPAD
;
250 return number(buf
, end
, value
, 16, field_width
, precision
, flags
);
255 * Show a '%p' thing. A kernel extension is that the '%p' is followed
256 * by an extra set of alphanumeric characters that are extended format
259 * Right now we handle:
261 * - 'S' For symbolic direct pointers
263 * Note: The difference between 'S' and 'F' is that on ia64 and ppc64
264 * function pointers are really function descriptors, which contain a
265 * pointer to the real address.
267 static char *pointer(const char *fmt
, char *buf
, char *end
, void *ptr
, int field_width
, int precision
, int flags
)
271 return symbol_string(buf
, end
, ptr
, field_width
, precision
, flags
);
274 if (field_width
== -1) {
275 field_width
= 2*sizeof(void *);
278 return number(buf
, end
, (unsigned long) ptr
, 16, field_width
, precision
, flags
);
282 * vsnprintf - Format a string and place it in a buffer
283 * @buf: The buffer to place the result into
284 * @size: The size of the buffer, including the trailing null space
285 * @fmt: The format string to use
286 * @args: Arguments for the format string
288 * This function follows C99 vsnprintf, but has some extensions:
289 * %pS output the name of a text symbol
290 * %pF output the name of a function pointer
291 * %pR output the address range in a struct resource
293 * The return value is the number of characters which would
294 * be generated for the given input, excluding the trailing
295 * '\0', as per ISO C99. If you want to have the exact
296 * number of characters written into @buf as return value
297 * (not including the trailing '\0'), use vscnprintf(). If the
298 * return is greater than or equal to @size, the resulting
299 * string is truncated.
301 * Call this function if you are already dealing with a va_list.
302 * You probably want snprintf() instead.
304 int vsnprintf(char *buf
, size_t size
, const char *fmt
, va_list args
)
306 unsigned long long num
;
310 int flags
; /* flags to number() */
312 int field_width
; /* width of output field */
313 int precision
; /* min. # of digits for integers; max
314 number of chars for from string */
315 int qualifier
; /* 'h', 'l', or 'L' for integer fields */
316 /* 'z' support added 23/7/1999 S.H. */
317 /* 'z' changed to 'Z' --davidm 1/25/99 */
318 /* 't' added for ptrdiff_t */
320 /* Reject out-of-range values early. Large positive sizes are
321 used for unknown buffer sizes. */
322 if (unlikely((int) size
< 0))
328 /* Make sure end is always >= buf */
334 for (; *fmt
; ++fmt
) {
345 ++fmt
; /* this also skips first '%' */
347 case '-': flags
|= LEFT
; goto repeat
;
348 case '+': flags
|= PLUS
; goto repeat
;
349 case ' ': flags
|= SPACE
; goto repeat
;
350 case '#': flags
|= SPECIAL
; goto repeat
;
351 case '0': flags
|= ZEROPAD
; goto repeat
;
354 /* get field width */
357 field_width
= skip_atoi(&fmt
);
358 else if (*fmt
== '*') {
360 /* it's the next argument */
361 field_width
= va_arg(args
, int);
362 if (field_width
< 0) {
363 field_width
= -field_width
;
368 /* get the precision */
373 precision
= skip_atoi(&fmt
);
374 else if (*fmt
== '*') {
376 /* it's the next argument */
377 precision
= va_arg(args
, int);
383 /* get the conversion qualifier */
385 if (*fmt
== 'h' || *fmt
== 'l' || *fmt
== 'L' ||
386 *fmt
=='Z' || *fmt
== 'z' || *fmt
== 't') {
389 if (qualifier
== 'l' && *fmt
== 'l') {
400 if (!(flags
& LEFT
)) {
401 while (--field_width
> 0) {
407 c
= (unsigned char) va_arg(args
, int);
411 while (--field_width
> 0) {
419 str
= string(str
, end
, va_arg(args
, char *), field_width
, precision
, flags
);
423 str
= pointer(fmt
+1, str
, end
,
424 va_arg(args
, void *),
425 field_width
, precision
, flags
);
426 /* Skip all alphanumeric pointer suffixes */
427 while (isalnum(fmt
[1]))
433 * What does C99 say about the overflow case here? */
434 if (qualifier
== 'l') {
435 long * ip
= va_arg(args
, long *);
437 } else if (qualifier
== 'Z' || qualifier
== 'z') {
438 size_t * ip
= va_arg(args
, size_t *);
441 int * ip
= va_arg(args
, int *);
452 /* integer number formats - set up the flags and "break" */
482 if (qualifier
== 'L')
483 num
= va_arg(args
, long long);
484 else if (qualifier
== 'l') {
485 num
= va_arg(args
, unsigned long);
487 num
= (signed long) num
;
488 } else if (qualifier
== 'Z' || qualifier
== 'z') {
489 num
= va_arg(args
, size_t);
490 } else if (qualifier
== 't') {
491 num
= va_arg(args
, ptrdiff_t);
492 } else if (qualifier
== 'h') {
493 num
= (unsigned short) va_arg(args
, int);
495 num
= (signed short) num
;
497 num
= va_arg(args
, unsigned int);
499 num
= (signed int) num
;
501 str
= number(str
, end
, num
, base
,
502 field_width
, precision
, flags
);
510 /* the trailing null byte doesn't count towards the total */
513 EXPORT_SYMBOL(vsnprintf
);
516 * vsprintf - Format a string and place it in a buffer
517 * @buf: The buffer to place the result into
518 * @fmt: The format string to use
519 * @args: Arguments for the format string
521 * The function returns the number of characters written
522 * into @buf. Use vsnprintf() or vscnprintf() in order to avoid
525 * Call this function if you are already dealing with a va_list.
526 * You probably want sprintf() instead.
528 * See the vsnprintf() documentation for format string extensions over C99.
530 int vsprintf(char *buf
, const char *fmt
, va_list args
)
532 return vsnprintf(buf
, INT_MAX
, fmt
, args
);
534 EXPORT_SYMBOL(vsprintf
);
536 int sprintf(char * buf
, const char *fmt
, ...)
542 i
=vsprintf(buf
,fmt
,args
);
546 EXPORT_SYMBOL(sprintf
);
548 /* Simplified asprintf. */
549 char *vasprintf(const char *fmt
, va_list ap
)
556 len
= vsnprintf(NULL
, 0, fmt
, aq
);
563 vsnprintf(p
, len
+ 1, fmt
, ap
);
567 EXPORT_SYMBOL(vasprintf
);
569 char *asprintf(const char *fmt
, ...)
575 p
= vasprintf(fmt
, ap
);
580 EXPORT_SYMBOL(asprintf
);
582 void panic(const char *fmt
, ...)
589 #if defined (CONFIG_PANIC_HANG)
592 udelay(100000); /* allow messages to go out */
596 EXPORT_SYMBOL(panic
);