153998Sfujita /* 253998Sfujita * Copyright (c) 1992 OMRON Corporation. 353998Sfujita * Copyright (c) 1992 The Regents of the University of California. 453998Sfujita * 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*56519Sbostic * @(#)dbgprf.c 7.2 (Berkeley) 10/11/92 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 21*56519Sbostic #include <sys/param.h> 22*56519Sbostic #include <sys/systm.h> 2353998Sfujita 24*56519Sbostic #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 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__ 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 * 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