3 * \brief Implementations of printf and friends
7 * Copyright (c) 2007, 2008, 2010, 2011, 2012, 2013 ETH Zurich.
10 * This file is distributed under the terms in the attached LICENSE file.
11 * If you do not find this file, copies can be found by writing to:
12 * ETH Zurich D-INFK, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
15 /* $NetBSD: subr_prf.c,v 1.109 2007/09/26 07:40:36 he Exp $ */
17 * Copyright (c) 1986, 1988, 1991, 1993
18 * The Regents of the University of California. All rights reserved.
19 * (c) UNIX System Laboratories, Inc.
20 * All or some portions of this file are derived from material licensed
21 * to the University of California by American Telephone and Telegraph
22 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
23 * the permission of UNIX System Laboratories, Inc.
25 * Redistribution and use in source and binary forms, with or without
26 * modification, are permitted provided that the following conditions
28 * 1. Redistributions of source code must retain the above copyright
29 * notice, this list of conditions and the following disclaimer.
30 * 2. Redistributions in binary form must reproduce the above copyright
31 * notice, this list of conditions and the following disclaimer in the
32 * documentation and/or other materials provided with the distribution.
33 * 3. Neither the name of the University nor the names of its contributors
34 * may be used to endorse or promote products derived from this software
35 * without specific prior written permission.
37 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
38 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
39 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
40 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
41 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
42 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
43 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
45 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
46 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
49 * @(#)subr_prf.c 8.4 (Berkeley) 5/4/95
58 #include <sys/types.h>
60 #define TOCONS (1 << 0)
61 #define TOLOG (1 << 1)
62 #define TOBUFONLY (1 << 2)
64 #define KPRINTF_BUFSIZE (sizeof(quad_t) * __CHAR_BIT__ / 3 + 2)
66 static const char hexdigits[] = "0123456789abcdef";
67 static const char HEXDIGITS[] = "0123456789ABCDEF";
69 #define KPRINTF_MUTEX_ENTER() kprintf_begin()
70 #define KPRINTF_MUTEX_EXIT() kprintf_end()
86 static int kprintf(char * CT(bufsize) OPT sbuf, size_t bufsize,
87 const char * NTS fmt0, va_list ap, int oflags);
90 * printf_nolog: Like printf(), but does not send message to the log.
94 printf_nolog(const char *fmt, ...)
98 KPRINTF_MUTEX_ENTER();
101 int retval = kprintf(NULL, 0, fmt, ap, TOCONS);
104 KPRINTF_MUTEX_EXIT();
110 * normal kernel printf functions: printf, vprintf, snprintf, vsnprintf
114 * printf: print a message to the console and the log
117 printf(const char *fmt, ...)
121 KPRINTF_MUTEX_ENTER();
124 int retval = kprintf(NULL, 0, fmt, ap, TOCONS /*| TOLOG*/);
127 KPRINTF_MUTEX_EXIT();
133 * vprintf: print a message to the console and the log [already have
138 vprintf(const char *fmt, va_list ap)
140 KPRINTF_MUTEX_ENTER();
142 int retval = kprintf(NULL, 0, fmt, ap, TOCONS /*| TOLOG*/);
144 KPRINTF_MUTEX_EXIT();
150 * snprintf: print a message to a buffer
153 snprintf(char *bf, size_t size, const char *fmt, ...)
162 retval = kprintf(bf, size, fmt, ap, TOBUFONLY);
165 bf[retval] = '\0'; /* null terminate */
171 * vsnprintf: print a message to a buffer [already have va_alist]
174 vsnprintf(char *bf, size_t size, const char *fmt, va_list ap)
181 retval = kprintf(bf, size, fmt, ap, TOBUFONLY);
183 bf[retval] = '\0'; /* null terminate */
189 * kprintf: scaled down version of printf(3).
191 * this version based on vfprintf() from libc which was derived from
192 * software contributed to Berkeley by Chris Torek.
194 * NOTE: The kprintf mutex must be held if we're going TOBUF or TOCONS!
197 /* XXX: legacy types needed by kprintf. don't use these for new code */
198 typedef signed long long quad_t;
199 typedef unsigned long long u_quad_t;
202 * macros for converting digits to letters and vice versa
204 #define to_digit(c) ((c) - '0')
205 #define is_digit(c) ((unsigned)to_digit(c) <= 9)
206 #define to_char(n) ((n) + '0')
209 * flags used during conversion.
211 #define ALT 0x001 /* alternate form */
212 #define HEXPREFIX 0x002 /* add 0x or 0X prefix */
213 #define LADJUST 0x004 /* left adjustment */
214 #define LONGDBL 0x008 /* long double; unimplemented */
215 #define LONGINT 0x010 /* long integer */
216 #define QUADINT 0x020 /* quad integer */
217 #define SHORTINT 0x040 /* short integer */
218 #define MAXINT 0x080 /* intmax_t */
219 #define PTRINT 0x100 /* intptr_t */
220 #define SIZEINT 0x200 /* size_t */
221 #define ZEROPAD 0x400 /* zero (as opposed to blank) pad */
222 #define FPT 0x800 /* Floating point number */
225 * To extend shorts properly, we need both signed and unsigned
226 * argument extraction methods.
229 (flags&MAXINT ? va_arg(ap, intmax_t) : \
230 flags&PTRINT ? va_arg(ap, intptr_t) : \
231 flags&SIZEINT ? va_arg(ap, ssize_t) : /* XXX */ \
232 flags&QUADINT ? va_arg(ap, quad_t) : \
233 flags&LONGINT ? va_arg(ap, long) : \
234 flags&SHORTINT ? (long)(short)va_arg(ap, int) : \
235 (long)va_arg(ap, int))
237 (flags&MAXINT ? va_arg(ap, uintmax_t) : \
238 flags&PTRINT ? va_arg(ap, uintptr_t) : \
239 flags&SIZEINT ? va_arg(ap, size_t) : \
240 flags&QUADINT ? va_arg(ap, u_quad_t) : \
241 flags&LONGINT ? va_arg(ap, u_long) : \
242 flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \
243 (u_long)va_arg(ap, u_int))
245 #define KPRINTF_PUTCHAR(C) { \
246 if (oflags == TOBUFONLY) { \
247 if (sbuf == tailp) { \
248 ret += 1; /* indicate error */ \
259 * Guts of kernel printf. Note, we already expect to be in a mutex!
262 kprintf(char *sbuf_in, size_t bufsize, const char *fmt0, va_list ap, int oflags)
264 char *sbuf = sbuf_in; /* XXX: make deputy happy */
265 const char *fmt; /* format string */
266 int ch; /* character from fmt */
267 int n; /* handy integer (short term usage) */
268 char * TRUSTED cp; /* handy char pointer (short term usage) */
269 int flags; /* flags as above */
270 int ret; /* return value accumulator */
271 int width; /* width from format (%8d), or 0 */
272 int prec; /* precision from format (%.3d), or -1 */
273 char sign; /* sign prefix (' ', '+', '-', or \0) */
275 u_quad_t _uquad; /* integer arguments %[diouxX] */
276 enum { OCT, DEC, HEX } base; /* base for [diouxX] conversion */
277 int dprec; /* a copy of prec if [diouxX], 0 otherwise */
278 int realsz; /* field size expanded by dprec */
279 int size; /* size of converted field or string */
280 const char *xdigs; /* digits for [xX] conversion */
281 char bf[KPRINTF_BUFSIZE]; /* space for %c, %[diouxX] */
282 char *tailp; /* tail pointer for snprintf */
284 tailp = NULL; /* XXX: shutup gcc */
287 * XXX: somehow this does not work on k1om
290 if (oflags == TOBUFONLY)
291 tailp = &sbuf[bufsize];
293 n = 0; /* XXX: shutup gcc */
294 cp = NULL; /* XXX: shutup gcc */
295 size = 0; /* XXX: shutup gcc */
300 xdigs = NULL; /* XXX: shut up gcc warning */
303 * Scan the format for conversions (`%' character).
306 while (*fmt != '%' && *fmt) {
308 KPRINTF_PUTCHAR(*fmt++);
313 fmt++; /* skip over '%' */
327 * ``If the space and + flags both appear, the space
328 * flag will be ignored.''
339 * ``A negative field width argument is taken as a
340 * - flag followed by a positive field width.''
342 * They don't exclude field widths read from args.
344 if ((width = va_arg(ap, int)) >= 0)
355 if ((ch = *fmt++) == '*') {
357 prec = n < 0 ? -1 : n;
361 while (is_digit(ch)) {
362 n = 10 * n + to_digit(ch);
365 prec = n < 0 ? -1 : n;
369 * ``Note that 0 is taken as a flag, not as the
370 * beginning of a field width.''
386 n = 10 * n + to_digit(ch);
388 } while (is_digit(ch));
415 *(cp = bf) = va_arg(ap, int);
421 /*FALLTHROUGH*/ case 'd':
424 if ((quad_t) _uquad < 0) {
432 *va_arg(ap, intmax_t *) = ret;
433 else if (flags & PTRINT)
434 *va_arg(ap, intptr_t *) = ret;
435 else if (flags & SIZEINT)
436 *va_arg(ap, ssize_t *) = ret;
437 else if (flags & QUADINT)
438 *va_arg(ap, quad_t *) = ret;
439 else if (flags & LONGINT)
440 *va_arg(ap, long *) = ret;
441 else if (flags & SHORTINT)
442 *va_arg(ap, short *) = ret;
444 *va_arg(ap, int *) = ret;
445 continue; /* no output */
448 /*FALLTHROUGH*/ case 'o':
454 * ``The argument shall be a pointer to void. The
455 * value of the pointer is converted to a sequence
456 * of printable characters, in an implementation-
461 _uquad = (u_long) va_arg(ap, void *);
468 cp = va_arg(ap, char *);
470 /*XXXUNCONST*/ cp = "(null)";
473 * can't use strlen; can only look for the
474 * NUL in the first `prec' characters, and
475 * strlen() will go further.
477 const char *p = memchr(cp, 0, prec);
491 /*FALLTHROUGH*/ case 'u':
502 /* leading 0x/X only if non-zero */
503 if (flags & ALT && _uquad != 0)
506 /* unsigned conversions */
509 * ``... diouXx conversions ... if a precision is
510 * specified, the 0 flag will be ignored.''
513 number:if ((dprec = prec) >= 0)
517 * ``The result of converting a zero value with an
518 * explicit precision of zero is no characters.''
521 cp = bf + KPRINTF_BUFSIZE;
522 if (_uquad != 0 || prec != 0) {
524 * Unsigned mod is hard, and unsigned mod
525 * by a constant is easier than that by
526 * a variable; hence this switch.
531 *--cp = to_char(_uquad & 7);
534 /* handle octal leading 0 */
535 if (flags & ALT && *cp != '0')
540 /* many numbers are 1 digit */
541 while (_uquad >= 10) {
542 *--cp = to_char(_uquad % 10);
545 *--cp = to_char(_uquad);
550 *--cp = xdigs[_uquad & 15];
556 /*XXXUNCONST*/ cp = "bug in kprintf: bad base";
561 size = TC(bf) + KPRINTF_BUFSIZE - cp;
564 default: /* "%?" prints ?, unless ? is NUL */
567 /* pretend it was %c with argument ch */
576 * All reasonable formats wind up here. At this point, `cp'
577 * points to a string which (if not flags&LADJUST) should be
578 * padded out to `width' places. If flags&ZEROPAD, it should
579 * first be prefixed by any sign or other prefix; otherwise,
580 * it should be blank padded before the prefix is emitted.
581 * After any left-hand padding and prefixing, emit zeroes
582 * required by a decimal [diouxX] precision, then print the
583 * string proper, then emit zeroes required by any leftover
584 * floating precision; finally, if LADJUST, pad with blanks.
586 * Compute actual size, so we know how much to pad.
587 * size excludes decimal prec; realsz includes it.
589 realsz = dprec > size ? dprec : size;
592 else if (flags & HEXPREFIX)
596 ret += width > realsz ? width : realsz;
598 /* right-adjusting blank padding */
599 if ((flags & (LADJUST | ZEROPAD)) == 0) {
602 KPRINTF_PUTCHAR(' ');
607 KPRINTF_PUTCHAR(sign);
608 } else if (flags & HEXPREFIX) {
609 KPRINTF_PUTCHAR('0');
613 /* right-adjusting zero padding */
614 if ((flags & (LADJUST | ZEROPAD)) == ZEROPAD) {
617 KPRINTF_PUTCHAR('0');
620 /* leading zeroes from decimal precision */
623 KPRINTF_PUTCHAR('0');
625 /* the string or number proper */
627 KPRINTF_PUTCHAR(*cp++);
628 /* left-adjusting padding (always blank) */
629 if (flags & LADJUST) {
632 KPRINTF_PUTCHAR(' ');