1 /* $NetBSD: subr_prf.c,v 1.136 2009/06/28 15:30:30 rmind Exp $ */
4 * Copyright (c) 1986, 1988, 1991, 1993
5 * The Regents of the University of California. All rights reserved.
6 * (c) UNIX System Laboratories, Inc.
7 * All or some portions of this file are derived from material licensed
8 * to the University of California by American Telephone and Telegraph
9 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
10 * the permission of UNIX System Laboratories, Inc.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * @(#)subr_prf.c 8.4 (Berkeley) 5/4/95
39 #include <sys/cdefs.h>
40 __KERNEL_RCSID(0, "$NetBSD: subr_prf.c,v 1.136 2009/06/28 15:30:30 rmind Exp $");
43 #include "opt_ipkdb.h"
47 #include <sys/param.h>
48 #include <sys/stdint.h>
49 #include <sys/systm.h>
51 #include <sys/device.h>
52 #include <sys/reboot.h>
53 #include <sys/msgbuf.h>
55 #include <sys/ioctl.h>
56 #include <sys/vnode.h>
59 #include <sys/tprintf.h>
60 #include <sys/spldebug.h>
61 #include <sys/syslog.h>
62 #include <sys/malloc.h>
63 #include <sys/kprintf.h>
64 #include <sys/atomic.h>
65 #include <sys/kernel.h>
73 #include <ddb/ddbvar.h>
74 #include <machine/db_machdep.h>
75 #include <ddb/db_command.h>
76 #include <ddb/db_interface.h>
80 #include <ipkdb/ipkdb.h>
83 static kmutex_t kprintf_mtx
;
84 static bool kprintf_inited
= false;
87 * note that stdarg.h and the ansi style va_start macro is used for both
88 * ansi and traditional c complers.
89 * XXX: this requires that stdarg.h define: va_alist and va_dcl
91 #include <machine/stdarg.h>
98 #include <ddb/db_output.h> /* db_printf, db_putchar prototypes */
111 static void putchar(int, int, struct tty
*);
118 extern struct tty
*constty
; /* pointer to console "window" tty */
119 extern int log_open
; /* subr_log: is /dev/klog open? */
120 const char *panicstr
; /* arg to first call to panic (used as a flag
121 to indicate that panic has already been called). */
122 struct cpu_info
*paniccpu
; /* cpu that first paniced */
123 long panicstart
, panicend
; /* position in the msgbuf of the start and
124 end of the formatted panicstr. */
125 int doing_shutdown
; /* set to indicate shutdown in progress */
127 #ifndef DUMP_ON_PANIC
128 #define DUMP_ON_PANIC 1
130 int dumponpanic
= DUMP_ON_PANIC
;
133 * v_putc: routine to putc on virtual console
135 * the v_putc pointer can be used to redirect the console cnputc elsewhere
136 * [e.g. to a "virtual console"].
139 void (*v_putc
)(int) = cnputc
; /* start with cnputc (normal cons) */
140 void (*v_flush
)(void) = cnflush
; /* start with cnflush (normal cons) */
142 const char hexdigits
[] = "0123456789abcdef";
143 const char HEXDIGITS
[] = "0123456789ABCDEF";
151 * Locking is inited fairly early in MI bootstrap. Before that
152 * prints are done unlocked. But that doesn't really matter,
153 * since nothing can preempt us before interrupts are enabled.
159 KASSERT(!kprintf_inited
&& cold
); /* not foolproof, but ... */
160 mutex_init(&kprintf_mtx
, MUTEX_DEFAULT
, IPL_HIGH
);
161 kprintf_inited
= true;
168 if (__predict_true(kprintf_inited
))
169 mutex_enter(&kprintf_mtx
);
176 if (__predict_true(kprintf_inited
)) {
177 /* assert kprintf wasn't somehow inited while we were in */
178 KASSERT(mutex_owned(&kprintf_mtx
));
179 mutex_exit(&kprintf_mtx
);
184 * twiddle: spin a little propellor on the console.
190 static const char twiddle_chars
[] = "|/-\\";
195 putchar(twiddle_chars
[pos
++ & 3], TOCONS
, NULL
);
196 putchar('\b', TOCONS
, NULL
);
202 * panic: handle an unresolvable fatal error
204 * prints "panic: <message>" and reboots. if called twice (i.e. recursive
205 * call) we avoid trying to sync the disk and just reboot (to avoid
210 panic(const char *fmt
, ...)
212 CPU_INFO_ITERATOR cii
;
213 struct cpu_info
*ci
, *oci
;
219 if (lwp0
.l_cpu
&& curlwp
) {
221 * Disable preemption. If already panicing on another CPU, sit
222 * here and spin until the system is rebooted. Allow the CPU that
223 * first paniced to panic again.
227 oci
= atomic_cas_ptr((void *)&paniccpu
, NULL
, ci
);
228 if (oci
!= NULL
&& oci
!= ci
) {
229 /* Give interrupts a chance to try and prevent deadlock. */
231 #ifndef _RUMPKERNEL /* XXXpooka: temporary build fix, see kern/40505 */
233 #endif /* _RUMPKERNEL */
238 * Convert the current thread to a bound thread and prevent all
239 * CPUs from scheduling unbound jobs. Do so without taking any
242 curlwp
->l_pflag
|= LP_BOUND
;
243 for (CPU_INFO_FOREACH(cii
, ci
)) {
244 ci
->ci_schedstate
.spc_flags
|= SPCF_OFFLINE
;
248 bootopt
= RB_AUTOBOOT
| RB_NOSYNC
;
255 if (msgbufenabled
&& msgbufp
->msg_magic
== MSG_MAGIC
)
256 panicstart
= msgbufp
->msg_bufx
;
264 if (msgbufenabled
&& msgbufp
->msg_magic
== MSG_MAGIC
)
265 panicend
= msgbufp
->msg_bufx
;
274 if (boothowto
& RB_KDB
)
280 else if (db_onpanic
>= 0) {
281 static int intrace
= 0;
285 printf("cpu%u: Begin traceback...\n",
286 cpu_index(curcpu()));
287 db_stack_trace_print(
288 (db_expr_t
)(intptr_t)__builtin_frame_address(0),
289 true, 65535, "", printf
);
290 printf("cpu%u: End traceback...\n",
291 cpu_index(curcpu()));
294 printf("Faulted in mid-traceback; aborting...");
299 cpu_reboot(bootopt
, NULL
);
303 * kernel logging functions: log, logpri, addlog
307 * log: write to the log buffer
309 * => will not sleep [so safe to call from interrupt]
310 * => will log to console if /dev/klog isn't open
314 log(int level
, const char *fmt
, ...)
320 klogpri(level
); /* log the level first */
322 kprintf(fmt
, TOLOG
, NULL
, NULL
, ap
);
326 kprintf(fmt
, TOCONS
, NULL
, NULL
, ap
);
332 logwakeup(); /* wake up anyone waiting for log msgs */
336 * vlog: write to the log buffer [already have va_alist]
340 vlog(int level
, const char *fmt
, va_list ap
)
345 klogpri(level
); /* log the level first */
346 kprintf(fmt
, TOLOG
, NULL
, NULL
, ap
);
348 kprintf(fmt
, TOCONS
, NULL
, NULL
, ap
);
352 logwakeup(); /* wake up anyone waiting for log msgs */
356 * logpri: log the priority level to the klog
369 * Note: we must be in the mutex here!
375 char snbuf
[KPRINTF_BUFSIZE
];
377 putchar('<', TOLOG
, NULL
);
378 snprintf(snbuf
, sizeof(snbuf
), "%d", level
);
379 for (p
= snbuf
; *p
; p
++)
380 putchar(*p
, TOLOG
, NULL
);
381 putchar('>', TOLOG
, NULL
);
385 * addlog: add info to previous log message
389 addlog(const char *fmt
, ...)
396 kprintf(fmt
, TOLOG
, NULL
, NULL
, ap
);
400 kprintf(fmt
, TOCONS
, NULL
, NULL
, ap
);
411 * putchar: print a single character on console or user terminal.
413 * => if console, then the last MSGBUFS chars are saved in msgbuf
414 * for inspection later (e.g. dmesg/syslog)
415 * => we must already be in the mutex!
418 putchar(int c
, int flags
, struct tty
*tp
)
423 if ((flags
& TOCONS
) && tp
== NULL
&& constty
) {
427 if ((flags
& TOTTY
) && tp
&&
428 tputchar(c
, flags
, tp
) < 0 &&
429 (flags
& TOCONS
) && tp
== constty
)
431 if ((flags
& TOLOG
) &&
432 c
!= '\0' && c
!= '\r' && c
!= 0177)
434 if ((flags
& TOCONS
) && constty
== NULL
&& c
!= '\0')
443 * tablefull: warn that a system table is full
447 tablefull(const char *tab
, const char *hint
)
450 log(LOG_ERR
, "%s: table is full - %s\n", tab
, hint
);
452 log(LOG_ERR
, "%s: table is full\n", tab
);
457 * uprintf: print to the controlling tty of the current process
459 * => we may block if the tty queue is full
460 * => no message is printed if the queue doesn't clear in a reasonable
465 uprintf(const char *fmt
, ...)
467 struct proc
*p
= curproc
;
470 /* mutex_enter(proc_lock); XXXSMP */
472 if (p
->p_lflag
& PL_CONTROLT
&& p
->p_session
->s_ttyvp
) {
473 /* No mutex needed; going to process TTY. */
475 kprintf(fmt
, TOTTY
, p
->p_session
->s_ttyp
, NULL
, ap
);
479 /* mutex_exit(proc_lock); XXXSMP */
483 uprintf_locked(const char *fmt
, ...)
485 struct proc
*p
= curproc
;
488 if (p
->p_lflag
& PL_CONTROLT
&& p
->p_session
->s_ttyvp
) {
489 /* No mutex needed; going to process TTY. */
491 kprintf(fmt
, TOTTY
, p
->p_session
->s_ttyp
, NULL
, ap
);
497 * tprintf functions: used to send messages to a specific process
500 * get a tpr_t handle on a process "p" by using "tprintf_open(p)"
501 * use the handle when calling "tprintf"
502 * when done, do a "tprintf_close" to drop the handle
506 * tprintf_open: get a tprintf handle on a process "p"
508 * => returns NULL if process can't be printed to
512 tprintf_open(struct proc
*p
)
518 mutex_enter(proc_lock
);
519 if (p
->p_lflag
& PL_CONTROLT
&& p
->p_session
->s_ttyvp
) {
520 proc_sesshold(p
->p_session
);
521 cookie
= (tpr_t
)p
->p_session
;
523 mutex_exit(proc_lock
);
529 * tprintf_close: dispose of a tprintf handle obtained with tprintf_open
533 tprintf_close(tpr_t sess
)
537 mutex_enter(proc_lock
);
538 /* Releases proc_lock. */
539 proc_sessrele((struct session
*)sess
);
544 * tprintf: given tprintf handle to a process [obtained with tprintf_open],
545 * send a message to the controlling tty for that process.
547 * => also sends message to /dev/klog
550 tprintf(tpr_t tpr
, const char *fmt
, ...)
552 struct session
*sess
= (struct session
*)tpr
;
553 struct tty
*tp
= NULL
;
557 /* mutex_enter(proc_lock); XXXSMP */
558 if (sess
&& sess
->s_ttyvp
&& ttycheckoutq(sess
->s_ttyp
, 0)) {
567 kprintf(fmt
, flags
, tp
, NULL
, ap
);
571 /* mutex_exit(proc_lock); XXXSMP */
578 * ttyprintf: send a message to a specific tty
580 * => should be used only by tty driver or anything that knows the
581 * underlying tty will not be revoked(2)'d away. [otherwise,
585 ttyprintf(struct tty
*tp
, const char *fmt
, ...)
589 /* No mutex needed; going to process TTY. */
591 kprintf(fmt
, TOTTY
, tp
, NULL
, ap
);
598 * db_printf: printf for DDB (via db_putchar)
602 db_printf(const char *fmt
, ...)
606 /* No mutex needed; DDB pauses all processors. */
608 kprintf(fmt
, TODDB
, NULL
, NULL
, ap
);
613 kprintf(fmt
, TOLOG
, NULL
, NULL
, ap
);
619 db_vprintf(const char *fmt
, va_list ap
)
622 /* No mutex needed; DDB pauses all processors. */
623 kprintf(fmt
, TODDB
, NULL
, NULL
, ap
);
625 kprintf(fmt
, TOLOG
, NULL
, NULL
, ap
);
631 kprintf_internal(const char *fmt
, int oflags
, void *vp
, char *sbuf
, ...)
636 (void)kprintf(fmt
, oflags
, vp
, sbuf
, ap
);
641 * Device autoconfiguration printf routines. These change their
642 * behavior based on the AB_* flags in boothowto. If AB_SILENT
643 * is set, messages never go to the console (but they still always
644 * go to the log). AB_VERBOSE overrides AB_SILENT.
648 * aprint_normal: Send to console unless AB_QUIET. Always goes
652 aprint_normal_internal(const char *prefix
, const char *fmt
, va_list ap
)
656 if ((boothowto
& (AB_SILENT
|AB_QUIET
)) == 0 ||
657 (boothowto
& AB_VERBOSE
) != 0)
663 kprintf_internal("%s: ", flags
, NULL
, NULL
, prefix
);
664 kprintf(fmt
, flags
, NULL
, NULL
, ap
);
673 aprint_normal(const char *fmt
, ...)
678 aprint_normal_internal(NULL
, fmt
, ap
);
683 aprint_normal_dev(device_t dv
, const char *fmt
, ...)
688 aprint_normal_internal(device_xname(dv
), fmt
, ap
);
693 aprint_normal_ifnet(struct ifnet
*ifp
, const char *fmt
, ...)
698 aprint_normal_internal(ifp
->if_xname
, fmt
, ap
);
703 * aprint_error: Send to console unless AB_QUIET. Always goes
704 * to the log. Also counts the number of times called so other
705 * parts of the kernel can report the number of errors during a
706 * given phase of system startup.
708 static int aprint_error_count
;
711 aprint_get_error_count(void)
717 count
= aprint_error_count
;
718 aprint_error_count
= 0;
726 aprint_error_internal(const char *prefix
, const char *fmt
, va_list ap
)
730 if ((boothowto
& (AB_SILENT
|AB_QUIET
)) == 0 ||
731 (boothowto
& AB_VERBOSE
) != 0)
736 aprint_error_count
++;
739 kprintf_internal("%s: ", flags
, NULL
, NULL
, prefix
);
740 kprintf(fmt
, flags
, NULL
, NULL
, ap
);
749 aprint_error(const char *fmt
, ...)
754 aprint_error_internal(NULL
, fmt
, ap
);
759 aprint_error_dev(device_t dv
, const char *fmt
, ...)
764 aprint_error_internal(device_xname(dv
), fmt
, ap
);
769 aprint_error_ifnet(struct ifnet
*ifp
, const char *fmt
, ...)
774 aprint_error_internal(ifp
->if_xname
, fmt
, ap
);
779 * aprint_naive: Send to console only if AB_QUIET. Never goes
783 aprint_naive_internal(const char *prefix
, const char *fmt
, va_list ap
)
786 if ((boothowto
& (AB_QUIET
|AB_SILENT
|AB_VERBOSE
)) != AB_QUIET
)
792 kprintf_internal("%s: ", TOCONS
, NULL
, NULL
, prefix
);
793 kprintf(fmt
, TOCONS
, NULL
, NULL
, ap
);
799 aprint_naive(const char *fmt
, ...)
804 aprint_naive_internal(NULL
, fmt
, ap
);
809 aprint_naive_dev(device_t dv
, const char *fmt
, ...)
814 aprint_naive_internal(device_xname(dv
), fmt
, ap
);
819 aprint_naive_ifnet(struct ifnet
*ifp
, const char *fmt
, ...)
824 aprint_naive_internal(ifp
->if_xname
, fmt
, ap
);
829 * aprint_verbose: Send to console only if AB_VERBOSE. Always
833 aprint_verbose_internal(const char *prefix
, const char *fmt
, va_list ap
)
837 if (boothowto
& AB_VERBOSE
)
843 kprintf_internal("%s: ", flags
, NULL
, NULL
, prefix
);
844 kprintf(fmt
, flags
, NULL
, NULL
, ap
);
853 aprint_verbose(const char *fmt
, ...)
858 aprint_verbose_internal(NULL
, fmt
, ap
);
863 aprint_verbose_dev(device_t dv
, const char *fmt
, ...)
868 aprint_verbose_internal(device_xname(dv
), fmt
, ap
);
873 aprint_verbose_ifnet(struct ifnet
*ifp
, const char *fmt
, ...)
878 aprint_verbose_internal(ifp
->if_xname
, fmt
, ap
);
883 * aprint_debug: Send to console and log only if AB_DEBUG.
886 aprint_debug_internal(const char *prefix
, const char *fmt
, va_list ap
)
889 if ((boothowto
& AB_DEBUG
) == 0)
895 kprintf_internal("%s: ", TOCONS
| TOLOG
, NULL
, NULL
, prefix
);
896 kprintf(fmt
, TOCONS
| TOLOG
, NULL
, NULL
, ap
);
902 aprint_debug(const char *fmt
, ...)
907 aprint_debug_internal(NULL
, fmt
, ap
);
912 aprint_debug_dev(device_t dv
, const char *fmt
, ...)
917 aprint_debug_internal(device_xname(dv
), fmt
, ap
);
922 aprint_debug_ifnet(struct ifnet
*ifp
, const char *fmt
, ...)
927 aprint_debug_internal(ifp
->if_xname
, fmt
, ap
);
932 printf_tolog(const char *fmt
, ...)
939 (void)kprintf(fmt
, TOLOG
, NULL
, NULL
, ap
);
946 * printf_nolog: Like printf(), but does not send message to the log.
950 printf_nolog(const char *fmt
, ...)
957 kprintf(fmt
, TOCONS
, NULL
, NULL
, ap
);
964 * normal kernel printf functions: printf, vprintf, snprintf, vsnprintf
968 * printf: print a message to the console and the log
971 printf(const char *fmt
, ...)
978 kprintf(fmt
, TOCONS
| TOLOG
, NULL
, NULL
, ap
);
988 * vprintf: print a message to the console and the log [already have
993 vprintf(const char *fmt
, va_list ap
)
998 kprintf(fmt
, TOCONS
| TOLOG
, NULL
, NULL
, ap
);
1007 * sprintf: print a message to a buffer
1010 sprintf(char *bf
, const char *fmt
, ...)
1016 retval
= kprintf(fmt
, TOBUFONLY
, NULL
, bf
, ap
);
1018 *(bf
+ retval
) = 0; /* null terminate */
1023 * vsprintf: print a message to a buffer [already have va_alist]
1027 vsprintf(char *bf
, const char *fmt
, va_list ap
)
1031 retval
= kprintf(fmt
, TOBUFONLY
, NULL
, bf
, ap
);
1032 *(bf
+ retval
) = 0; /* null terminate */
1037 * snprintf: print a message to a buffer
1040 snprintf(char *bf
, size_t size
, const char *fmt
, ...)
1050 retval
= kprintf(fmt
, TOBUFONLY
, &p
, bf
, ap
);
1052 *(p
) = 0; /* null terminate */
1057 * vsnprintf: print a message to a buffer [already have va_alist]
1060 vsnprintf(char *bf
, size_t size
, const char *fmt
, va_list ap
)
1068 retval
= kprintf(fmt
, TOBUFONLY
, &p
, bf
, ap
);
1069 *(p
) = 0; /* null terminate */
1074 * kprintf: scaled down version of printf(3).
1076 * this version based on vfprintf() from libc which was derived from
1077 * software contributed to Berkeley by Chris Torek.
1079 * NOTE: The kprintf mutex must be held if we're going TOBUF or TOCONS!
1083 * macros for converting digits to letters and vice versa
1085 #define to_digit(c) ((c) - '0')
1086 #define is_digit(c) ((unsigned)to_digit(c) <= 9)
1087 #define to_char(n) ((n) + '0')
1090 * flags used during conversion.
1092 #define ALT 0x001 /* alternate form */
1093 #define HEXPREFIX 0x002 /* add 0x or 0X prefix */
1094 #define LADJUST 0x004 /* left adjustment */
1095 #define LONGDBL 0x008 /* long double; unimplemented */
1096 #define LONGINT 0x010 /* long integer */
1097 #define QUADINT 0x020 /* quad integer */
1098 #define SHORTINT 0x040 /* short integer */
1099 #define MAXINT 0x080 /* intmax_t */
1100 #define PTRINT 0x100 /* intptr_t */
1101 #define SIZEINT 0x200 /* size_t */
1102 #define ZEROPAD 0x400 /* zero (as opposed to blank) pad */
1103 #define FPT 0x800 /* Floating point number */
1106 * To extend shorts properly, we need both signed and unsigned
1107 * argument extraction methods.
1110 (flags&MAXINT ? va_arg(ap, intmax_t) : \
1111 flags&PTRINT ? va_arg(ap, intptr_t) : \
1112 flags&SIZEINT ? va_arg(ap, ssize_t) : /* XXX */ \
1113 flags&QUADINT ? va_arg(ap, quad_t) : \
1114 flags&LONGINT ? va_arg(ap, long) : \
1115 flags&SHORTINT ? (long)(short)va_arg(ap, int) : \
1116 (long)va_arg(ap, int))
1118 (flags&MAXINT ? va_arg(ap, uintmax_t) : \
1119 flags&PTRINT ? va_arg(ap, uintptr_t) : \
1120 flags&SIZEINT ? va_arg(ap, size_t) : \
1121 flags&QUADINT ? va_arg(ap, u_quad_t) : \
1122 flags&LONGINT ? va_arg(ap, u_long) : \
1123 flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \
1124 (u_long)va_arg(ap, u_int))
1126 #define KPRINTF_PUTCHAR(C) { \
1127 if (oflags == TOBUFONLY) { \
1128 if ((vp != NULL) && (sbuf == tailp)) { \
1129 ret += 1; /* indicate error */ \
1134 putchar((C), oflags, (struct tty *)vp); \
1139 * Guts of kernel printf. Note, we already expect to be in a mutex!
1142 kprintf(const char *fmt0
, int oflags
, void *vp
, char *sbuf
, va_list ap
)
1144 const char *fmt
; /* format string */
1145 int ch
; /* character from fmt */
1146 int n
; /* handy integer (short term usage) */
1147 char *cp
; /* handy char pointer (short term usage) */
1148 int flags
; /* flags as above */
1149 int ret
; /* return value accumulator */
1150 int width
; /* width from format (%8d), or 0 */
1151 int prec
; /* precision from format (%.3d), or -1 */
1152 char sign
; /* sign prefix (' ', '+', '-', or \0) */
1154 u_quad_t _uquad
; /* integer arguments %[diouxX] */
1155 enum { OCT
, DEC
, HEX
} base
;/* base for [diouxX] conversion */
1156 int dprec
; /* a copy of prec if [diouxX], 0 otherwise */
1157 int realsz
; /* field size expanded by dprec */
1158 int size
; /* size of converted field or string */
1159 const char *xdigs
; /* digits for [xX] conversion */
1160 char bf
[KPRINTF_BUFSIZE
]; /* space for %c, %[diouxX] */
1161 char *tailp
; /* tail pointer for snprintf */
1163 tailp
= NULL
; /* XXX: shutup gcc */
1164 if (oflags
== TOBUFONLY
&& (vp
!= NULL
))
1165 tailp
= *(char **)vp
;
1167 cp
= NULL
; /* XXX: shutup gcc */
1168 size
= 0; /* XXX: shutup gcc */
1173 xdigs
= NULL
; /* XXX: shut up gcc warning */
1176 * Scan the format for conversions (`%' character).
1179 while (*fmt
!= '%' && *fmt
) {
1181 KPRINTF_PUTCHAR(*fmt
++);
1186 fmt
++; /* skip over '%' */
1195 reswitch
: switch (ch
) {
1198 * ``If the space and + flags both appear, the space
1199 * flag will be ignored.''
1210 * ``A negative field width argument is taken as a
1211 * - flag followed by a positive field width.''
1213 * They don't exclude field widths read from args.
1215 if ((width
= va_arg(ap
, int)) >= 0)
1226 if ((ch
= *fmt
++) == '*') {
1227 n
= va_arg(ap
, int);
1228 prec
= n
< 0 ? -1 : n
;
1232 while (is_digit(ch
)) {
1233 n
= 10 * n
+ to_digit(ch
);
1236 prec
= n
< 0 ? -1 : n
;
1240 * ``Note that 0 is taken as a flag, not as the
1241 * beginning of a field width.''
1246 case '1': case '2': case '3': case '4':
1247 case '5': case '6': case '7': case '8': case '9':
1250 n
= 10 * n
+ to_digit(ch
);
1252 } while (is_digit(ch
));
1279 *(cp
= bf
) = va_arg(ap
, int);
1289 if ((quad_t
)_uquad
< 0) {
1297 *va_arg(ap
, intmax_t *) = ret
;
1298 else if (flags
& PTRINT
)
1299 *va_arg(ap
, intptr_t *) = ret
;
1300 else if (flags
& SIZEINT
)
1301 *va_arg(ap
, ssize_t
*) = ret
;
1302 else if (flags
& QUADINT
)
1303 *va_arg(ap
, quad_t
*) = ret
;
1304 else if (flags
& LONGINT
)
1305 *va_arg(ap
, long *) = ret
;
1306 else if (flags
& SHORTINT
)
1307 *va_arg(ap
, short *) = ret
;
1309 *va_arg(ap
, int *) = ret
;
1310 continue; /* no output */
1320 * ``The argument shall be a pointer to void. The
1321 * value of the pointer is converted to a sequence
1322 * of printable characters, in an implementation-
1327 _uquad
= (u_long
)va_arg(ap
, void *);
1334 if ((cp
= va_arg(ap
, char *)) == NULL
)
1336 cp
= __UNCONST("(null)");
1339 * can't use strlen; can only look for the
1340 * NUL in the first `prec' characters, and
1341 * strlen() will go further.
1343 char *p
= memchr(cp
, 0, prec
);
1367 hex
: _uquad
= UARG();
1369 /* leading 0x/X only if non-zero */
1370 if (flags
& ALT
&& _uquad
!= 0)
1373 /* unsigned conversions */
1374 nosign
: sign
= '\0';
1376 * ``... diouXx conversions ... if a precision is
1377 * specified, the 0 flag will be ignored.''
1380 number
: if ((dprec
= prec
) >= 0)
1384 * ``The result of converting a zero value with an
1385 * explicit precision of zero is no characters.''
1388 cp
= bf
+ KPRINTF_BUFSIZE
;
1389 if (_uquad
!= 0 || prec
!= 0) {
1391 * Unsigned mod is hard, and unsigned mod
1392 * by a constant is easier than that by
1393 * a variable; hence this switch.
1398 *--cp
= to_char(_uquad
& 7);
1401 /* handle octal leading 0 */
1402 if (flags
& ALT
&& *cp
!= '0')
1407 /* many numbers are 1 digit */
1408 while (_uquad
>= 10) {
1409 *--cp
= to_char(_uquad
% 10);
1412 *--cp
= to_char(_uquad
);
1417 *--cp
= xdigs
[_uquad
& 15];
1424 cp
= __UNCONST("bug in kprintf: bad base");
1429 size
= bf
+ KPRINTF_BUFSIZE
- cp
;
1432 default: /* "%?" prints ?, unless ? is NUL */
1435 /* pretend it was %c with argument ch */
1444 * All reasonable formats wind up here. At this point, `cp'
1445 * points to a string which (if not flags&LADJUST) should be
1446 * padded out to `width' places. If flags&ZEROPAD, it should
1447 * first be prefixed by any sign or other prefix; otherwise,
1448 * it should be blank padded before the prefix is emitted.
1449 * After any left-hand padding and prefixing, emit zeroes
1450 * required by a decimal [diouxX] precision, then print the
1451 * string proper, then emit zeroes required by any leftover
1452 * floating precision; finally, if LADJUST, pad with blanks.
1454 * Compute actual size, so we know how much to pad.
1455 * size excludes decimal prec; realsz includes it.
1457 realsz
= dprec
> size
? dprec
: size
;
1460 else if (flags
& HEXPREFIX
)
1464 ret
+= width
> realsz
? width
: realsz
;
1466 /* right-adjusting blank padding */
1467 if ((flags
& (LADJUST
|ZEROPAD
)) == 0) {
1470 KPRINTF_PUTCHAR(' ');
1475 KPRINTF_PUTCHAR(sign
);
1476 } else if (flags
& HEXPREFIX
) {
1477 KPRINTF_PUTCHAR('0');
1478 KPRINTF_PUTCHAR(ch
);
1481 /* right-adjusting zero padding */
1482 if ((flags
& (LADJUST
|ZEROPAD
)) == ZEROPAD
) {
1485 KPRINTF_PUTCHAR('0');
1488 /* leading zeroes from decimal precision */
1491 KPRINTF_PUTCHAR('0');
1493 /* the string or number proper */
1495 KPRINTF_PUTCHAR(*cp
++);
1496 /* left-adjusting padding (always blank) */
1497 if (flags
& LADJUST
) {
1500 KPRINTF_PUTCHAR(' ');
1505 if ((oflags
== TOBUFONLY
) && (vp
!= NULL
))
1506 *(char **)vp
= sbuf
;