1 /*
2  * Copyright (c) 1986 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  *
6  *	@(#)kdb_output.c	7.3 (Berkeley) 05/03/90
7  */
8 
9 #include "../kdb/defs.h"
10 
11 long	kdbmaxpos;
12 int	kdbradix = 16;
13 
14 char	kdbprintbuf[MAXLIN];
15 char	*kdbprintptr = kdbprintbuf;
16 char	*kdbdigitptr;
17 
18 kdbprintc(c)
19 	char c;
20 {
21 	char d;
22 	register char *q;
23 	register posn, tabs, p;
24 
25 	if (kdbmkfault)
26 		return;
27 	if ((*kdbprintptr=c)==EOR) {
28 		tabs=0; posn=0; q=kdbprintbuf;
29 		for (p=0; p<kdbprintptr-kdbprintbuf; p++) {
30 			d=kdbprintbuf[p];
31 			if ((p&7)==0 && posn) {
32 				tabs++;
33 				posn=0;
34 			}
35 			if (d!=SP) {
36 				while (tabs>0)
37 					*q++=TB, tabs--;
38 				while (posn>0)
39 					*q++=SP, posn--;
40 				*q++=d;
41 			} else
42 				posn++;
43 		 }
44 		 *q++=EOR;
45 		 kdbwrite(kdbprintbuf,q-kdbprintbuf);
46 		 kdbprintptr=kdbprintbuf;
47 	} else if (c==TB) {
48 		*kdbprintptr++=SP;
49 		while ((kdbprintptr-kdbprintbuf)&7)
50 			*kdbprintptr++=SP;
51 	} else if (c)
52 		kdbprintptr++;
53 	if (kdbprintptr >= &kdbprintbuf[MAXLIN-9]) {
54 		kdbwrite(kdbprintbuf, kdbprintptr - kdbprintbuf);
55 		kdbprintptr = kdbprintbuf;
56 	}
57 }
58 
59 kdbcharpos()
60 {
61 
62 	return (kdbprintptr-kdbprintbuf);
63 }
64 
65 kdbflushbuf()
66 {
67 
68 	if (kdbprintptr!=kdbprintbuf)
69 		kdbprintc(EOR);
70 }
71 
72 /* VARARGS1 */
73 kdbprintf(fmat,a1)
74 	char *fmat, *a1;
75 {
76 	char *fptr;
77 	register char *s;
78 	register long *dptr;
79 	register width, prec;
80 	char c, adj;
81 	int x, n;
82 	register long lx;
83 	char digits[64];
84 
85 	fptr = fmat; dptr = (long *)&a1;
86 	while (c = *fptr++) {
87 		if (c!='%') {
88 			kdbprintc(c);
89 			continue;
90 		}
91 		if (*fptr=='-') {
92 			adj='l'; fptr++;
93 		} else
94 			adj='r';
95 		width=kdbconvert(&fptr);
96 		if (*fptr=='.') {
97 			fptr++; prec=kdbconvert(&fptr);
98 		} else
99 			prec = -1;
100 		kdbdigitptr=digits;
101 		x = lx = *dptr++;
102 		s=0;
103 		switch (c = *fptr++) {
104 		case 'd':
105 			kdbprintnum((u_long)x, -10); break;
106 		case 'u':
107 			kdbprintnum((u_long)x, 10); break;
108 		case 'o':
109 			kdbprintnum((u_long)x, 8); break;
110 		case 'q':
111 			kdbprintnum((u_long)x, -8); break;
112 		case 'x':
113 			kdbprintnum((u_long)x, 16); break;
114 		case 'z':
115 			kdbprintnum((u_long)x, -16); break;
116 		case 'R':
117 			kdbprintnum((u_long)lx, kdbradix); break;
118 		case 'D':
119 			kdbprintnum((u_long)lx, -10); break;
120 		case 'U':
121 			kdbprintnum((u_long)lx, 10); break;
122 		case 'O':
123 			kdbprintnum((u_long)lx, 8); break;
124 		case 'Q':
125 			kdbprintnum((u_long)lx, -8); break;
126 		case 'X':
127 			kdbprintnum((u_long)lx, 16); break;
128 		case 'Z':
129 			kdbprintnum((u_long)lx, -16); break;
130 		case 'c':
131 			kdbprintc(x); break;
132 		case 's':
133 			s=(char *)lx; break;
134 		case 'm':
135 			break;
136 		case 'M':
137 			width=x; break;
138 		case 'T': case 't':
139 			if (c=='T')
140 				width=x;
141 			else
142 				dptr--;
143 			if (width)
144 				width -= kdbcharpos()%width;
145 			break;
146 		default:
147 			kdbprintc(c); dptr--;
148 			break;
149 		}
150 		if (s==0) {
151 			*kdbdigitptr=0; s=digits;
152 		}
153 		n=strlen(s);
154 		n=(prec<n && prec>=0 ? prec : n);
155 		width -= n;
156 		if (adj=='r')
157 			while (width-- > 0)
158 				kdbprintc(SP);
159 		while (n--)
160 			kdbprintc(*s++);
161 		while (width-- > 0)
162 			kdbprintc(SP);
163 		kdbdigitptr=digits;
164 	}
165 }
166 
167 static
168 kdbconvert(cp)
169 	register char **cp;
170 {
171 	register char c;
172 	int n;
173 
174 	n=0;
175 	while (((c = *(*cp)++)>='0') && c<='9')
176 		n=n*10+c-'0';
177 	(*cp)--;
178 	return (n);
179 }
180 
181 static
182 kdbprintnum(n, base)
183 	register u_long n;
184 {
185 	register char *dptr;
186 	char digs[15];
187 
188 	dptr=digs;
189 	if (base<0) {
190 		base = -base;
191 		if ((long)n<0) {
192 			n = -n;
193 			*kdbdigitptr++ = '-';
194 		}
195 	}
196 	while (n) {
197 		*dptr++ = n%base;
198 		n /= base;
199 	}
200 	if (dptr==digs)
201 		*dptr++=0;
202 	while (dptr!=digs) {
203 		n = *--dptr;
204 		*kdbdigitptr++ = (n+(n<=9 ? '0' : 'a'-10));
205 	}
206 }
207 
208 kdbendline()
209 {
210 
211 	if (kdbmaxpos <= kdbcharpos())
212 		kdbprintf("\n");
213 }
214