2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
27 * Mach Operating System
28 * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University
29 * All Rights Reserved.
31 * Permission to use, copy, modify and distribute this software and its
32 * documentation is hereby granted, provided that both the copyright
33 * notice and this permission notice appear in all copies of the
34 * software, derivative works or modified versions, and any portions
35 * thereof, and that both notices appear in supporting documentation.
37 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
38 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
39 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
41 * Carnegie Mellon requests users of this software to return to
43 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
44 * School of Computer Science
45 * Carnegie Mellon University
46 * Pittsburgh PA 15213-3890
48 * any improvements or extensions that they make and grant Carnegie Mellon
49 * the rights to redistribute these changes.
53 * Common code for printf et al.
55 * The calling routine typically takes a variable number of arguments,
56 * and passes the address of the first one. This implementation
57 * assumes a straightforward, stack implementation, aligned to the
58 * machine's wordsize. Increasing addresses are assumed to point to
59 * successive arguments (left-to-right), as is the case for a machine
60 * with a downward-growing stack with arguments pushed right-to-left.
62 * To write, for example, fprintf() using this routine, the code
64 * fprintf(fd, format, args)
68 * _doprnt(format, &args, fd);
71 * would suffice. (This example does not handle the fprintf's "return
72 * value" correctly, but who looks at the return value of fprintf
75 * This version implements the following printf features:
77 * %d decimal conversion
78 * %u unsigned conversion
79 * %x hexadecimal conversion
80 * %X hexadecimal conversion with capital letters
84 * %m.n field width, precision
85 * %-m.n left adjustment
87 * %*.* width and precision taken from arguments
89 * This version does not implement %f, %e, or %g. It accepts, but
90 * ignores, an `l' as in %ld, %lo, %lx, and %lu, and therefore will not
91 * work correctly on machines for which sizeof(long) != sizeof(int).
92 * It does not even parse %D, %O, or %U; you should be using %ld, %o and
93 * %lu if you mean long conversion.
95 * As mentioned, this version does not return any reasonable value.
97 * Permission is granted to use, modify, or propagate this code as
98 * long as this notice is incorporated.
100 * Steve Summit 3/25/87
104 * Added formats for decoding device registers:
106 * printf("reg = %b", regval, "<base><arg>*")
108 * where <base> is the output base expressed as a control character:
109 * i.e. '\10' gives octal, '\20' gives hex. Each <arg> is a sequence of
110 * characters, the first of which gives the bit number to be inspected
111 * (origin 1), and the rest (up to a control character (<= 32)) give the
112 * name of the register. Thus
113 * printf("reg = %b\n", 3, "\10\2BITTWO\1BITONE")
115 * reg = 3<BITTWO,BITONE>
117 * If the second character in <arg> is also a control character, it
118 * indicates the last bit of a bit field. In this case, printf will extract
119 * bits <1> to <2> and print it. Characters following the second control
120 * character are printed before the bit field.
121 * printf("reg = %b\n", 0xb, "\10\4\3FIELD1=\2BITTWO\1BITONE")
123 * reg = b<FIELD1=2,BITONE>
125 * The %B format is like %b but the bits are numbered from the most
126 * significant (the bit weighted 31), which is called 1, to the least
127 * significant, called 32.
130 * Added for general use:
131 * # prefix for alternate format:
133 * leading 0 for octal
134 * + print '+' if positive
135 * blank print ' ' if positive
137 * z signed hexadecimal
139 * n unsigned, 'radix'
141 * D,U,O,Z same as corresponding lower-case versions
145 #include <platforms.h>
146 #include <mach/boolean.h>
148 #include <kern/cpu_number.h>
149 #include <kern/lock.h>
150 #include <kern/thread.h>
151 #include <kern/sched_prim.h>
152 #include <kern/misc_protos.h>
155 #include <mach_assert.h>
157 #include <sys/msgbuf.h>
161 #include <ppc/Firmware.h>
165 * Forward declarations
168 register unsigned int u
,
173 #define isdigit(d) ((d) >= '0' && (d) <= '9')
174 #define Ctod(c) ((c) - '0')
176 #define MAXBUF (sizeof(long int) * 8) /* enough for binary */
180 register unsigned int u
, /* number to print */
184 char buf
[MAXBUF
]; /* build number here */
185 register char * p
= &buf
[MAXBUF
-1];
186 static char digs
[] = "0123456789abcdef";
189 *p
-- = digs
[u
% base
];
193 while (++p
!= &buf
[MAXBUF
])
198 boolean_t _doprnt_truncates
= FALSE
;
202 register const char *fmt
,
204 /* character output routine */
206 int radix
) /* default radix - for '%r' */
216 boolean_t altfmt
, truncate
;
221 while ((c
= *fmt
) != '\0') {
265 length
= 10 * length
+ Ctod(c
);
270 length
= va_arg(*argp
, int);
283 prec
= 10 * prec
+ Ctod(c
);
288 prec
= va_arg(*argp
, int);
294 c
= *++fmt
; /* need it if sizeof(int) < sizeof(long) */
297 capitals
=0; /* Assume lower case printing */
307 u
= va_arg(*argp
, unsigned long);
308 p
= va_arg(*argp
, char *);
310 printnum(u
, base
, putc
);
316 while ((i
= *p
++) != '\0') {
333 for (; (c
= *p
) > 32; p
++)
335 printnum((unsigned)( (u
>>(j
-1)) & ((2<<(i
-j
))-1)),
338 else if (u
& (1<<(i
-1))) {
345 for (; (c
= *p
) > 32; p
++)
359 c
= va_arg(*argp
, int);
369 prec
= 0x7fffffff; /* MAXINT */
371 p
= va_arg(*argp
, char *);
376 if (length
> 0 && !ladjust
) {
380 for (; *p
!= '\0' && n
< prec
; p
++)
394 if (++n
> prec
|| (length
> 0 && n
> length
))
400 if (n
< length
&& ladjust
) {
411 truncate
= _doprnt_truncates
;
417 truncate
= _doprnt_truncates
;
423 truncate
= _doprnt_truncates
;
431 truncate
= _doprnt_truncates
;
437 capitals
=16; /* Print in upper case */
441 truncate
= _doprnt_truncates
;
447 capitals
=16; /* Print in upper case */
451 truncate
= _doprnt_truncates
;
457 truncate
= _doprnt_truncates
;
463 n
= va_arg(*argp
, long);
466 sign_char
= plus_sign
;
475 u
= va_arg(*argp
, unsigned long);
480 char buf
[MAXBUF
]; /* build number here */
481 register char * p
= &buf
[MAXBUF
-1];
482 static char digits
[] = "0123456789abcdef0123456789ABCDEF";
485 if (truncate
) u
= (long)((int)(u
));
487 if (u
!= 0 && altfmt
) {
495 /* Print in the correct case */
496 *p
-- = digits
[(u
% base
)+capitals
];
500 length
-= (&buf
[MAXBUF
-1] - p
);
504 length
-= strlen((const char *) prefix
);
506 if (padc
== ' ' && !ladjust
) {
507 /* blank padding goes before prefix */
508 while (--length
>= 0)
517 /* zero padding goes after sign and prefix */
518 while (--length
>= 0)
521 while (++p
!= &buf
[MAXBUF
])
525 while (--length
>= 0)
543 boolean_t new_printf_cpu_number
= FALSE
;
544 #endif /* MP_PRINTF */
547 decl_simple_lock_data(,printf_lock
)
548 decl_mutex_data(,sprintf_lock
)
554 * Lock is only really needed after the first thread is created.
556 simple_lock_init(&printf_lock
, ETAP_MISC_PRINTF
);
557 mutex_init(&sprintf_lock
, ETAP_MISC_PRINTF
);
560 /* derived from boot_gets */
568 char *strmax
= str
+ maxlen
- 1; /* allow space for trailing 0 */
596 if (c
>= ' ' && c
< '\177') {
602 printf("%c", '\007'); /* beep */
613 extern unsigned int debug_mode
, disableDebugOuput
, disableConsoleOutput
;
615 if ((debug_mode
&& !disableDebugOuput
) || !disableConsoleOutput
)
624 printf(const char *fmt
, ...)
628 disable_preemption();
629 va_start(listp
, fmt
);
630 _doprnt(fmt
, &listp
, conslog_putc
, 16);
635 static char *copybyte_str
;
641 *copybyte_str
++ = byte
;
642 *copybyte_str
= '\0';
646 sprintf(char *buf
, const char *fmt
, ...)
650 va_start(listp
, fmt
);
651 mutex_lock(&sprintf_lock
);
653 _doprnt(fmt
, &listp
, copybyte
, 16);
654 mutex_unlock(&sprintf_lock
);