4.4BSD snapshot (revision 8.1); add 1993 to copyright
[unix-history] / usr / src / sys / stand.att / printf.c
CommitLineData
e157cc69 1/*-
80409bdc
KB
2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
e157cc69
KB
4 *
5 * %sccs.include.redist.c%
6 *
80409bdc 7 * @(#)printf.c 8.1 (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 33#include <sys/cdefs.h>
11220997 34#include <sys/types.h>
81c658ae
KB
35
36/*
37 * Note that stdarg.h and the ANSI style va_start macro is used for both
38 * ANSI and traditional C compilers.
39 */
40#define KERNEL
41#include <machine/stdarg.h>
42#undef KERNEL
e157cc69 43
81c658ae 44static void kprintn __P((u_long, int));
e157cc69
KB
45
46void
47#if __STDC__
48printf(const char *fmt, ...)
49#else
81c658ae 50printf(fmt /* , va_alist */)
e157cc69 51 char *fmt;
e157cc69
KB
52#endif
53{
54 register char *p;
55 register int ch, n;
1e934460 56 unsigned long ul;
e157cc69 57 int lflag, set;
e157cc69 58 va_list ap;
81c658ae 59
e157cc69 60 va_start(ap, fmt);
e157cc69
KB
61 for (;;) {
62 while ((ch = *fmt++) != '%') {
63 if (ch == '\0')
64 return;
65 putchar(ch);
66 }
67 lflag = 0;
68reswitch: switch (ch = *fmt++) {
69 case 'l':
70 lflag = 1;
71 goto reswitch;
72 case 'b':
1e934460 73 ul = va_arg(ap, int);
e157cc69 74 p = va_arg(ap, char *);
81c658ae 75 kprintn(ul, *p++);
e157cc69 76
1e934460 77 if (!ul)
e157cc69
KB
78 break;
79
80 for (set = 0; n = *p++;) {
1e934460 81 if (ul & (1 << (n - 1))) {
e157cc69
KB
82 putchar(set ? ',' : '<');
83 for (; (n = *p) > ' '; ++p)
84 putchar(n);
85 set = 1;
86 } else
87 for (; *p > ' '; ++p);
88 }
89 if (set)
90 putchar('>');
91 break;
92 case 'c':
93 ch = va_arg(ap, int);
94 putchar(ch & 0x7f);
95 break;
96 case 's':
97 p = va_arg(ap, char *);
98 while (ch = *p++)
99 putchar(ch);
100 break;
101 case 'd':
1e934460 102 ul = lflag ?
e157cc69 103 va_arg(ap, long) : va_arg(ap, int);
1e934460 104 if ((long)ul < 0) {
e157cc69 105 putchar('-');
1e934460 106 ul = -(long)ul;
e157cc69 107 }
81c658ae 108 kprintn(ul, 10);
e157cc69
KB
109 break;
110 case 'o':
1e934460 111 ul = lflag ?
81c658ae
KB
112 va_arg(ap, u_long) : va_arg(ap, u_int);
113 kprintn(ul, 8);
e157cc69
KB
114 break;
115 case 'u':
1e934460 116 ul = lflag ?
81c658ae
KB
117 va_arg(ap, u_long) : va_arg(ap, u_int);
118 kprintn(ul, 10);
e157cc69
KB
119 break;
120 case 'x':
1e934460 121 ul = lflag ?
81c658ae
KB
122 va_arg(ap, u_long) : va_arg(ap, u_int);
123 kprintn(ul, 16);
e157cc69
KB
124 break;
125 default:
126 putchar('%');
127 if (lflag)
128 putchar('l');
129 putchar(ch);
130 }
131 }
132 va_end(ap);
133}
134
135static void
81c658ae 136kprintn(ul, base)
1e934460 137 unsigned long ul;
e157cc69
KB
138 int base;
139{
11220997
WN
140 /* hold a long in base 8 */
141 char *p, buf[(sizeof(long) * NBBY / 3) + 1];
e157cc69
KB
142
143 p = buf;
144 do {
1e934460
KB
145 *p++ = "0123456789abcdef"[ul % base];
146 } while (ul /= base);
e157cc69
KB
147 do {
148 putchar(*--p);
149 } while (p > buf);
150}