|
|
1.1 root 1: /*-
2: * Copyright (c) 1991 The Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice, this list of conditions and the following disclaimer in the
12: * documentation and/or other materials provided with the distribution.
13: * 3. All advertising materials mentioning features or use of this software
14: * must display the following acknowledgement:
15: * This product includes software developed by the University of
16: * California, Berkeley and its contributors.
17: * 4. Neither the name of the University nor the names of its contributors
18: * may be used to endorse or promote products derived from this software
19: * without specific prior written permission.
20: *
21: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31: * SUCH DAMAGE.
32: *
33: * @(#)printf.c 5.6 (Berkeley) 5/25/91
34: */
35:
36: /*
37: * Scaled down version of printf(3).
38: *
39: * One additional format:
40: *
41: * The format %b is supported to decode error registers.
42: * Its usage is:
43: *
44: * printf("reg=%b\n", regval, "<base><arg>*");
45: *
46: * where <base> is the output base expressed as a control character, e.g.
47: * \10 gives octal; \20 gives hex. Each arg is a sequence of characters,
48: * the first of which gives the bit number to be inspected (origin 1), and
49: * the next characters (up to a control character, i.e. a character <= 32),
50: * give the name of the register. Thus:
51: *
52: * printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
53: *
54: * would produce output:
55: *
56: * reg=3<BITTWO,BITONE>
57: */
58:
59: #include <sys/cdefs.h>
60: #include <sys/types.h>
61:
62: /*
63: * Note that stdarg.h and the ANSI style va_start macro is used for both
64: * ANSI and traditional C compilers.
65: */
66: #define KERNEL
67: #include <machine/stdarg.h>
68: #undef KERNEL
69:
70: static void kprintn __P((u_long, int));
71:
72: void
73: #if __STDC__
74: printf(const char *fmt, ...)
75: #else
76: printf(fmt /* , va_alist */)
77: char *fmt;
78: #endif
79: {
80: register char *p;
81: register int ch, n;
82: unsigned long ul;
83: int lflag, set;
84: va_list ap;
85:
86: va_start(ap, fmt);
87: for (;;) {
88: while ((ch = *fmt++) != '%') {
89: if (ch == '\0')
90: return;
91: putchar(ch);
92: }
93: lflag = 0;
94: reswitch: switch (ch = *fmt++) {
95: case 'l':
96: lflag = 1;
97: goto reswitch;
98: case 'b':
99: ul = va_arg(ap, int);
100: p = va_arg(ap, char *);
101: kprintn(ul, *p++);
102:
103: if (!ul)
104: break;
105:
106: for (set = 0; n = *p++;) {
107: if (ul & (1 << (n - 1))) {
108: putchar(set ? ',' : '<');
109: for (; (n = *p) > ' '; ++p)
110: putchar(n);
111: set = 1;
112: } else
113: for (; *p > ' '; ++p);
114: }
115: if (set)
116: putchar('>');
117: break;
118: case 'c':
119: ch = va_arg(ap, int);
120: putchar(ch & 0x7f);
121: break;
122: case 's':
123: p = va_arg(ap, char *);
124: while (ch = *p++)
125: putchar(ch);
126: break;
127: case 'd':
128: ul = lflag ?
129: va_arg(ap, long) : va_arg(ap, int);
130: if ((long)ul < 0) {
131: putchar('-');
132: ul = -(long)ul;
133: }
134: kprintn(ul, 10);
135: break;
136: case 'o':
137: ul = lflag ?
138: va_arg(ap, u_long) : va_arg(ap, u_int);
139: kprintn(ul, 8);
140: break;
141: case 'u':
142: ul = lflag ?
143: va_arg(ap, u_long) : va_arg(ap, u_int);
144: kprintn(ul, 10);
145: break;
146: case 'x':
147: ul = lflag ?
148: va_arg(ap, u_long) : va_arg(ap, u_int);
149: kprintn(ul, 16);
150: break;
151: default:
152: putchar('%');
153: if (lflag)
154: putchar('l');
155: putchar(ch);
156: }
157: }
158: va_end(ap);
159: }
160:
161: static void
162: kprintn(ul, base)
163: unsigned long ul;
164: int base;
165: {
166: /* hold a long in base 8 */
167: char *p, buf[(sizeof(long) * NBBY / 3) + 1];
168:
169: p = buf;
170: do {
171: *p++ = "0123456789abcdef"[ul % base];
172: } while (ul /= base);
173: do {
174: putchar(*--p);
175: } while (p > buf);
176: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.