move ttyprintf to subr_prf.c
[unix-history] / usr / src / sys / stand.att / printf.c
CommitLineData
e157cc69
KB
1/*-
2 * Copyright (c) 1991 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 *
81c658ae 7 * @(#)printf.c 5.4 (Berkeley) %G%
e157cc69
KB
8 */
9
e157cc69 10/*
8cd347e4 11 * Scaled down version of printf(3).
e157cc69 12 *
81c658ae 13 * One additional format:
e157cc69 14 *
81c658ae 15 * The format %b is supported to decode error registers.
e157cc69
KB
16 * Its usage is:
17 *
18 * printf("reg=%b\n", regval, "<base><arg>*");
19 *
20 * where <base> is the output base expressed as a control character, e.g.
21 * \10 gives octal; \20 gives hex. Each arg is a sequence of characters,
22 * the first of which gives the bit number to be inspected (origin 1), and
23 * the next characters (up to a control character, i.e. a character <= 32),
24 * give the name of the register. Thus:
25 *
26 * printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
27 *
28 * would produce output:
29 *
30 * reg=3<BITTWO,BITONE>
31 */
32
81c658ae
KB
33#include <sys/cdefs.h>
34
35/*
36 * Note that stdarg.h and the ANSI style va_start macro is used for both
37 * ANSI and traditional C compilers.
38 */
39#define KERNEL
40#include <machine/stdarg.h>
41#undef KERNEL
e157cc69 42
81c658ae 43static void kprintn __P((u_long, int));
e157cc69
KB
44
45void
46#if __STDC__
47printf(const char *fmt, ...)
48#else
81c658ae 49printf(fmt /* , va_alist */)
e157cc69 50 char *fmt;
e157cc69
KB
51#endif
52{
53 register char *p;
54 register int ch, n;
1e934460 55 unsigned long ul;
e157cc69 56 int lflag, set;
e157cc69 57 va_list ap;
81c658ae 58
e157cc69 59 va_start(ap, fmt);
e157cc69
KB
60 for (;;) {
61 while ((ch = *fmt++) != '%') {
62 if (ch == '\0')
63 return;
64 putchar(ch);
65 }
66 lflag = 0;
67reswitch: switch (ch = *fmt++) {
68 case 'l':
69 lflag = 1;
70 goto reswitch;
71 case 'b':
1e934460 72 ul = va_arg(ap, int);
e157cc69 73 p = va_arg(ap, char *);
81c658ae 74 kprintn(ul, *p++);
e157cc69 75
1e934460 76 if (!ul)
e157cc69
KB
77 break;
78
79 for (set = 0; n = *p++;) {
1e934460 80 if (ul & (1 << (n - 1))) {
e157cc69
KB
81 putchar(set ? ',' : '<');
82 for (; (n = *p) > ' '; ++p)
83 putchar(n);
84 set = 1;
85 } else
86 for (; *p > ' '; ++p);
87 }
88 if (set)
89 putchar('>');
90 break;
91 case 'c':
92 ch = va_arg(ap, int);
93 putchar(ch & 0x7f);
94 break;
95 case 's':
96 p = va_arg(ap, char *);
97 while (ch = *p++)
98 putchar(ch);
99 break;
81c658ae
KB
100 case 'D':
101 lflag = 1;
102 /* FALLTHROUGH */
e157cc69 103 case 'd':
1e934460 104 ul = lflag ?
e157cc69 105 va_arg(ap, long) : va_arg(ap, int);
1e934460 106 if ((long)ul < 0) {
e157cc69 107 putchar('-');
1e934460 108 ul = -(long)ul;
e157cc69 109 }
81c658ae 110 kprintn(ul, 10);
e157cc69 111 break;
81c658ae
KB
112 case 'O':
113 lflag = 1;
114 /* FALLTHROUGH */
e157cc69 115 case 'o':
1e934460 116 ul = lflag ?
81c658ae
KB
117 va_arg(ap, u_long) : va_arg(ap, u_int);
118 kprintn(ul, 8);
e157cc69 119 break;
81c658ae
KB
120 case 'U':
121 lflag = 1;
122 /* FALLTHROUGH */
e157cc69 123 case 'u':
1e934460 124 ul = lflag ?
81c658ae
KB
125 va_arg(ap, u_long) : va_arg(ap, u_int);
126 kprintn(ul, 10);
e157cc69 127 break;
81c658ae
KB
128 case 'X':
129 lflag = 1;
130 /* FALLTHROUGH */
e157cc69 131 case 'x':
1e934460 132 ul = lflag ?
81c658ae
KB
133 va_arg(ap, u_long) : va_arg(ap, u_int);
134 kprintn(ul, 16);
e157cc69
KB
135 break;
136 default:
137 putchar('%');
138 if (lflag)
139 putchar('l');
140 putchar(ch);
141 }
142 }
143 va_end(ap);
144}
145
146static void
81c658ae 147kprintn(ul, base)
1e934460 148 unsigned long ul;
e157cc69
KB
149 int base;
150{
151 char *p, buf[11]; /* hold 2^32 in base 8 */
152
153 p = buf;
154 do {
1e934460
KB
155 *p++ = "0123456789abcdef"[ul % base];
156 } while (ul /= base);
e157cc69
KB
157 do {
158 putchar(*--p);
159 } while (p > buf);
160}