Subversion Repositories Kolibri OS

Rev

Rev 1408 | Rev 1871 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1408 Rev 1869
Line 1... Line 1...
1
/*
1
/*
-
 
2
 *  linux/lib/vsprintf.c
-
 
3
 *
-
 
4
 *  Copyright (C) 1991, 1992  Linus Torvalds
-
 
5
 */
-
 
6
 
2
 * vsprintf - print formatted output without ellipsis on an array
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 
-
 
14
 * - changed to provide snprintf and vsnprintf functions
-
 
15
 * So Feb  1 16:51:32 CET 2004 Juergen Quade 
-
 
16
 * - scnprintf and vscnprintf
3
 */
17
 */
4
/* $Header$ */
-
 
Line 5... Line -...
5
 
-
 
6
#include    "stdio.h"
18
 
-
 
19
#include 
7
#include   
20
#include 
-
 
21
#include 
-
 
22
#include 
-
 
23
#include 
-
 
24
#include 
-
 
25
#include 
-
 
26
#include 
8
#include   
27
 
-
 
28
#include 
-
 
29
 
-
 
30
struct va_format {
-
 
31
    const char *fmt;
-
 
32
    va_list *va;
-
 
33
};
-
 
34
 
-
 
35
#ifndef dereference_function_descriptor
-
 
36
#define dereference_function_descriptor(p) (p)
-
 
37
#endif
-
 
38
 
-
 
39
const char hex_asc[] = "0123456789abcdef";
-
 
40
 
-
 
41
/* Works only for digits and letters, but small and fast */
-
 
42
#define TOLOWER(x) ((x) | 0x20)
-
 
43
 
-
 
44
static unsigned int simple_guess_base(const char *cp)
-
 
45
{
-
 
46
	if (cp[0] == '0') {
-
 
47
		if (TOLOWER(cp[1]) == 'x' && isxdigit(cp[2]))
-
 
48
			return 16;
-
 
49
		else
-
 
50
			return 8;
-
 
51
	} else {
-
 
52
		return 10;
-
 
53
	}
-
 
54
}
-
 
55
 
-
 
56
/**
-
 
57
 * simple_strtoull - convert a string to an unsigned long long
-
 
58
 * @cp: The start of the string
-
 
59
 * @endp: A pointer to the end of the parsed string will be placed here
-
 
60
 * @base: The number base to use
-
 
61
 */
-
 
62
unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base)
-
 
63
{
Line 9... Line 64...
9
#include	"loc_incl.h"
64
	unsigned long long result = 0;
10
 
65
 
Line -... Line 66...
-
 
66
	if (!base)
-
 
67
		base = simple_guess_base(cp);
-
 
68
 
-
 
69
	if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x')
-
 
70
		cp += 2;
-
 
71
 
-
 
72
	while (isxdigit(*cp)) {
-
 
73
		unsigned int value;
-
 
74
 
-
 
75
		value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10;
-
 
76
		if (value >= base)
-
 
77
			break;
-
 
78
		result = result * base + value;
-
 
79
		cp++;
-
 
80
	}
-
 
81
	if (endp)
-
 
82
		*endp = (char *)cp;
-
 
83
 
-
 
84
	return result;
-
 
85
}
-
 
86
EXPORT_SYMBOL(simple_strtoull);
-
 
87
 
-
 
88
/**
-
 
89
 * simple_strtoul - convert a string to an unsigned long
-
 
90
 * @cp: The start of the string
-
 
91
 * @endp: A pointer to the end of the parsed string will be placed here
-
 
92
 * @base: The number base to use
-
 
93
 */
-
 
94
unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base)
-
 
95
{
-
 
96
	return simple_strtoull(cp, endp, base);
-
 
97
}
-
 
98
EXPORT_SYMBOL(simple_strtoul);
-
 
99
 
-
 
100
/**
-
 
101
 * simple_strtol - convert a string to a signed long
11
#define putc(c, p)  (--(p)->_count >= 0 ? \
102
 * @cp: The start of the string
12
                    (int) (*(p)->_ptr++ = (c)) : EOF)
103
 * @endp: A pointer to the end of the parsed string will be placed here
13
 
104
 * @base: The number base to use
14
int
105
 */
15
vsnprintf(char *s, unsigned n, const char *format, va_list arg)
106
long simple_strtol(const char *cp, char **endp, unsigned int base)
Line 16... Line -...
16
{
-
 
17
	int retval;
-
 
18
	FILE tmp_stream;
-
 
19
 
107
{
-
 
108
	if (*cp == '-')
20
	tmp_stream._fd     = -1;
109
		return -simple_strtoul(cp + 1, endp, base);
Line -... Line 110...
-
 
110
 
-
 
111
	return simple_strtoul(cp, endp, base);
21
	tmp_stream._flags  = _IOWRITE + _IONBF + _IOWRITING;
112
}
-
 
113
EXPORT_SYMBOL(simple_strtol);
22
	tmp_stream._buf    = (unsigned char *) s;
114
 
-
 
115
/**
-
 
116
 * simple_strtoll - convert a string to a signed long long
-
 
117
 * @cp: The start of the string
23
	tmp_stream._ptr    = (unsigned char *) s;
118
 * @endp: A pointer to the end of the parsed string will be placed here
-
 
119
 * @base: The number base to use
Line 24... Line 120...
24
	tmp_stream._count  = n-1;
120
 */
25
 
121
long long simple_strtoll(const char *cp, char **endp, unsigned int base)
-
 
122
{
Line 26... Line 123...
26
	retval = _doprnt(format, arg, &tmp_stream);
123
	if (*cp == '-')
-
 
124
		return -simple_strtoull(cp + 1, endp, base);
-
 
125
 
-
 
126
	return simple_strtoull(cp, endp, base);
-
 
127
}
-
 
128
EXPORT_SYMBOL(simple_strtoll);
-
 
129
 
-
 
130
/**
-
 
131
 * strict_strtoul - convert a string to an unsigned long strictly
-
 
132
 * @cp: The string to be converted
-
 
133
 * @base: The number base to use
-
 
134
 * @res: The converted result value
-
 
135
 *
-
 
136
 * strict_strtoul converts a string to an unsigned long only if the
-
 
137
 * string is really an unsigned long string, any string containing
-
 
138
 * any invalid char at the tail will be rejected and -EINVAL is returned,
-
 
139
 * only a newline char at the tail is acceptible because people generally
-
 
140
 * change a module parameter in the following way:
-
 
141
 *
-
 
142
 * 	echo 1024 > /sys/module/e1000/parameters/copybreak
27
	tmp_stream._count  = 1;
143
 *
-
 
144
 * echo will append a newline to the tail.
-
 
145
 *
28
	putc('\0',&tmp_stream);
146
 * It returns 0 if conversion is successful and *res is set to the converted
-
 
147
 * value, otherwise it returns -EINVAL and *res is set to 0.
-
 
148
 *
-
 
149
 * simple_strtoul just ignores the successive invalid characters and
-
 
150
 * return the converted value of prefix part of the string.
-
 
151
 */
-
 
152
int strict_strtoul(const char *cp, unsigned int base, unsigned long *res)
-
 
153
{
29
 
154
	char *tail;
-
 
155
	unsigned long val;
-
 
156
 
-
 
157
	*res = 0;
-
 
158
	if (!*cp)
-
 
159
		return -EINVAL;
-
 
160
 
-
 
161
	val = simple_strtoul(cp, &tail, base);
-
 
162
	if (tail == cp)
-
 
163
		return -EINVAL;
-
 
164
 
-
 
165
	if ((tail[0] == '\0') || (tail[0] == '\n' && tail[1] == '\0')) {
-
 
166
		*res = val;
-
 
167
		return 0;
-
 
168
	}
-
 
169
 
-
 
170
	return -EINVAL;
-
 
171
}
-
 
172
EXPORT_SYMBOL(strict_strtoul);
-
 
173
 
-
 
174
/**
-
 
175
 * strict_strtol - convert a string to a long strictly
-
 
176
 * @cp: The string to be converted
-
 
177
 * @base: The number base to use
-
 
178
 * @res: The converted result value
-
 
179
 *
-
 
180
 * strict_strtol is similiar to strict_strtoul, but it allows the first
-
 
181
 * character of a string is '-'.
-
 
182
 *
-
 
183
 * It returns 0 if conversion is successful and *res is set to the converted
-
 
184
 * value, otherwise it returns -EINVAL and *res is set to 0.
-
 
185
 */
-
 
186
int strict_strtol(const char *cp, unsigned int base, long *res)
-
 
187
{
-
 
188
	int ret;
-
 
189
	if (*cp == '-') {
-
 
190
		ret = strict_strtoul(cp + 1, base, (unsigned long *)res);
-
 
191
		if (!ret)
-
 
192
			*res = -(*res);
-
 
193
	} else {
-
 
194
		ret = strict_strtoul(cp, base, (unsigned long *)res);
-
 
195
	}
-
 
196
 
-
 
197
	return ret;
-
 
198
}
-
 
199
EXPORT_SYMBOL(strict_strtol);
-
 
200
 
-
 
201
/**
-
 
202
 * strict_strtoull - convert a string to an unsigned long long strictly
-
 
203
 * @cp: The string to be converted
-
 
204
 * @base: The number base to use
-
 
205
 * @res: The converted result value
-
 
206
 *
-
 
207
 * strict_strtoull converts a string to an unsigned long long only if the
-
 
208
 * string is really an unsigned long long string, any string containing
-
 
209
 * any invalid char at the tail will be rejected and -EINVAL is returned,
-
 
210
 * only a newline char at the tail is acceptible because people generally
-
 
211
 * change a module parameter in the following way:
-
 
212
 *
-
 
213
 * 	echo 1024 > /sys/module/e1000/parameters/copybreak
-
 
214
 *
-
 
215
 * echo will append a newline to the tail of the string.
-
 
216
 *
-
 
217
 * It returns 0 if conversion is successful and *res is set to the converted
-
 
218
 * value, otherwise it returns -EINVAL and *res is set to 0.
-
 
219
 *
-
 
220
 * simple_strtoull just ignores the successive invalid characters and
-
 
221
 * return the converted value of prefix part of the string.
-
 
222
 */
-
 
223
int strict_strtoull(const char *cp, unsigned int base, unsigned long long *res)
-
 
224
{
-
 
225
	char *tail;
-
 
226
	unsigned long long val;
-
 
227
 
-
 
228
	*res = 0;
-
 
229
	if (!*cp)
-
 
230
		return -EINVAL;
-
 
231
 
-
 
232
	val = simple_strtoull(cp, &tail, base);
-
 
233
	if (tail == cp)
-
 
234
		return -EINVAL;
-
 
235
	if ((tail[0] == '\0') || (tail[0] == '\n' && tail[1] == '\0')) {
-
 
236
		*res = val;
-
 
237
		return 0;
-
 
238
	}
-
 
239
 
-
 
240
	return -EINVAL;
-
 
241
}
-
 
242
EXPORT_SYMBOL(strict_strtoull);
-
 
243
 
-
 
244
/**
-
 
245
 * strict_strtoll - convert a string to a long long strictly
-
 
246
 * @cp: The string to be converted
-
 
247
 * @base: The number base to use
-
 
248
 * @res: The converted result value
-
 
249
 *
-
 
250
 * strict_strtoll is similiar to strict_strtoull, but it allows the first
-
 
251
 * character of a string is '-'.
-
 
252
 *
-
 
253
 * It returns 0 if conversion is successful and *res is set to the converted
-
 
254
 * value, otherwise it returns -EINVAL and *res is set to 0.
-
 
255
 */
-
 
256
int strict_strtoll(const char *cp, unsigned int base, long long *res)
-
 
257
{
-
 
258
	int ret;
-
 
259
	if (*cp == '-') {
-
 
260
		ret = strict_strtoull(cp + 1, base, (unsigned long long *)res);
-
 
261
		if (!ret)
-
 
262
			*res = -(*res);
-
 
263
	} else {
-
 
264
		ret = strict_strtoull(cp, base, (unsigned long long *)res);
-
 
265
	}
-
 
266
 
-
 
267
	return ret;
-
 
268
}
-
 
269
EXPORT_SYMBOL(strict_strtoll);
-
 
270
 
-
 
271
static noinline_for_stack
-
 
272
int skip_atoi(const char **s)
-
 
273
{
-
 
274
	int i = 0;
-
 
275
 
-
 
276
	while (isdigit(**s))
-
 
277
		i = i*10 + *((*s)++) - '0';
-
 
278
 
-
 
279
	return i;
-
 
280
}
-
 
281
 
-
 
282
/* Decimal conversion is by far the most typical, and is used
-
 
283
 * for /proc and /sys data. This directly impacts e.g. top performance
-
 
284
 * with many processes running. We optimize it for speed
-
 
285
 * using code from
-
 
286
 * http://www.cs.uiowa.edu/~jones/bcd/decimal.html
-
 
287
 * (with permission from the author, Douglas W. Jones). */
-
 
288
 
-
 
289
/* Formats correctly any integer in [0,99999].
-
 
290
 * Outputs from one to five digits depending on input.
-
 
291
 * On i386 gcc 4.1.2 -O2: ~250 bytes of code. */
-
 
292
static noinline_for_stack
-
 
293
char *put_dec_trunc(char *buf, unsigned q)
-
 
294
{
-
 
295
	unsigned d3, d2, d1, d0;
-
 
296
	d1 = (q>>4) & 0xf;
-
 
297
	d2 = (q>>8) & 0xf;
-
 
298
	d3 = (q>>12);
-
 
299
 
-
 
300
	d0 = 6*(d3 + d2 + d1) + (q & 0xf);
-
 
301
	q = (d0 * 0xcd) >> 11;
-
 
302
	d0 = d0 - 10*q;
-
 
303
	*buf++ = d0 + '0'; /* least significant digit */
-
 
304
	d1 = q + 9*d3 + 5*d2 + d1;
-
 
305
	if (d1 != 0) {
-
 
306
		q = (d1 * 0xcd) >> 11;
-
 
307
		d1 = d1 - 10*q;
-
 
308
		*buf++ = d1 + '0'; /* next digit */
-
 
309
 
-
 
310
		d2 = q + 2*d2;
-
 
311
		if ((d2 != 0) || (d3 != 0)) {
-
 
312
			q = (d2 * 0xd) >> 7;
-
 
313
			d2 = d2 - 10*q;
-
 
314
			*buf++ = d2 + '0'; /* next digit */
-
 
315
 
-
 
316
			d3 = q + 4*d3;
30
	return retval;
317
			if (d3 != 0) {
-
 
318
				q = (d3 * 0xcd) >> 11;
-
 
319
				d3 = d3 - 10*q;
-
 
320
				*buf++ = d3 + '0';  /* next digit */
-
 
321
				if (q != 0)
-
 
322
					*buf++ = q + '0'; /* most sign. digit */
-
 
323
			}
-
 
324
		}
-
 
325
	}
-
 
326
 
-
 
327
	return buf;
-
 
328
}
-
 
329
/* Same with if's removed. Always emits five digits */
-
 
330
static noinline_for_stack
-
 
331
char *put_dec_full(char *buf, unsigned q)
-
 
332
{
-
 
333
	/* BTW, if q is in [0,9999], 8-bit ints will be enough, */
-
 
334
	/* but anyway, gcc produces better code with full-sized ints */
-
 
335
	unsigned d3, d2, d1, d0;
-
 
336
	d1 = (q>>4) & 0xf;
-
 
337
	d2 = (q>>8) & 0xf;
-
 
338
	d3 = (q>>12);
-
 
339
 
-
 
340
	/*
-
 
341
	 * Possible ways to approx. divide by 10
-
 
342
	 * gcc -O2 replaces multiply with shifts and adds
-
 
343
	 * (x * 0xcd) >> 11: 11001101 - shorter code than * 0x67 (on i386)
-
 
344
	 * (x * 0x67) >> 10:  1100111
-
 
345
	 * (x * 0x34) >> 9:    110100 - same
-
 
346
	 * (x * 0x1a) >> 8:     11010 - same
-
 
347
	 * (x * 0x0d) >> 7:      1101 - same, shortest code (on i386)
-
 
348
	 */
-
 
349
	d0 = 6*(d3 + d2 + d1) + (q & 0xf);
-
 
350
	q = (d0 * 0xcd) >> 11;
-
 
351
	d0 = d0 - 10*q;
-
 
352
	*buf++ = d0 + '0';
-
 
353
	d1 = q + 9*d3 + 5*d2 + d1;
-
 
354
		q = (d1 * 0xcd) >> 11;
-
 
355
		d1 = d1 - 10*q;
-
 
356
		*buf++ = d1 + '0';
-
 
357
 
-
 
358
		d2 = q + 2*d2;
-
 
359
			q = (d2 * 0xd) >> 7;
-
 
360
			d2 = d2 - 10*q;
-
 
361
			*buf++ = d2 + '0';
-
 
362
 
-
 
363
			d3 = q + 4*d3;
-
 
364
				q = (d3 * 0xcd) >> 11; /* - shorter code */
-
 
365
				/* q = (d3 * 0x67) >> 10; - would also work */
-
 
366
				d3 = d3 - 10*q;
-
 
367
				*buf++ = d3 + '0';
-
 
368
					*buf++ = q + '0';
-
 
369
 
-
 
370
	return buf;
-
 
371
}
-
 
372
/* No inlining helps gcc to use registers better */
-
 
373
static noinline_for_stack
-
 
374
char *put_dec(char *buf, unsigned long long num)
-
 
375
{
-
 
376
	while (1) {
-
 
377
		unsigned rem;
-
 
378
		if (num < 100000)
-
 
379
			return put_dec_trunc(buf, num);
-
 
380
		rem = do_div(num, 100000);
-
 
381
		buf = put_dec_full(buf, rem);
-
 
382
	}
-
 
383
}
-
 
384
 
-
 
385
#define ZEROPAD	1		/* pad with zero */
-
 
386
#define SIGN	2		/* unsigned/signed long */
-
 
387
#define PLUS	4		/* show plus */
-
 
388
#define SPACE	8		/* space if plus */
-
 
389
#define LEFT	16		/* left justified */
-
 
390
#define SMALL	32		/* use lowercase in hex (must be 32 == 0x20) */
-
 
391
#define SPECIAL	64		/* prefix hex with "0x", octal with "0" */
-
 
392
 
-
 
393
enum format_type {
-
 
394
	FORMAT_TYPE_NONE, /* Just a string part */
-
 
395
	FORMAT_TYPE_WIDTH,
-
 
396
	FORMAT_TYPE_PRECISION,
-
 
397
	FORMAT_TYPE_CHAR,
-
 
398
	FORMAT_TYPE_STR,
-
 
399
	FORMAT_TYPE_PTR,
-
 
400
	FORMAT_TYPE_PERCENT_CHAR,
-
 
401
	FORMAT_TYPE_INVALID,
-
 
402
	FORMAT_TYPE_LONG_LONG,
-
 
403
	FORMAT_TYPE_ULONG,
-
 
404
	FORMAT_TYPE_LONG,
-
 
405
	FORMAT_TYPE_UBYTE,
-
 
406
	FORMAT_TYPE_BYTE,
-
 
407
	FORMAT_TYPE_USHORT,
-
 
408
	FORMAT_TYPE_SHORT,
-
 
409
	FORMAT_TYPE_UINT,
-
 
410
	FORMAT_TYPE_INT,
-
 
411
	FORMAT_TYPE_NRCHARS,
-
 
412
	FORMAT_TYPE_SIZE_T,
-
 
413
	FORMAT_TYPE_PTRDIFF
-
 
414
};
-
 
415
 
-
 
416
struct printf_spec {
-
 
417
	u8	type;		/* format_type enum */
-
 
418
	u8	flags;		/* flags to number() */
-
 
419
	u8	base;		/* number base, 8, 10 or 16 only */
-
 
420
	u8	qualifier;	/* number qualifier, one of 'hHlLtzZ' */
-
 
421
	s16	field_width;	/* width of output field */
-
 
422
	s16	precision;	/* # of digits/chars */
-
 
423
};
-
 
424
 
-
 
425
static noinline_for_stack
-
 
426
char *number(char *buf, char *end, unsigned long long num,
-
 
427
	     struct printf_spec spec)
-
 
428
{
-
 
429
	/* we are called with base 8, 10 or 16, only, thus don't need "G..."  */
-
 
430
	static const char digits[16] = "0123456789ABCDEF"; /* "GHIJKLMNOPQRSTUVWXYZ"; */
-
 
431
 
-
 
432
	char tmp[66];
-
 
433
	char sign;
-
 
434
	char locase;
-
 
435
	int need_pfx = ((spec.flags & SPECIAL) && spec.base != 10);
-
 
436
	int i;
-
 
437
 
-
 
438
	/* locase = 0 or 0x20. ORing digits or letters with 'locase'
-
 
439
	 * produces same digits or (maybe lowercased) letters */
-
 
440
	locase = (spec.flags & SMALL);
-
 
441
	if (spec.flags & LEFT)
-
 
442
		spec.flags &= ~ZEROPAD;
-
 
443
	sign = 0;
-
 
444
	if (spec.flags & SIGN) {
-
 
445
		if ((signed long long)num < 0) {
-
 
446
			sign = '-';
-
 
447
			num = -(signed long long)num;
-
 
448
			spec.field_width--;
-
 
449
		} else if (spec.flags & PLUS) {
-
 
450
			sign = '+';
-
 
451
			spec.field_width--;
-
 
452
		} else if (spec.flags & SPACE) {
-
 
453
			sign = ' ';
-
 
454
			spec.field_width--;
-
 
455
		}
-
 
456
	}
-
 
457
	if (need_pfx) {
-
 
458
		spec.field_width--;
-
 
459
		if (spec.base == 16)
-
 
460
			spec.field_width--;
-
 
461
	}
-
 
462
 
-
 
463
	/* generate full string in tmp[], in reverse order */
-
 
464
	i = 0;
-
 
465
	if (num == 0)
-
 
466
		tmp[i++] = '0';
-
 
467
	/* Generic code, for any base:
-
 
468
	else do {
-
 
469
		tmp[i++] = (digits[do_div(num,base)] | locase);
-
 
470
	} while (num != 0);
-
 
471
	*/
-
 
472
	else if (spec.base != 10) { /* 8 or 16 */
-
 
473
		int mask = spec.base - 1;
-
 
474
		int shift = 3;
-
 
475
 
-
 
476
		if (spec.base == 16)
-
 
477
			shift = 4;
-
 
478
		do {
-
 
479
			tmp[i++] = (digits[((unsigned char)num) & mask] | locase);
-
 
480
			num >>= shift;
-
 
481
		} while (num);
-
 
482
	} else { /* base 10 */
-
 
483
		i = put_dec(tmp, num) - tmp;
-
 
484
	}
-
 
485
 
-
 
486
	/* printing 100 using %2d gives "100", not "00" */
-
 
487
	if (i > spec.precision)
-
 
488
		spec.precision = i;
-
 
489
	/* leading space padding */
-
 
490
	spec.field_width -= spec.precision;
-
 
491
	if (!(spec.flags & (ZEROPAD+LEFT))) {
-
 
492
		while (--spec.field_width >= 0) {
-
 
493
			if (buf < end)
-
 
494
				*buf = ' ';
-
 
495
			++buf;
-
 
496
		}
-
 
497
	}
-
 
498
	/* sign */
-
 
499
	if (sign) {
-
 
500
		if (buf < end)
-
 
501
			*buf = sign;
-
 
502
		++buf;
-
 
503
	}
-
 
504
	/* "0x" / "0" prefix */
-
 
505
	if (need_pfx) {
-
 
506
		if (buf < end)
-
 
507
			*buf = '0';
-
 
508
		++buf;
-
 
509
		if (spec.base == 16) {
-
 
510
			if (buf < end)
-
 
511
				*buf = ('X' | locase);
-
 
512
			++buf;
-
 
513
		}
-
 
514
	}
-
 
515
	/* zero or space padding */
-
 
516
	if (!(spec.flags & LEFT)) {
-
 
517
		char c = (spec.flags & ZEROPAD) ? '0' : ' ';
-
 
518
		while (--spec.field_width >= 0) {
-
 
519
			if (buf < end)
-
 
520
				*buf = c;
-
 
521
			++buf;
-
 
522
		}
-
 
523
	}
-
 
524
	/* hmm even more zero padding? */
-
 
525
	while (i <= --spec.precision) {
-
 
526
		if (buf < end)
-
 
527
			*buf = '0';
-
 
528
		++buf;
-
 
529
	}
-
 
530
	/* actual digits of result */
-
 
531
	while (--i >= 0) {
-
 
532
		if (buf < end)
-
 
533
			*buf = tmp[i];
-
 
534
		++buf;
-
 
535
	}
-
 
536
	/* trailing space padding */
-
 
537
	while (--spec.field_width >= 0) {
-
 
538
		if (buf < end)
-
 
539
			*buf = ' ';
-
 
540
		++buf;
-
 
541
	}
-
 
542
 
-
 
543
	return buf;
-
 
544
}
-
 
545
 
-
 
546
static noinline_for_stack
-
 
547
char *string(char *buf, char *end, const char *s, struct printf_spec spec)
-
 
548
{
-
 
549
	int len, i;
-
 
550
 
-
 
551
	if ((unsigned long)s < PAGE_SIZE)
-
 
552
		s = "(null)";
-
 
553
 
-
 
554
	len = strnlen(s, spec.precision);
-
 
555
 
-
 
556
	if (!(spec.flags & LEFT)) {
-
 
557
		while (len < spec.field_width--) {
-
 
558
			if (buf < end)
-
 
559
				*buf = ' ';
-
 
560
			++buf;
-
 
561
		}
-
 
562
	}
-
 
563
	for (i = 0; i < len; ++i) {
-
 
564
		if (buf < end)
-
 
565
			*buf = *s;
-
 
566
		++buf; ++s;
-
 
567
	}
-
 
568
	while (len < spec.field_width--) {
-
 
569
		if (buf < end)
-
 
570
			*buf = ' ';
-
 
571
		++buf;
-
 
572
	}
-
 
573
 
-
 
574
	return buf;
-
 
575
}
-
 
576
 
-
 
577
static noinline_for_stack
-
 
578
char *symbol_string(char *buf, char *end, void *ptr,
-
 
579
		    struct printf_spec spec, char ext)
-
 
580
{
-
 
581
	unsigned long value = (unsigned long) ptr;
-
 
582
#ifdef CONFIG_KALLSYMS
-
 
583
	char sym[KSYM_SYMBOL_LEN];
-
 
584
	if (ext != 'f' && ext != 's')
-
 
585
		sprint_symbol(sym, value);
-
 
586
	else
-
 
587
		kallsyms_lookup(value, NULL, NULL, NULL, sym);
-
 
588
 
-
 
589
	return string(buf, end, sym, spec);
-
 
590
#else
-
 
591
	spec.field_width = 2 * sizeof(void *);
-
 
592
	spec.flags |= SPECIAL | SMALL | ZEROPAD;
-
 
593
	spec.base = 16;
-
 
594
 
-
 
595
	return number(buf, end, value, spec);
-
 
596
#endif
-
 
597
}
-
 
598
 
-
 
599
static noinline_for_stack
-
 
600
char *resource_string(char *buf, char *end, struct resource *res,
-
 
601
		      struct printf_spec spec, const char *fmt)
-
 
602
{
-
 
603
#ifndef IO_RSRC_PRINTK_SIZE
-
 
604
#define IO_RSRC_PRINTK_SIZE	6
-
 
605
#endif
-
 
606
 
-
 
607
#ifndef MEM_RSRC_PRINTK_SIZE
-
 
608
#define MEM_RSRC_PRINTK_SIZE	10
-
 
609
#endif
-
 
610
	static const struct printf_spec io_spec = {
-
 
611
		.base = 16,
-
 
612
		.field_width = IO_RSRC_PRINTK_SIZE,
-
 
613
		.precision = -1,
-
 
614
		.flags = SPECIAL | SMALL | ZEROPAD,
-
 
615
	};
-
 
616
	static const struct printf_spec mem_spec = {
-
 
617
		.base = 16,
-
 
618
		.field_width = MEM_RSRC_PRINTK_SIZE,
-
 
619
		.precision = -1,
-
 
620
		.flags = SPECIAL | SMALL | ZEROPAD,
-
 
621
	};
-
 
622
	static const struct printf_spec bus_spec = {
-
 
623
		.base = 16,
-
 
624
		.field_width = 2,
-
 
625
		.precision = -1,
-
 
626
		.flags = SMALL | ZEROPAD,
-
 
627
	};
-
 
628
	static const struct printf_spec dec_spec = {
-
 
629
		.base = 10,
-
 
630
		.precision = -1,
-
 
631
		.flags = 0,
-
 
632
	};
-
 
633
	static const struct printf_spec str_spec = {
-
 
634
		.field_width = -1,
-
 
635
		.precision = 10,
-
 
636
		.flags = LEFT,
-
 
637
	};
-
 
638
	static const struct printf_spec flag_spec = {
-
 
639
		.base = 16,
-
 
640
		.precision = -1,
-
 
641
		.flags = SPECIAL | SMALL,
-
 
642
	};
-
 
643
 
-
 
644
	/* 32-bit res (sizeof==4): 10 chars in dec, 10 in hex ("0x" + 8)
-
 
645
	 * 64-bit res (sizeof==8): 20 chars in dec, 18 in hex ("0x" + 16) */
-
 
646
#define RSRC_BUF_SIZE		((2 * sizeof(resource_size_t)) + 4)
-
 
647
#define FLAG_BUF_SIZE		(2 * sizeof(res->flags))
-
 
648
#define DECODED_BUF_SIZE	sizeof("[mem - 64bit pref window disabled]")
-
 
649
#define RAW_BUF_SIZE		sizeof("[mem - flags 0x]")
-
 
650
	char sym[max(2*RSRC_BUF_SIZE + DECODED_BUF_SIZE,
-
 
651
		     2*RSRC_BUF_SIZE + FLAG_BUF_SIZE + RAW_BUF_SIZE)];
-
 
652
 
-
 
653
	char *p = sym, *pend = sym + sizeof(sym);
-
 
654
	int decode = (fmt[0] == 'R') ? 1 : 0;
-
 
655
	const struct printf_spec *specp;
-
 
656
 
-
 
657
	*p++ = '[';
-
 
658
	if (res->flags & IORESOURCE_IO) {
-
 
659
		p = string(p, pend, "io  ", str_spec);
-
 
660
		specp = &io_spec;
-
 
661
	} else if (res->flags & IORESOURCE_MEM) {
-
 
662
		p = string(p, pend, "mem ", str_spec);
-
 
663
		specp = &mem_spec;
-
 
664
	} else if (res->flags & IORESOURCE_IRQ) {
-
 
665
		p = string(p, pend, "irq ", str_spec);
-
 
666
		specp = &dec_spec;
-
 
667
	} else if (res->flags & IORESOURCE_DMA) {
-
 
668
		p = string(p, pend, "dma ", str_spec);
-
 
669
		specp = &dec_spec;
-
 
670
	} else if (res->flags & IORESOURCE_BUS) {
-
 
671
		p = string(p, pend, "bus ", str_spec);
-
 
672
		specp = &bus_spec;
-
 
673
	} else {
-
 
674
		p = string(p, pend, "??? ", str_spec);
-
 
675
		specp = &mem_spec;
-
 
676
		decode = 0;
-
 
677
	}
-
 
678
	p = number(p, pend, res->start, *specp);
-
 
679
	if (res->start != res->end) {
-
 
680
		*p++ = '-';
-
 
681
		p = number(p, pend, res->end, *specp);
-
 
682
	}
-
 
683
	if (decode) {
-
 
684
		if (res->flags & IORESOURCE_MEM_64)
-
 
685
			p = string(p, pend, " 64bit", str_spec);
-
 
686
		if (res->flags & IORESOURCE_PREFETCH)
-
 
687
			p = string(p, pend, " pref", str_spec);
-
 
688
		if (res->flags & IORESOURCE_WINDOW)
-
 
689
			p = string(p, pend, " window", str_spec);
-
 
690
		if (res->flags & IORESOURCE_DISABLED)
-
 
691
			p = string(p, pend, " disabled", str_spec);
-
 
692
	} else {
-
 
693
		p = string(p, pend, " flags ", str_spec);
-
 
694
		p = number(p, pend, res->flags, flag_spec);
-
 
695
	}
-
 
696
	*p++ = ']';
-
 
697
	*p = '\0';
-
 
698
 
-
 
699
	return string(buf, end, sym, spec);
-
 
700
}
-
 
701
 
-
 
702
static noinline_for_stack
-
 
703
char *mac_address_string(char *buf, char *end, u8 *addr,
-
 
704
			 struct printf_spec spec, const char *fmt)
-
 
705
{
-
 
706
	char mac_addr[sizeof("xx:xx:xx:xx:xx:xx")];
-
 
707
	char *p = mac_addr;
-
 
708
	int i;
-
 
709
	char separator;
-
 
710
 
-
 
711
	if (fmt[1] == 'F') {		/* FDDI canonical format */
-
 
712
		separator = '-';
-
 
713
	} else {
-
 
714
		separator = ':';
-
 
715
	}
-
 
716
 
-
 
717
	for (i = 0; i < 6; i++) {
-
 
718
		p = pack_hex_byte(p, addr[i]);
-
 
719
		if (fmt[0] == 'M' && i != 5)
-
 
720
			*p++ = separator;
-
 
721
	}
-
 
722
	*p = '\0';
-
 
723
 
-
 
724
	return string(buf, end, mac_addr, spec);
-
 
725
}
-
 
726
 
-
 
727
static noinline_for_stack
-
 
728
char *ip4_string(char *p, const u8 *addr, const char *fmt)
-
 
729
{
-
 
730
	int i;
-
 
731
	bool leading_zeros = (fmt[0] == 'i');
-
 
732
	int index;
-
 
733
	int step;
-
 
734
 
-
 
735
	switch (fmt[2]) {
-
 
736
	case 'h':
-
 
737
#ifdef __BIG_ENDIAN
-
 
738
		index = 0;
-
 
739
		step = 1;
-
 
740
#else
-
 
741
		index = 3;
-
 
742
		step = -1;
-
 
743
#endif
-
 
744
		break;
-
 
745
	case 'l':
-
 
746
		index = 3;
-
 
747
		step = -1;
-
 
748
		break;
-
 
749
	case 'n':
-
 
750
	case 'b':
-
 
751
	default:
-
 
752
		index = 0;
-
 
753
		step = 1;
-
 
754
		break;
-
 
755
	}
-
 
756
	for (i = 0; i < 4; i++) {
-
 
757
		char temp[3];	/* hold each IP quad in reverse order */
-
 
758
		int digits = put_dec_trunc(temp, addr[index]) - temp;
-
 
759
		if (leading_zeros) {
-
 
760
			if (digits < 3)
-
 
761
				*p++ = '0';
-
 
762
			if (digits < 2)
-
 
763
				*p++ = '0';
-
 
764
		}
-
 
765
		/* reverse the digits in the quad */
-
 
766
		while (digits--)
-
 
767
			*p++ = temp[digits];
-
 
768
		if (i < 3)
-
 
769
			*p++ = '.';
-
 
770
		index += step;
-
 
771
	}
-
 
772
	*p = '\0';
-
 
773
 
-
 
774
	return p;
-
 
775
}
-
 
776
 
-
 
777
 
-
 
778
static noinline_for_stack
-
 
779
char *ip4_addr_string(char *buf, char *end, const u8 *addr,
-
 
780
		      struct printf_spec spec, const char *fmt)
-
 
781
{
-
 
782
	char ip4_addr[sizeof("255.255.255.255")];
-
 
783
 
-
 
784
	ip4_string(ip4_addr, addr, fmt);
-
 
785
 
-
 
786
	return string(buf, end, ip4_addr, spec);
-
 
787
}
-
 
788
 
-
 
789
 
-
 
790
int kptr_restrict = 1;
-
 
791
 
-
 
792
/*
-
 
793
 * Show a '%p' thing.  A kernel extension is that the '%p' is followed
-
 
794
 * by an extra set of alphanumeric characters that are extended format
-
 
795
 * specifiers.
-
 
796
 *
-
 
797
 * Right now we handle:
-
 
798
 *
-
 
799
 * - 'F' For symbolic function descriptor pointers with offset
-
 
800
 * - 'f' For simple symbolic function names without offset
-
 
801
 * - 'S' For symbolic direct pointers with offset
-
 
802
 * - 's' For symbolic direct pointers without offset
-
 
803
 * - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref]
-
 
804
 * - 'r' For raw struct resource, e.g., [mem 0x0-0x1f flags 0x201]
-
 
805
 * - 'M' For a 6-byte MAC address, it prints the address in the
-
 
806
 *       usual colon-separated hex notation
-
 
807
 * - 'm' For a 6-byte MAC address, it prints the hex address without colons
-
 
808
 * - 'MF' For a 6-byte MAC FDDI address, it prints the address
-
 
809
 *       with a dash-separated hex notation
-
 
810
 * - 'I' [46] for IPv4/IPv6 addresses printed in the usual way
-
 
811
 *       IPv4 uses dot-separated decimal without leading 0's (1.2.3.4)
-
 
812
 *       IPv6 uses colon separated network-order 16 bit hex with leading 0's
-
 
813
 * - 'i' [46] for 'raw' IPv4/IPv6 addresses
-
 
814
 *       IPv6 omits the colons (01020304...0f)
-
 
815
 *       IPv4 uses dot-separated decimal with leading 0's (010.123.045.006)
-
 
816
 * - '[Ii]4[hnbl]' IPv4 addresses in host, network, big or little endian order
-
 
817
 * - 'I6c' for IPv6 addresses printed as specified by
-
 
818
 *       http://tools.ietf.org/html/draft-ietf-6man-text-addr-representation-00
-
 
819
 * - 'U' For a 16 byte UUID/GUID, it prints the UUID/GUID in the form
-
 
820
 *       "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
-
 
821
 *       Options for %pU are:
-
 
822
 *         b big endian lower case hex (default)
-
 
823
 *         B big endian UPPER case hex
-
 
824
 *         l little endian lower case hex
-
 
825
 *         L little endian UPPER case hex
-
 
826
 *           big endian output byte order is:
-
 
827
 *             [0][1][2][3]-[4][5]-[6][7]-[8][9]-[10][11][12][13][14][15]
-
 
828
 *           little endian output byte order is:
-
 
829
 *             [3][2][1][0]-[5][4]-[7][6]-[8][9]-[10][11][12][13][14][15]
-
 
830
 * - 'V' For a struct va_format which contains a format string * and va_list *,
-
 
831
 *       call vsnprintf(->format, *->va_list).
-
 
832
 *       Implements a "recursive vsnprintf".
-
 
833
 *       Do not use this feature without some mechanism to verify the
-
 
834
 *       correctness of the format string and va_list arguments.
-
 
835
 * - 'K' For a kernel pointer that should be hidden from unprivileged users
-
 
836
 *
-
 
837
 * Note: The difference between 'S' and 'F' is that on ia64 and ppc64
-
 
838
 * function pointers are really function descriptors, which contain a
-
 
839
 * pointer to the real address.
-
 
840
 */
-
 
841
static noinline_for_stack
-
 
842
char *pointer(const char *fmt, char *buf, char *end, void *ptr,
-
 
843
	      struct printf_spec spec)
-
 
844
{
-
 
845
	if (!ptr) {
-
 
846
		/*
-
 
847
		 * Print (null) with the same width as a pointer so it makes
-
 
848
		 * tabular output look nice.
-
 
849
		 */
-
 
850
		if (spec.field_width == -1)
-
 
851
			spec.field_width = 2 * sizeof(void *);
-
 
852
		return string(buf, end, "(null)", spec);
-
 
853
	}
-
 
854
 
-
 
855
	switch (*fmt) {
-
 
856
	case 'F':
-
 
857
	case 'f':
-
 
858
		ptr = dereference_function_descriptor(ptr);
-
 
859
		/* Fallthrough */
-
 
860
	case 'S':
-
 
861
	case 's':
-
 
862
		return symbol_string(buf, end, ptr, spec, *fmt);
-
 
863
	case 'R':
-
 
864
	case 'r':
-
 
865
		return resource_string(buf, end, ptr, spec, fmt);
-
 
866
	case 'M':			/* Colon separated: 00:01:02:03:04:05 */
-
 
867
	case 'm':			/* Contiguous: 000102030405 */
-
 
868
					/* [mM]F (FDDI, bit reversed) */
-
 
869
		return mac_address_string(buf, end, ptr, spec, fmt);
-
 
870
	case 'I':			/* Formatted IP supported
-
 
871
					 * 4:	1.2.3.4
-
 
872
					 * 6:	0001:0203:...:0708
-
 
873
					 * 6c:	1::708 or 1::1.2.3.4
-
 
874
					 */
-
 
875
	case 'i':			/* Contiguous:
-
 
876
					 * 4:	001.002.003.004
-
 
877
					 * 6:   000102...0f
-
 
878
					 */
-
 
879
		switch (fmt[1]) {
-
 
880
		case '4':
-
 
881
			return ip4_addr_string(buf, end, ptr, spec, fmt);
-
 
882
		}
-
 
883
		break;
-
 
884
	case 'V':
-
 
885
		return buf + vsnprintf(buf, end - buf,
-
 
886
				       ((struct va_format *)ptr)->fmt,
-
 
887
				       *(((struct va_format *)ptr)->va));
-
 
888
	}
-
 
889
	spec.flags |= SMALL;
-
 
890
	if (spec.field_width == -1) {
-
 
891
		spec.field_width = 2 * sizeof(void *);
-
 
892
		spec.flags |= ZEROPAD;
-
 
893
	}
-
 
894
	spec.base = 16;
-
 
895
 
-
 
896
	return number(buf, end, (unsigned long) ptr, spec);
-
 
897
}
-
 
898
 
-
 
899
/*
-
 
900
 * Helper function to decode printf style format.
-
 
901
 * Each call decode a token from the format and return the
-
 
902
 * number of characters read (or likely the delta where it wants
-
 
903
 * to go on the next call).
-
 
904
 * The decoded token is returned through the parameters
-
 
905
 *
-
 
906
 * 'h', 'l', or 'L' for integer fields
-
 
907
 * 'z' support added 23/7/1999 S.H.
-
 
908
 * 'z' changed to 'Z' --davidm 1/25/99
-
 
909
 * 't' added for ptrdiff_t
-
 
910
 *
-
 
911
 * @fmt: the format string
-
 
912
 * @type of the token returned
-
 
913
 * @flags: various flags such as +, -, # tokens..
-
 
914
 * @field_width: overwritten width
-
 
915
 * @base: base of the number (octal, hex, ...)
-
 
916
 * @precision: precision of a number
-
 
917
 * @qualifier: qualifier of a number (long, size_t, ...)
-
 
918
 */
-
 
919
static noinline_for_stack
-
 
920
int format_decode(const char *fmt, struct printf_spec *spec)
-
 
921
{
-
 
922
	const char *start = fmt;
-
 
923
 
-
 
924
	/* we finished early by reading the field width */
-
 
925
	if (spec->type == FORMAT_TYPE_WIDTH) {
-
 
926
		if (spec->field_width < 0) {
-
 
927
			spec->field_width = -spec->field_width;
-
 
928
			spec->flags |= LEFT;
-
 
929
		}
-
 
930
		spec->type = FORMAT_TYPE_NONE;
-
 
931
		goto precision;
-
 
932
	}
-
 
933
 
-
 
934
	/* we finished early by reading the precision */
-
 
935
	if (spec->type == FORMAT_TYPE_PRECISION) {
-
 
936
		if (spec->precision < 0)
-
 
937
			spec->precision = 0;
-
 
938
 
-
 
939
		spec->type = FORMAT_TYPE_NONE;
-
 
940
		goto qualifier;
-
 
941
	}
-
 
942
 
-
 
943
	/* By default */
-
 
944
	spec->type = FORMAT_TYPE_NONE;
-
 
945
 
-
 
946
	for (; *fmt ; ++fmt) {
-
 
947
		if (*fmt == '%')
-
 
948
			break;
-
 
949
	}
-
 
950
 
-
 
951
	/* Return the current non-format string */
-
 
952
	if (fmt != start || !*fmt)
-
 
953
		return fmt - start;
-
 
954
 
-
 
955
	/* Process flags */
-
 
956
	spec->flags = 0;
-
 
957
 
-
 
958
	while (1) { /* this also skips first '%' */
-
 
959
		bool found = true;
-
 
960
 
-
 
961
		++fmt;
-
 
962
 
-
 
963
		switch (*fmt) {
-
 
964
		case '-': spec->flags |= LEFT;    break;
-
 
965
		case '+': spec->flags |= PLUS;    break;
-
 
966
		case ' ': spec->flags |= SPACE;   break;
-
 
967
		case '#': spec->flags |= SPECIAL; break;
-
 
968
		case '0': spec->flags |= ZEROPAD; break;
-
 
969
		default:  found = false;
-
 
970
		}
-
 
971
 
-
 
972
		if (!found)
-
 
973
			break;
-
 
974
	}
-
 
975
 
-
 
976
	/* get field width */
-
 
977
	spec->field_width = -1;
-
 
978
 
-
 
979
	if (isdigit(*fmt))
-
 
980
		spec->field_width = skip_atoi(&fmt);
-
 
981
	else if (*fmt == '*') {
-
 
982
		/* it's the next argument */
-
 
983
		spec->type = FORMAT_TYPE_WIDTH;
-
 
984
		return ++fmt - start;
-
 
985
	}
-
 
986
 
-
 
987
precision:
-
 
988
	/* get the precision */
-
 
989
	spec->precision = -1;
-
 
990
	if (*fmt == '.') {
-
 
991
		++fmt;
-
 
992
		if (isdigit(*fmt)) {
-
 
993
			spec->precision = skip_atoi(&fmt);
-
 
994
			if (spec->precision < 0)
-
 
995
				spec->precision = 0;
-
 
996
		} else if (*fmt == '*') {
-
 
997
			/* it's the next argument */
-
 
998
			spec->type = FORMAT_TYPE_PRECISION;
-
 
999
			return ++fmt - start;
-
 
1000
		}
-
 
1001
	}
-
 
1002
 
-
 
1003
qualifier:
-
 
1004
	/* get the conversion qualifier */
-
 
1005
	spec->qualifier = -1;
-
 
1006
	if (*fmt == 'h' || TOLOWER(*fmt) == 'l' ||
-
 
1007
	    TOLOWER(*fmt) == 'z' || *fmt == 't') {
-
 
1008
		spec->qualifier = *fmt++;
-
 
1009
		if (unlikely(spec->qualifier == *fmt)) {
-
 
1010
			if (spec->qualifier == 'l') {
-
 
1011
				spec->qualifier = 'L';
-
 
1012
				++fmt;
-
 
1013
			} else if (spec->qualifier == 'h') {
-
 
1014
				spec->qualifier = 'H';
-
 
1015
				++fmt;
-
 
1016
			}
-
 
1017
		}
-
 
1018
	}
-
 
1019
 
-
 
1020
	/* default base */
-
 
1021
	spec->base = 10;
-
 
1022
	switch (*fmt) {
-
 
1023
	case 'c':
-
 
1024
		spec->type = FORMAT_TYPE_CHAR;
-
 
1025
		return ++fmt - start;
-
 
1026
 
-
 
1027
	case 's':
-
 
1028
		spec->type = FORMAT_TYPE_STR;
-
 
1029
		return ++fmt - start;
-
 
1030
 
-
 
1031
	case 'p':
-
 
1032
		spec->type = FORMAT_TYPE_PTR;
-
 
1033
		return fmt - start;
-
 
1034
		/* skip alnum */
-
 
1035
 
-
 
1036
	case 'n':
-
 
1037
		spec->type = FORMAT_TYPE_NRCHARS;
-
 
1038
		return ++fmt - start;
-
 
1039
 
-
 
1040
	case '%':
-
 
1041
		spec->type = FORMAT_TYPE_PERCENT_CHAR;
-
 
1042
		return ++fmt - start;
-
 
1043
 
-
 
1044
	/* integer number formats - set up the flags and "break" */
-
 
1045
	case 'o':
-
 
1046
		spec->base = 8;
-
 
1047
		break;
-
 
1048
 
-
 
1049
	case 'x':
-
 
1050
		spec->flags |= SMALL;
-
 
1051
 
-
 
1052
	case 'X':
-
 
1053
		spec->base = 16;
-
 
1054
		break;
-
 
1055
 
-
 
1056
	case 'd':
-
 
1057
	case 'i':
-
 
1058
		spec->flags |= SIGN;
-
 
1059
	case 'u':
-
 
1060
		break;
-
 
1061
 
-
 
1062
	default:
-
 
1063
		spec->type = FORMAT_TYPE_INVALID;
-
 
1064
		return fmt - start;
-
 
1065
	}
-
 
1066
 
-
 
1067
	if (spec->qualifier == 'L')
-
 
1068
		spec->type = FORMAT_TYPE_LONG_LONG;
-
 
1069
	else if (spec->qualifier == 'l') {
-
 
1070
		if (spec->flags & SIGN)
-
 
1071
			spec->type = FORMAT_TYPE_LONG;
-
 
1072
		else
-
 
1073
			spec->type = FORMAT_TYPE_ULONG;
-
 
1074
	} else if (TOLOWER(spec->qualifier) == 'z') {
-
 
1075
		spec->type = FORMAT_TYPE_SIZE_T;
-
 
1076
	} else if (spec->qualifier == 't') {
-
 
1077
		spec->type = FORMAT_TYPE_PTRDIFF;
-
 
1078
	} else if (spec->qualifier == 'H') {
-
 
1079
		if (spec->flags & SIGN)
-
 
1080
			spec->type = FORMAT_TYPE_BYTE;
-
 
1081
		else
-
 
1082
			spec->type = FORMAT_TYPE_UBYTE;
-
 
1083
	} else if (spec->qualifier == 'h') {
-
 
1084
		if (spec->flags & SIGN)
-
 
1085
			spec->type = FORMAT_TYPE_SHORT;
-
 
1086
		else
-
 
1087
			spec->type = FORMAT_TYPE_USHORT;
-
 
1088
	} else {
-
 
1089
		if (spec->flags & SIGN)
-
 
1090
			spec->type = FORMAT_TYPE_INT;
-
 
1091
		else
-
 
1092
			spec->type = FORMAT_TYPE_UINT;
-
 
1093
	}
-
 
1094
 
-
 
1095
	return ++fmt - start;
-
 
1096
}
-
 
1097
 
-
 
1098
/**
-
 
1099
 * vsnprintf - Format a string and place it in a buffer
-
 
1100
 * @buf: The buffer to place the result into
-
 
1101
 * @size: The size of the buffer, including the trailing null space
-
 
1102
 * @fmt: The format string to use
-
 
1103
 * @args: Arguments for the format string
-
 
1104
 *
-
 
1105
 * This function follows C99 vsnprintf, but has some extensions:
-
 
1106
 * %pS output the name of a text symbol with offset
-
 
1107
 * %ps output the name of a text symbol without offset
-
 
1108
 * %pF output the name of a function pointer with its offset
-
 
1109
 * %pf output the name of a function pointer without its offset
-
 
1110
 * %pR output the address range in a struct resource with decoded flags
-
 
1111
 * %pr output the address range in a struct resource with raw flags
-
 
1112
 * %pM output a 6-byte MAC address with colons
-
 
1113
 * %pm output a 6-byte MAC address without colons
-
 
1114
 * %pI4 print an IPv4 address without leading zeros
-
 
1115
 * %pi4 print an IPv4 address with leading zeros
-
 
1116
 * %pI6 print an IPv6 address with colons
-
 
1117
 * %pi6 print an IPv6 address without colons
-
 
1118
 * %pI6c print an IPv6 address as specified by
-
 
1119
 *   http://tools.ietf.org/html/draft-ietf-6man-text-addr-representation-00
-
 
1120
 * %pU[bBlL] print a UUID/GUID in big or little endian using lower or upper
-
 
1121
 *   case.
-
 
1122
 * %n is ignored
-
 
1123
 *
-
 
1124
 * The return value is the number of characters which would
-
 
1125
 * be generated for the given input, excluding the trailing
-
 
1126
 * '\0', as per ISO C99. If you want to have the exact
-
 
1127
 * number of characters written into @buf as return value
-
 
1128
 * (not including the trailing '\0'), use vscnprintf(). If the
-
 
1129
 * return is greater than or equal to @size, the resulting
-
 
1130
 * string is truncated.
-
 
1131
 *
-
 
1132
 * Call this function if you are already dealing with a va_list.
-
 
1133
 * You probably want snprintf() instead.
-
 
1134
 */
-
 
1135
int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
-
 
1136
{
-
 
1137
	unsigned long long num;
-
 
1138
	char *str, *end;
-
 
1139
	struct printf_spec spec = {0};
-
 
1140
 
-
 
1141
	/* Reject out-of-range values early.  Large positive sizes are
-
 
1142
	   used for unknown buffer sizes. */
-
 
1143
    if ((int)size < 0)
-
 
1144
		return 0;
-
 
1145
 
-
 
1146
	str = buf;
-
 
1147
	end = buf + size;
-
 
1148
 
-
 
1149
	/* Make sure end is always >= buf */
-
 
1150
	if (end < buf) {
-
 
1151
		end = ((void *)-1);
-
 
1152
		size = end - buf;
-
 
1153
	}
-
 
1154
 
-
 
1155
	while (*fmt) {
-
 
1156
		const char *old_fmt = fmt;
-
 
1157
		int read = format_decode(fmt, &spec);
-
 
1158
 
-
 
1159
		fmt += read;
-
 
1160
 
-
 
1161
		switch (spec.type) {
-
 
1162
		case FORMAT_TYPE_NONE: {
-
 
1163
			int copy = read;
-
 
1164
			if (str < end) {
-
 
1165
				if (copy > end - str)
-
 
1166
					copy = end - str;
-
 
1167
				memcpy(str, old_fmt, copy);
-
 
1168
			}
-
 
1169
			str += read;
-
 
1170
			break;
-
 
1171
		}
-
 
1172
 
-
 
1173
		case FORMAT_TYPE_WIDTH:
-
 
1174
			spec.field_width = va_arg(args, int);
-
 
1175
			break;
-
 
1176
 
-
 
1177
		case FORMAT_TYPE_PRECISION:
-
 
1178
			spec.precision = va_arg(args, int);
-
 
1179
			break;
-
 
1180
 
-
 
1181
		case FORMAT_TYPE_CHAR: {
-
 
1182
			char c;
-
 
1183
 
-
 
1184
			if (!(spec.flags & LEFT)) {
-
 
1185
				while (--spec.field_width > 0) {
-
 
1186
					if (str < end)
-
 
1187
						*str = ' ';
-
 
1188
					++str;
-
 
1189
 
-
 
1190
				}
-
 
1191
			}
-
 
1192
			c = (unsigned char) va_arg(args, int);
-
 
1193
			if (str < end)
-
 
1194
				*str = c;
-
 
1195
			++str;
-
 
1196
			while (--spec.field_width > 0) {
-
 
1197
				if (str < end)
-
 
1198
					*str = ' ';
-
 
1199
				++str;
-
 
1200
			}
-
 
1201
			break;
-
 
1202
		}
-
 
1203
 
-
 
1204
		case FORMAT_TYPE_STR:
-
 
1205
			str = string(str, end, va_arg(args, char *), spec);
-
 
1206
			break;
-
 
1207
 
-
 
1208
		case FORMAT_TYPE_PTR:
-
 
1209
			str = pointer(fmt+1, str, end, va_arg(args, void *),
-
 
1210
				      spec);
-
 
1211
			while (isalnum(*fmt))
-
 
1212
				fmt++;
-
 
1213
			break;
-
 
1214
 
-
 
1215
		case FORMAT_TYPE_PERCENT_CHAR:
-
 
1216
			if (str < end)
-
 
1217
				*str = '%';
-
 
1218
			++str;
-
 
1219
			break;
-
 
1220
 
-
 
1221
		case FORMAT_TYPE_INVALID:
-
 
1222
			if (str < end)
-
 
1223
				*str = '%';
-
 
1224
			++str;
-
 
1225
			break;
-
 
1226
 
-
 
1227
		case FORMAT_TYPE_NRCHARS: {
-
 
1228
			u8 qualifier = spec.qualifier;
-
 
1229
 
-
 
1230
			if (qualifier == 'l') {
-
 
1231
				long *ip = va_arg(args, long *);
-
 
1232
				*ip = (str - buf);
-
 
1233
			} else if (TOLOWER(qualifier) == 'z') {
-
 
1234
				size_t *ip = va_arg(args, size_t *);
-
 
1235
				*ip = (str - buf);
-
 
1236
			} else {
-
 
1237
				int *ip = va_arg(args, int *);
-
 
1238
				*ip = (str - buf);
-
 
1239
			}
-
 
1240
			break;
-
 
1241
		}
-
 
1242
 
-
 
1243
		default:
-
 
1244
			switch (spec.type) {
-
 
1245
			case FORMAT_TYPE_LONG_LONG:
-
 
1246
				num = va_arg(args, long long);
-
 
1247
				break;
-
 
1248
			case FORMAT_TYPE_ULONG:
-
 
1249
				num = va_arg(args, unsigned long);
-
 
1250
				break;
-
 
1251
			case FORMAT_TYPE_LONG:
-
 
1252
				num = va_arg(args, long);
-
 
1253
				break;
-
 
1254
			case FORMAT_TYPE_SIZE_T:
-
 
1255
				num = va_arg(args, size_t);
-
 
1256
				break;
-
 
1257
			case FORMAT_TYPE_PTRDIFF:
-
 
1258
				num = va_arg(args, ptrdiff_t);
-
 
1259
				break;
-
 
1260
			case FORMAT_TYPE_UBYTE:
-
 
1261
				num = (unsigned char) va_arg(args, int);
-
 
1262
				break;
-
 
1263
			case FORMAT_TYPE_BYTE:
-
 
1264
				num = (signed char) va_arg(args, int);
-
 
1265
				break;
-
 
1266
			case FORMAT_TYPE_USHORT:
-
 
1267
				num = (unsigned short) va_arg(args, int);
-
 
1268
				break;
-
 
1269
			case FORMAT_TYPE_SHORT:
-
 
1270
				num = (short) va_arg(args, int);
-
 
1271
				break;
-
 
1272
			case FORMAT_TYPE_INT:
-
 
1273
				num = (int) va_arg(args, int);
-
 
1274
				break;
-
 
1275
			default:
-
 
1276
				num = va_arg(args, unsigned int);
-
 
1277
			}
-
 
1278
 
-
 
1279
			str = number(str, end, num, spec);
-
 
1280
		}
-
 
1281
	}
-
 
1282
 
-
 
1283
	if (size > 0) {
-
 
1284
		if (str < end)
-
 
1285
			*str = '\0';
-
 
1286
		else
-
 
1287
			end[-1] = '\0';
-
 
1288
	}
-
 
1289
 
-
 
1290
	/* the trailing null byte doesn't count towards the total */
-
 
1291
	return str-buf;
-
 
1292
 
-
 
1293
}
-
 
1294
EXPORT_SYMBOL(vsnprintf);
-
 
1295
 
-
 
1296
int vsprintf(char *buf, const char *fmt, va_list args)
-
 
1297
{
-
 
1298
    return vsnprintf(buf, INT_MAX, fmt, args);
-
 
1299
}
-
 
1300
 
-
 
1301
 
-
 
1302
/**
-
 
1303
 * snprintf - Format a string and place it in a buffer
-
 
1304
 * @buf: The buffer to place the result into
-
 
1305
 * @size: The size of the buffer, including the trailing null space
-
 
1306
 * @fmt: The format string to use
-
 
1307
 * @...: Arguments for the format string
-
 
1308
 *
-
 
1309
 * The return value is the number of characters which would be
-
 
1310
 * generated for the given input, excluding the trailing null,
-
 
1311
 * as per ISO C99.  If the return is greater than or equal to
-
 
1312
 * @size, the resulting string is truncated.
-
 
1313
 *
-
 
1314
 * See the vsnprintf() documentation for format string extensions over C99.
-
 
1315
 */
-
 
1316
int snprintf(char *buf, size_t size, const char *fmt, ...)
-
 
1317
{
-
 
1318
	va_list args;
-
 
1319
	int i;
-
 
1320
 
-
 
1321
	va_start(args, fmt);
-
 
1322
	i = vsnprintf(buf, size, fmt, args);
-
 
1323
	va_end(args);
-
 
1324
 
-
 
1325
	return i;
-
 
1326
}
-
 
1327
EXPORT_SYMBOL(snprintf);
-
 
1328
 
-
 
1329
 
-
 
1330
/**
-
 
1331
 * sprintf - Format a string and place it in a buffer
-
 
1332
 * @buf: The buffer to place the result into
-
 
1333
 * @fmt: The format string to use
-
 
1334
 * @...: Arguments for the format string
-
 
1335
 *
-
 
1336
 * The function returns the number of characters written
-
 
1337
 * into @buf. Use snprintf() or scnprintf() in order to avoid
-
 
1338
 * buffer overflows.
-
 
1339
 *
-
 
1340
 * See the vsnprintf() documentation for format string extensions over C99.
-
 
1341
 */
-
 
1342
int sprintf(char *buf, const char *fmt, ...)
-
 
1343
{
-
 
1344
	va_list args;
-
 
1345
	int i;
-
 
1346