xref: /csrg-svn/sys/stand.att/printf.c (revision 49168)
148987Sbostic /*-
248987Sbostic  * Copyright (c) 1991 The Regents of the University of California.
348987Sbostic  * All rights reserved.
448987Sbostic  *
548987Sbostic  * %sccs.include.redist.c%
648987Sbostic  *
7*49168Swilliam  *	@(#)printf.c	5.5 (Berkeley) 05/05/91
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>
34*49168Swilliam #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__
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;
10149118Sbostic 		case 'D':
10249118Sbostic 			lflag = 1;
10349118Sbostic 			/* FALLTHROUGH */
10448987Sbostic 		case 'd':
10548989Sbostic 			ul = lflag ?
10648987Sbostic 			    va_arg(ap, long) : va_arg(ap, int);
10748989Sbostic 			if ((long)ul < 0) {
10848987Sbostic 				putchar('-');
10948989Sbostic 				ul = -(long)ul;
11048987Sbostic 			}
11149118Sbostic 			kprintn(ul, 10);
11248987Sbostic 			break;
11349118Sbostic 		case 'O':
11449118Sbostic 			lflag = 1;
11549118Sbostic 			/* FALLTHROUGH */
11648987Sbostic 		case 'o':
11748989Sbostic 			ul = lflag ?
11849118Sbostic 			    va_arg(ap, u_long) : va_arg(ap, u_int);
11949118Sbostic 			kprintn(ul, 8);
12048987Sbostic 			break;
12149118Sbostic 		case 'U':
12249118Sbostic 			lflag = 1;
12349118Sbostic 			/* FALLTHROUGH */
12448987Sbostic 		case 'u':
12548989Sbostic 			ul = lflag ?
12649118Sbostic 			    va_arg(ap, u_long) : va_arg(ap, u_int);
12749118Sbostic 			kprintn(ul, 10);
12848987Sbostic 			break;
12949118Sbostic 		case 'X':
13049118Sbostic 			lflag = 1;
13149118Sbostic 			/* FALLTHROUGH */
13248987Sbostic 		case 'x':
13348989Sbostic 			ul = lflag ?
13449118Sbostic 			    va_arg(ap, u_long) : va_arg(ap, u_int);
13549118Sbostic 			kprintn(ul, 16);
13648987Sbostic 			break;
13748987Sbostic 		default:
13848987Sbostic 			putchar('%');
13948987Sbostic 			if (lflag)
14048987Sbostic 				putchar('l');
14148987Sbostic 			putchar(ch);
14248987Sbostic 		}
14348987Sbostic 	}
14448987Sbostic 	va_end(ap);
14548987Sbostic }
14648987Sbostic 
14748987Sbostic static void
14849118Sbostic kprintn(ul, base)
14948989Sbostic 	unsigned long ul;
15048987Sbostic 	int base;
15148987Sbostic {
152*49168Swilliam 					/* hold a long in base 8 */
153*49168Swilliam 	char *p, buf[(sizeof(long) * NBBY / 3) + 1];
15448987Sbostic 
15548987Sbostic 	p = buf;
15648987Sbostic 	do {
15748989Sbostic 		*p++ = "0123456789abcdef"[ul % base];
15848989Sbostic 	} while (ul /= base);
15948987Sbostic 	do {
16048987Sbostic 		putchar(*--p);
16148987Sbostic 	} while (p > buf);
16248987Sbostic }
163