148987Sbostic /*-
2*63370Sbostic * Copyright (c) 1991, 1993
3*63370Sbostic * The Regents of the University of California. All rights reserved.
448987Sbostic *
548987Sbostic * %sccs.include.redist.c%
648987Sbostic *
7*63370Sbostic * @(#)printf.c 8.1 (Berkeley) 06/11/93
848987Sbostic */
948987Sbostic
1048987Sbostic /*
1148988Sbostic * Scaled down version of printf(3).
1248987Sbostic *
1349118Sbostic * One additional format:
1448987Sbostic *
1549118Sbostic * The format %b is supported to decode error registers.
1648987Sbostic * Its usage is:
1748987Sbostic *
1848987Sbostic * printf("reg=%b\n", regval, "<base><arg>*");
1948987Sbostic *
2048987Sbostic * where <base> is the output base expressed as a control character, e.g.
2148987Sbostic * \10 gives octal; \20 gives hex. Each arg is a sequence of characters,
2248987Sbostic * the first of which gives the bit number to be inspected (origin 1), and
2348987Sbostic * the next characters (up to a control character, i.e. a character <= 32),
2448987Sbostic * give the name of the register. Thus:
2548987Sbostic *
2648987Sbostic * printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
2748987Sbostic *
2848987Sbostic * would produce output:
2948987Sbostic *
3048987Sbostic * reg=3<BITTWO,BITONE>
3148987Sbostic */
3248987Sbostic
3349118Sbostic #include <sys/cdefs.h>
3449168Swilliam #include <sys/types.h>
3548987Sbostic
3649118Sbostic /*
3749118Sbostic * Note that stdarg.h and the ANSI style va_start macro is used for both
3849118Sbostic * ANSI and traditional C compilers.
3949118Sbostic */
4049118Sbostic #define KERNEL
4149118Sbostic #include <machine/stdarg.h>
4249118Sbostic #undef KERNEL
4348987Sbostic
4449118Sbostic static void kprintn __P((u_long, int));
4549118Sbostic
4648987Sbostic void
4748987Sbostic #if __STDC__
printf(const char * fmt,...)4848987Sbostic printf(const char *fmt, ...)
4948987Sbostic #else
5049118Sbostic printf(fmt /* , va_alist */)
5148987Sbostic char *fmt;
5248987Sbostic #endif
5348987Sbostic {
5448987Sbostic register char *p;
5548987Sbostic register int ch, n;
5648989Sbostic unsigned long ul;
5748987Sbostic int lflag, set;
5849118Sbostic va_list ap;
5948987Sbostic
6048987Sbostic va_start(ap, fmt);
6148987Sbostic for (;;) {
6248987Sbostic while ((ch = *fmt++) != '%') {
6348987Sbostic if (ch == '\0')
6448987Sbostic return;
6548987Sbostic putchar(ch);
6648987Sbostic }
6748987Sbostic lflag = 0;
6848987Sbostic reswitch: switch (ch = *fmt++) {
6948987Sbostic case 'l':
7048987Sbostic lflag = 1;
7148987Sbostic goto reswitch;
7248987Sbostic case 'b':
7348989Sbostic ul = va_arg(ap, int);
7448987Sbostic p = va_arg(ap, char *);
7549118Sbostic kprintn(ul, *p++);
7648987Sbostic
7748989Sbostic if (!ul)
7848987Sbostic break;
7948987Sbostic
8048987Sbostic for (set = 0; n = *p++;) {
8148989Sbostic if (ul & (1 << (n - 1))) {
8248987Sbostic putchar(set ? ',' : '<');
8348987Sbostic for (; (n = *p) > ' '; ++p)
8448987Sbostic putchar(n);
8548987Sbostic set = 1;
8648987Sbostic } else
8748987Sbostic for (; *p > ' '; ++p);
8848987Sbostic }
8948987Sbostic if (set)
9048987Sbostic putchar('>');
9148987Sbostic break;
9248987Sbostic case 'c':
9348987Sbostic ch = va_arg(ap, int);
9448987Sbostic putchar(ch & 0x7f);
9548987Sbostic break;
9648987Sbostic case 's':
9748987Sbostic p = va_arg(ap, char *);
9848987Sbostic while (ch = *p++)
9948987Sbostic putchar(ch);
10048987Sbostic break;
10148987Sbostic case 'd':
10248989Sbostic ul = lflag ?
10348987Sbostic va_arg(ap, long) : va_arg(ap, int);
10448989Sbostic if ((long)ul < 0) {
10548987Sbostic putchar('-');
10648989Sbostic ul = -(long)ul;
10748987Sbostic }
10849118Sbostic kprintn(ul, 10);
10948987Sbostic break;
11048987Sbostic case 'o':
11148989Sbostic ul = lflag ?
11249118Sbostic va_arg(ap, u_long) : va_arg(ap, u_int);
11349118Sbostic kprintn(ul, 8);
11448987Sbostic break;
11548987Sbostic case 'u':
11648989Sbostic ul = lflag ?
11749118Sbostic va_arg(ap, u_long) : va_arg(ap, u_int);
11849118Sbostic kprintn(ul, 10);
11948987Sbostic break;
12048987Sbostic case 'x':
12148989Sbostic ul = lflag ?
12249118Sbostic va_arg(ap, u_long) : va_arg(ap, u_int);
12349118Sbostic kprintn(ul, 16);
12448987Sbostic break;
12548987Sbostic default:
12648987Sbostic putchar('%');
12748987Sbostic if (lflag)
12848987Sbostic putchar('l');
12948987Sbostic putchar(ch);
13048987Sbostic }
13148987Sbostic }
13248987Sbostic va_end(ap);
13348987Sbostic }
13448987Sbostic
13548987Sbostic static void
kprintn(ul,base)13649118Sbostic kprintn(ul, base)
13748989Sbostic unsigned long ul;
13848987Sbostic int base;
13948987Sbostic {
14049168Swilliam /* hold a long in base 8 */
14149168Swilliam char *p, buf[(sizeof(long) * NBBY / 3) + 1];
14248987Sbostic
14348987Sbostic p = buf;
14448987Sbostic do {
14548989Sbostic *p++ = "0123456789abcdef"[ul % base];
14648989Sbostic } while (ul /= base);
14748987Sbostic do {
14848987Sbostic putchar(*--p);
14948987Sbostic } while (p > buf);
15048987Sbostic }
151