153998Sfujita /*
253998Sfujita * Copyright (c) 1992 OMRON Corporation.
3*63192Sbostic * Copyright (c) 1992, 1993
4*63192Sbostic * The Regents of the University of California. All rights reserved.
553998Sfujita *
653998Sfujita * This code is derived from software contributed to Berkeley by
753998Sfujita * OMRON Corporation.
853998Sfujita *
953998Sfujita * %sccs.include.redist.c%
1053998Sfujita *
11*63192Sbostic * @(#)dbgprf.c 8.1 (Berkeley) 06/10/93
1253998Sfujita */
1353998Sfujita
1453998Sfujita /*
1553998Sfujita * dbgprf.c -- batched printf for device driver debugging
1653998Sfujita * by A.Fujita, May-3-1992
1753998Sfujita */
1853998Sfujita
1953998Sfujita #ifdef DEBUGPRINT
2053998Sfujita
2156519Sbostic #include <sys/param.h>
2256519Sbostic #include <sys/systm.h>
2353998Sfujita
2456519Sbostic #include <machine/stdarg.h>
2553998Sfujita
2653998Sfujita static char *sprintn __P((u_long num, int base, int *len));
2753998Sfujita
2853998Sfujita #define DBG_LINES 80
2953998Sfujita #define DBG_BUFS 300
3053998Sfujita
3153998Sfujita struct dbgprf {
3253998Sfujita struct dbgprf *dbg_forw;
3353998Sfujita struct dbgprf *dbg_back;
3453998Sfujita char dbg_buf[DBG_LINES];
3553998Sfujita };
3653998Sfujita
3753998Sfujita struct dbgprf dbgprf[DBG_BUFS];
3853998Sfujita
3953998Sfujita struct dbgprf dbgroot = {
4053998Sfujita &dbgroot,
4153998Sfujita &dbgroot,
4253998Sfujita };
4353998Sfujita
4453998Sfujita int dbg_used = 0;
4553998Sfujita
4653998Sfujita void
dbgprintall()4753998Sfujita dbgprintall()
4853998Sfujita {
4953998Sfujita register struct dbgprf *dbgp;
5053998Sfujita
5153998Sfujita for (dbgp = dbgroot.dbg_forw; dbgp != &dbgroot; dbgp = dbgp->dbg_forw) {
5253998Sfujita printf("%s", dbgp->dbg_buf);
5353998Sfujita }
5453998Sfujita }
5553998Sfujita
5653998Sfujita void
5753998Sfujita #ifdef __STDC__
dbgprintf(const char * cfmt,...)5853998Sfujita dbgprintf(const char *cfmt, ...)
5953998Sfujita #else
6053998Sfujita dbgprintf(cfmt /*, va_alist */)
6153998Sfujita char *cfmt;
6253998Sfujita #endif
6353998Sfujita {
6453998Sfujita register struct dbgprf *dbgp;
6553998Sfujita register const char *fmt = cfmt;
6653998Sfujita register char *p, *bp;
6753998Sfujita register int ch, base;
6853998Sfujita u_long ul;
6953998Sfujita int lflag;
7053998Sfujita va_list ap;
7153998Sfujita
7253998Sfujita if (dbg_used < DBG_BUFS) {
7353998Sfujita dbgp = &dbgprf[dbg_used++];
7453998Sfujita } else {
7553998Sfujita dbgp = dbgroot.dbg_forw;
7653998Sfujita remque(dbgp);
7753998Sfujita }
7853998Sfujita
7953998Sfujita va_start(ap, cfmt);
8053998Sfujita for (bp = dbgp->dbg_buf; ; ) {
8153998Sfujita while ((ch = *(u_char *)fmt++) != '%')
8253998Sfujita if ((*bp++ = ch) == '\0')
8353998Sfujita goto done;
8453998Sfujita
8553998Sfujita lflag = 0;
8653998Sfujita reswitch: switch (ch = *(u_char *)fmt++) {
8753998Sfujita case 'l':
8853998Sfujita lflag = 1;
8953998Sfujita goto reswitch;
9053998Sfujita case 'c':
9153998Sfujita *bp++ = va_arg(ap, int);
9253998Sfujita break;
9353998Sfujita case 's':
9453998Sfujita p = va_arg(ap, char *);
9553998Sfujita while (*bp++ = *p++)
9653998Sfujita ;
9753998Sfujita --bp;
9853998Sfujita break;
9953998Sfujita case 'd':
10053998Sfujita ul = lflag ? va_arg(ap, long) : va_arg(ap, int);
10153998Sfujita if ((long)ul < 0) {
10253998Sfujita *bp++ = '-';
10353998Sfujita ul = -(long)ul;
10453998Sfujita }
10553998Sfujita base = 10;
10653998Sfujita goto number;
10753998Sfujita break;
10853998Sfujita case 'o':
10953998Sfujita ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
11053998Sfujita base = 8;
11153998Sfujita goto number;
11253998Sfujita break;
11353998Sfujita case 'u':
11453998Sfujita ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
11553998Sfujita base = 10;
11653998Sfujita goto number;
11753998Sfujita break;
11853998Sfujita case 'x':
11953998Sfujita ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
12053998Sfujita base = 16;
12153998Sfujita number: for (p = sprintn(ul, base, NULL); ch = *p--;)
12253998Sfujita *bp++ = ch;
12353998Sfujita break;
12453998Sfujita default:
12553998Sfujita *bp++ = '%';
12653998Sfujita if (lflag)
12753998Sfujita *bp++ = 'l';
12853998Sfujita /* FALLTHROUGH */
12953998Sfujita case '%':
13053998Sfujita *bp++ = ch;
13153998Sfujita }
13253998Sfujita }
13353998Sfujita va_end(ap);
13453998Sfujita
13553998Sfujita done:
13653998Sfujita insque(dbgp, dbgroot.dbg_back);
13753998Sfujita
13853998Sfujita /* printf("%s", dbgp->dbg_buf); */
13953998Sfujita }
14053998Sfujita
14153998Sfujita /*
14253998Sfujita * Put a number (base <= 16) in a buffer in reverse order; return an
14353998Sfujita * optional length and a pointer to the NULL terminated (preceded?)
14453998Sfujita * buffer.
14553998Sfujita */
14653998Sfujita static char *
sprintn(ul,base,lenp)14753998Sfujita sprintn(ul, base, lenp)
14853998Sfujita register u_long ul;
14953998Sfujita register int base, *lenp;
15053998Sfujita { /* A long in base 8, plus NULL. */
15153998Sfujita static char buf[sizeof(long) * NBBY / 3 + 2];
15253998Sfujita register char *p;
15353998Sfujita
15453998Sfujita p = buf;
15553998Sfujita do {
15653998Sfujita *++p = "0123456789abcdef"[ul % base];
15753998Sfujita } while (ul /= base);
15853998Sfujita if (lenp)
15953998Sfujita *lenp = p - buf;
16053998Sfujita return (p);
16153998Sfujita }
16253998Sfujita #endif
163