xref: /csrg-svn/sys/stand/printf.c (revision 63370)
163277Smckusick /*-
2*63370Sbostic  * Copyright (c) 1993
3*63370Sbostic  *	The Regents of the University of California.  All rights reserved.
463277Smckusick  *
563277Smckusick  * %sccs.include.redist.c%
663277Smckusick  *
7*63370Sbostic  *	@(#)printf.c	8.1 (Berkeley) 06/11/93
863277Smckusick  */
963277Smckusick 
1063277Smckusick /*
1163277Smckusick  * Scaled down version of printf(3).
1263277Smckusick  *
1363277Smckusick  * One additional format:
1463277Smckusick  *
1563277Smckusick  * The format %b is supported to decode error registers.
1663277Smckusick  * Its usage is:
1763277Smckusick  *
1863277Smckusick  *	printf("reg=%b\n", regval, "<base><arg>*");
1963277Smckusick  *
2063277Smckusick  * where <base> is the output base expressed as a control character, e.g.
2163277Smckusick  * \10 gives octal; \20 gives hex.  Each arg is a sequence of characters,
2263277Smckusick  * the first of which gives the bit number to be inspected (origin 1), and
2363277Smckusick  * the next characters (up to a control character, i.e. a character <= 32),
2463277Smckusick  * give the name of the register.  Thus:
2563277Smckusick  *
2663277Smckusick  *	printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
2763277Smckusick  *
2863277Smckusick  * would produce output:
2963277Smckusick  *
3063277Smckusick  *	reg=3<BITTWO,BITONE>
3163277Smckusick  */
3263277Smckusick 
3363277Smckusick #include <sys/cdefs.h>
3463277Smckusick #include <sys/types.h>
3563277Smckusick 
3663277Smckusick /*
3763277Smckusick  * Note that stdarg.h and the ANSI style va_start macro is used for both
3863277Smckusick  * ANSI and traditional C compilers.
3963277Smckusick  */
4063277Smckusick #define KERNEL
4163277Smckusick #include <machine/stdarg.h>
4263277Smckusick #undef KERNEL
4363277Smckusick 
4463277Smckusick static void kprintn __P((u_long, int));
4563277Smckusick 
4663277Smckusick void
4763277Smckusick #if __STDC__
printf(const char * fmt,...)4863277Smckusick printf(const char *fmt, ...)
4963277Smckusick #else
5063277Smckusick printf(fmt /* , va_alist */)
5163277Smckusick 	char *fmt;
5263277Smckusick #endif
5363277Smckusick {
5463277Smckusick 	register char *p;
5563277Smckusick 	register int ch, n;
5663277Smckusick 	unsigned long ul;
5763277Smckusick 	int lflag, set;
5863277Smckusick 	va_list ap;
5963277Smckusick 
6063277Smckusick 	va_start(ap, fmt);
6163277Smckusick 	for (;;) {
6263277Smckusick 		while ((ch = *fmt++) != '%') {
6363277Smckusick 			if (ch == '\0')
6463277Smckusick 				return;
6563277Smckusick 			putchar(ch);
6663277Smckusick 		}
6763277Smckusick 		lflag = 0;
6863277Smckusick reswitch:	switch (ch = *fmt++) {
6963277Smckusick 		case 'l':
7063277Smckusick 			lflag = 1;
7163277Smckusick 			goto reswitch;
7263277Smckusick 		case 'b':
7363277Smckusick 			ul = va_arg(ap, int);
7463277Smckusick 			p = va_arg(ap, char *);
7563277Smckusick 			kprintn(ul, *p++);
7663277Smckusick 
7763277Smckusick 			if (!ul)
7863277Smckusick 				break;
7963277Smckusick 
8063277Smckusick 			for (set = 0; n = *p++;) {
8163277Smckusick 				if (ul & (1 << (n - 1))) {
8263277Smckusick 					putchar(set ? ',' : '<');
8363277Smckusick 					for (; (n = *p) > ' '; ++p)
8463277Smckusick 						putchar(n);
8563277Smckusick 					set = 1;
8663277Smckusick 				} else
8763277Smckusick 					for (; *p > ' '; ++p);
8863277Smckusick 			}
8963277Smckusick 			if (set)
9063277Smckusick 				putchar('>');
9163277Smckusick 			break;
9263277Smckusick 		case 'c':
9363277Smckusick 			ch = va_arg(ap, int);
9463277Smckusick 				putchar(ch & 0x7f);
9563277Smckusick 			break;
9663277Smckusick 		case 's':
9763277Smckusick 			p = va_arg(ap, char *);
9863277Smckusick 			while (ch = *p++)
9963277Smckusick 				putchar(ch);
10063277Smckusick 			break;
10163277Smckusick 		case 'd':
10263277Smckusick 			ul = lflag ?
10363277Smckusick 			    va_arg(ap, long) : va_arg(ap, int);
10463277Smckusick 			if ((long)ul < 0) {
10563277Smckusick 				putchar('-');
10663277Smckusick 				ul = -(long)ul;
10763277Smckusick 			}
10863277Smckusick 			kprintn(ul, 10);
10963277Smckusick 			break;
11063277Smckusick 		case 'o':
11163277Smckusick 			ul = lflag ?
11263277Smckusick 			    va_arg(ap, u_long) : va_arg(ap, u_int);
11363277Smckusick 			kprintn(ul, 8);
11463277Smckusick 			break;
11563277Smckusick 		case 'u':
11663277Smckusick 			ul = lflag ?
11763277Smckusick 			    va_arg(ap, u_long) : va_arg(ap, u_int);
11863277Smckusick 			kprintn(ul, 10);
11963277Smckusick 			break;
12063277Smckusick 		case 'x':
12163277Smckusick 			ul = lflag ?
12263277Smckusick 			    va_arg(ap, u_long) : va_arg(ap, u_int);
12363277Smckusick 			kprintn(ul, 16);
12463277Smckusick 			break;
12563277Smckusick 		default:
12663277Smckusick 			putchar('%');
12763277Smckusick 			if (lflag)
12863277Smckusick 				putchar('l');
12963277Smckusick 			putchar(ch);
13063277Smckusick 		}
13163277Smckusick 	}
13263277Smckusick 	va_end(ap);
13363277Smckusick }
13463277Smckusick 
13563277Smckusick static void
kprintn(ul,base)13663277Smckusick kprintn(ul, base)
13763277Smckusick 	unsigned long ul;
13863277Smckusick 	int base;
13963277Smckusick {
14063277Smckusick 					/* hold a long in base 8 */
14163277Smckusick 	char *p, buf[(sizeof(long) * NBBY / 3) + 1];
14263277Smckusick 
14363277Smckusick 	p = buf;
14463277Smckusick 	do {
14563277Smckusick 		*p++ = "0123456789abcdef"[ul % base];
14663277Smckusick 	} while (ul /= base);
14763277Smckusick 	do {
14863277Smckusick 		putchar(*--p);
14963277Smckusick 	} while (p > buf);
15063277Smckusick }
151