xref: /original-bsd/sys/luna68k/dev/dbgprf.c (revision 3705696b)
1 /*
2  * Copyright (c) 1992 OMRON Corporation.
3  * Copyright (c) 1992, 1993
4  *	The Regents of the University of California.  All rights reserved.
5  *
6  * This code is derived from software contributed to Berkeley by
7  * OMRON Corporation.
8  *
9  * %sccs.include.redist.c%
10  *
11  *	@(#)dbgprf.c	8.1 (Berkeley) 06/10/93
12  */
13 
14 /*
15  * dbgprf.c -- batched printf for device driver debugging
16  * by A.Fujita, May-3-1992
17  */
18 
19 #ifdef DEBUGPRINT
20 
21 #include <sys/param.h>
22 #include <sys/systm.h>
23 
24 #include <machine/stdarg.h>
25 
26 static char *sprintn __P((u_long num, int base, int *len));
27 
28 #define DBG_LINES	 80
29 #define DBG_BUFS	300
30 
31 struct dbgprf {
32 	struct dbgprf *dbg_forw;
33 	struct dbgprf *dbg_back;
34 	char dbg_buf[DBG_LINES];
35 };
36 
37 struct dbgprf dbgprf[DBG_BUFS];
38 
39 struct dbgprf dbgroot = {
40 	&dbgroot,
41 	&dbgroot,
42 };
43 
44 int dbg_used = 0;
45 
46 void
47 dbgprintall()
48 {
49 	register struct dbgprf *dbgp;
50 
51 	for (dbgp = dbgroot.dbg_forw; dbgp != &dbgroot; dbgp = dbgp->dbg_forw) {
52 		printf("%s", dbgp->dbg_buf);
53 	}
54 }
55 
56 void
57 #ifdef __STDC__
58 dbgprintf(const char *cfmt, ...)
59 #else
60 dbgprintf(cfmt /*, va_alist */)
61 	char *cfmt;
62 #endif
63 {
64 	register struct dbgprf *dbgp;
65 	register const char *fmt = cfmt;
66 	register char *p, *bp;
67 	register int ch, base;
68 	u_long ul;
69 	int lflag;
70 	va_list ap;
71 
72 	if (dbg_used < DBG_BUFS) {
73 		dbgp = &dbgprf[dbg_used++];
74 	} else {
75 		dbgp = dbgroot.dbg_forw;
76 		remque(dbgp);
77 	}
78 
79 	va_start(ap, cfmt);
80 	for (bp = dbgp->dbg_buf; ; ) {
81 		while ((ch = *(u_char *)fmt++) != '%')
82 			if ((*bp++ = ch) == '\0')
83 				goto done;
84 
85 		lflag = 0;
86 reswitch:	switch (ch = *(u_char *)fmt++) {
87 		case 'l':
88 			lflag = 1;
89 			goto reswitch;
90 		case 'c':
91 			*bp++ = va_arg(ap, int);
92 			break;
93 		case 's':
94 			p = va_arg(ap, char *);
95 			while (*bp++ = *p++)
96 				;
97 			--bp;
98 			break;
99 		case 'd':
100 			ul = lflag ? va_arg(ap, long) : va_arg(ap, int);
101 			if ((long)ul < 0) {
102 				*bp++ = '-';
103 				ul = -(long)ul;
104 			}
105 			base = 10;
106 			goto number;
107 			break;
108 		case 'o':
109 			ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
110 			base = 8;
111 			goto number;
112 			break;
113 		case 'u':
114 			ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
115 			base = 10;
116 			goto number;
117 			break;
118 		case 'x':
119 			ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
120 			base = 16;
121 number:			for (p = sprintn(ul, base, NULL); ch = *p--;)
122 				*bp++ = ch;
123 			break;
124 		default:
125 			*bp++ = '%';
126 			if (lflag)
127 				*bp++ = 'l';
128 			/* FALLTHROUGH */
129 		case '%':
130 			*bp++ = ch;
131 		}
132 	}
133 	va_end(ap);
134 
135  done:
136 	insque(dbgp, dbgroot.dbg_back);
137 
138 /*	printf("%s", dbgp->dbg_buf);	*/
139 }
140 
141 /*
142  * Put a number (base <= 16) in a buffer in reverse order; return an
143  * optional length and a pointer to the NULL terminated (preceded?)
144  * buffer.
145  */
146 static char *
147 sprintn(ul, base, lenp)
148 	register u_long ul;
149 	register int base, *lenp;
150 {					/* A long in base 8, plus NULL. */
151 	static char buf[sizeof(long) * NBBY / 3 + 2];
152 	register char *p;
153 
154 	p = buf;
155 	do {
156 		*++p = "0123456789abcdef"[ul % base];
157 	} while (ul /= base);
158 	if (lenp)
159 		*lenp = p - buf;
160 	return (p);
161 }
162 #endif
163