xref: /inferno-os/os/boot/rpcg/donprint.c (revision 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a)
1*74a4d8c2SCharles.Forsyth #include	"u.h"
2*74a4d8c2SCharles.Forsyth #include	"lib.h"
3*74a4d8c2SCharles.Forsyth 
4*74a4d8c2SCharles.Forsyth #define	PTR	sizeof(char*)
5*74a4d8c2SCharles.Forsyth #define	SHORT	sizeof(int)
6*74a4d8c2SCharles.Forsyth #define	INT	sizeof(int)
7*74a4d8c2SCharles.Forsyth #define	LONG	sizeof(long)
8*74a4d8c2SCharles.Forsyth #define	IDIGIT	30
9*74a4d8c2SCharles.Forsyth #define	MAXCON	30
10*74a4d8c2SCharles.Forsyth 
11*74a4d8c2SCharles.Forsyth #define	FLONG	(1<<0)
12*74a4d8c2SCharles.Forsyth #define	FSHORT	(1<<1)
13*74a4d8c2SCharles.Forsyth #define	FUNSIGN	(1<<2)
14*74a4d8c2SCharles.Forsyth 
15*74a4d8c2SCharles.Forsyth typedef struct Op	Op;
16*74a4d8c2SCharles.Forsyth struct Op
17*74a4d8c2SCharles.Forsyth {
18*74a4d8c2SCharles.Forsyth 	char	*p;
19*74a4d8c2SCharles.Forsyth 	char	*ep;
20*74a4d8c2SCharles.Forsyth 	void	*argp;
21*74a4d8c2SCharles.Forsyth 	int	f1;
22*74a4d8c2SCharles.Forsyth 	int	f2;
23*74a4d8c2SCharles.Forsyth 	int	f3;
24*74a4d8c2SCharles.Forsyth };
25*74a4d8c2SCharles.Forsyth 
26*74a4d8c2SCharles.Forsyth static	int	noconv(Op*);
27*74a4d8c2SCharles.Forsyth static	int	cconv(Op*);
28*74a4d8c2SCharles.Forsyth static	int	dconv(Op*);
29*74a4d8c2SCharles.Forsyth static	int	hconv(Op*);
30*74a4d8c2SCharles.Forsyth static	int	lconv(Op*);
31*74a4d8c2SCharles.Forsyth static	int	oconv(Op*);
32*74a4d8c2SCharles.Forsyth static	int	sconv(Op*);
33*74a4d8c2SCharles.Forsyth static	int	uconv(Op*);
34*74a4d8c2SCharles.Forsyth static	int	xconv(Op*);
35*74a4d8c2SCharles.Forsyth static	int	Xconv(Op*);
36*74a4d8c2SCharles.Forsyth static	int	percent(Op*);
37*74a4d8c2SCharles.Forsyth 
38*74a4d8c2SCharles.Forsyth static
39*74a4d8c2SCharles.Forsyth int	(*fmtconv[MAXCON])(Op*) =
40*74a4d8c2SCharles.Forsyth {
41*74a4d8c2SCharles.Forsyth 	noconv,
42*74a4d8c2SCharles.Forsyth 	cconv, dconv, hconv, lconv,
43*74a4d8c2SCharles.Forsyth 	oconv, sconv, uconv, xconv,
44*74a4d8c2SCharles.Forsyth 	Xconv, percent,
45*74a4d8c2SCharles.Forsyth };
46*74a4d8c2SCharles.Forsyth static
47*74a4d8c2SCharles.Forsyth char	fmtindex[128] =
48*74a4d8c2SCharles.Forsyth {
49*74a4d8c2SCharles.Forsyth 	['c'] 1,
50*74a4d8c2SCharles.Forsyth 	['d'] 2,
51*74a4d8c2SCharles.Forsyth 	['h'] 3,
52*74a4d8c2SCharles.Forsyth 	['l'] 4,
53*74a4d8c2SCharles.Forsyth 	['o'] 5,
54*74a4d8c2SCharles.Forsyth 	['s'] 6,
55*74a4d8c2SCharles.Forsyth 	['u'] 7,
56*74a4d8c2SCharles.Forsyth 	['x'] 8,
57*74a4d8c2SCharles.Forsyth 	['X'] 9,
58*74a4d8c2SCharles.Forsyth 	['%'] 10,
59*74a4d8c2SCharles.Forsyth };
60*74a4d8c2SCharles.Forsyth 
61*74a4d8c2SCharles.Forsyth static	int	convcount  = { 11 };
62*74a4d8c2SCharles.Forsyth static	int	ucase;
63*74a4d8c2SCharles.Forsyth 
64*74a4d8c2SCharles.Forsyth static void
PUT(Op * o,int c)65*74a4d8c2SCharles.Forsyth PUT(Op *o, int c)
66*74a4d8c2SCharles.Forsyth {
67*74a4d8c2SCharles.Forsyth 	static int pos;
68*74a4d8c2SCharles.Forsyth 	int opos;
69*74a4d8c2SCharles.Forsyth 
70*74a4d8c2SCharles.Forsyth 	if(c == '\t'){
71*74a4d8c2SCharles.Forsyth 		opos = pos;
72*74a4d8c2SCharles.Forsyth 		pos = (opos+8) & ~7;
73*74a4d8c2SCharles.Forsyth 		while(opos++ < pos && o->p < o->ep)
74*74a4d8c2SCharles.Forsyth 			*o->p++ = ' ';
75*74a4d8c2SCharles.Forsyth 		return;
76*74a4d8c2SCharles.Forsyth 	}
77*74a4d8c2SCharles.Forsyth 	if(o->p < o->ep){
78*74a4d8c2SCharles.Forsyth 		*o->p++ = c;
79*74a4d8c2SCharles.Forsyth 		pos++;
80*74a4d8c2SCharles.Forsyth 	}
81*74a4d8c2SCharles.Forsyth 	if(c == '\n')
82*74a4d8c2SCharles.Forsyth 		pos = 0;
83*74a4d8c2SCharles.Forsyth }
84*74a4d8c2SCharles.Forsyth 
85*74a4d8c2SCharles.Forsyth int
fmtinstall(char c,int (* f)(Op *))86*74a4d8c2SCharles.Forsyth fmtinstall(char c, int (*f)(Op*))
87*74a4d8c2SCharles.Forsyth {
88*74a4d8c2SCharles.Forsyth 
89*74a4d8c2SCharles.Forsyth 	c &= 0177;
90*74a4d8c2SCharles.Forsyth 	if(fmtindex[c] == 0) {
91*74a4d8c2SCharles.Forsyth 		if(convcount >= MAXCON)
92*74a4d8c2SCharles.Forsyth 			return 1;
93*74a4d8c2SCharles.Forsyth 		fmtindex[c] = convcount++;
94*74a4d8c2SCharles.Forsyth 	}
95*74a4d8c2SCharles.Forsyth 	fmtconv[fmtindex[c]] = f;
96*74a4d8c2SCharles.Forsyth 	return 0;
97*74a4d8c2SCharles.Forsyth }
98*74a4d8c2SCharles.Forsyth 
99*74a4d8c2SCharles.Forsyth char*
donprint(char * p,char * ep,char * fmt,void * argp)100*74a4d8c2SCharles.Forsyth donprint(char *p, char *ep, char *fmt, void *argp)
101*74a4d8c2SCharles.Forsyth {
102*74a4d8c2SCharles.Forsyth 	int sf1, c;
103*74a4d8c2SCharles.Forsyth 	Op o;
104*74a4d8c2SCharles.Forsyth 
105*74a4d8c2SCharles.Forsyth 	o.p = p;
106*74a4d8c2SCharles.Forsyth 	o.ep = ep;
107*74a4d8c2SCharles.Forsyth 	o.argp = argp;
108*74a4d8c2SCharles.Forsyth 
109*74a4d8c2SCharles.Forsyth loop:
110*74a4d8c2SCharles.Forsyth 	c = *fmt++;
111*74a4d8c2SCharles.Forsyth 	if(c != '%') {
112*74a4d8c2SCharles.Forsyth 		if(c == 0) {
113*74a4d8c2SCharles.Forsyth 			if(o.p < o.ep)
114*74a4d8c2SCharles.Forsyth 				*o.p = 0;
115*74a4d8c2SCharles.Forsyth 			return o.p;
116*74a4d8c2SCharles.Forsyth 		}
117*74a4d8c2SCharles.Forsyth 		PUT(&o, c);
118*74a4d8c2SCharles.Forsyth 		goto loop;
119*74a4d8c2SCharles.Forsyth 	}
120*74a4d8c2SCharles.Forsyth 	o.f1 = 0;
121*74a4d8c2SCharles.Forsyth 	o.f2 = -1;
122*74a4d8c2SCharles.Forsyth 	o.f3 = 0;
123*74a4d8c2SCharles.Forsyth 	c = *fmt++;
124*74a4d8c2SCharles.Forsyth 	sf1 = 0;
125*74a4d8c2SCharles.Forsyth 	if(c == '-') {
126*74a4d8c2SCharles.Forsyth 		sf1 = 1;
127*74a4d8c2SCharles.Forsyth 		c = *fmt++;
128*74a4d8c2SCharles.Forsyth 	}
129*74a4d8c2SCharles.Forsyth 	while(c >= '0' && c <= '9') {
130*74a4d8c2SCharles.Forsyth 		o.f1 = o.f1*10 + c-'0';
131*74a4d8c2SCharles.Forsyth 		c = *fmt++;
132*74a4d8c2SCharles.Forsyth 	}
133*74a4d8c2SCharles.Forsyth 	if(sf1)
134*74a4d8c2SCharles.Forsyth 		o.f1 = -o.f1;
135*74a4d8c2SCharles.Forsyth 	if(c != '.')
136*74a4d8c2SCharles.Forsyth 		goto l1;
137*74a4d8c2SCharles.Forsyth 	c = *fmt++;
138*74a4d8c2SCharles.Forsyth 	while(c >= '0' && c <= '9') {
139*74a4d8c2SCharles.Forsyth 		if(o.f2 < 0)
140*74a4d8c2SCharles.Forsyth 			o.f2 = 0;
141*74a4d8c2SCharles.Forsyth 		o.f2 = o.f2*10 + c-'0';
142*74a4d8c2SCharles.Forsyth 		c = *fmt++;
143*74a4d8c2SCharles.Forsyth 	}
144*74a4d8c2SCharles.Forsyth l1:
145*74a4d8c2SCharles.Forsyth 	if(c == 0)
146*74a4d8c2SCharles.Forsyth 		fmt--;
147*74a4d8c2SCharles.Forsyth 	c = (*fmtconv[fmtindex[c&0177]])(&o);
148*74a4d8c2SCharles.Forsyth 	if(c < 0) {
149*74a4d8c2SCharles.Forsyth 		o.f3 |= -c;
150*74a4d8c2SCharles.Forsyth 		c = *fmt++;
151*74a4d8c2SCharles.Forsyth 		goto l1;
152*74a4d8c2SCharles.Forsyth 	}
153*74a4d8c2SCharles.Forsyth 	o.argp = (char*)o.argp + c;
154*74a4d8c2SCharles.Forsyth 	goto loop;
155*74a4d8c2SCharles.Forsyth }
156*74a4d8c2SCharles.Forsyth 
157*74a4d8c2SCharles.Forsyth void
strconv(char * o,Op * op,int f1,int f2)158*74a4d8c2SCharles.Forsyth strconv(char *o, Op *op, int f1, int f2)
159*74a4d8c2SCharles.Forsyth {
160*74a4d8c2SCharles.Forsyth 	int n, c;
161*74a4d8c2SCharles.Forsyth 	char *p;
162*74a4d8c2SCharles.Forsyth 
163*74a4d8c2SCharles.Forsyth 	n = strlen(o);
164*74a4d8c2SCharles.Forsyth 	if(f1 >= 0)
165*74a4d8c2SCharles.Forsyth 		while(n < f1) {
166*74a4d8c2SCharles.Forsyth 			PUT(op, ' ');
167*74a4d8c2SCharles.Forsyth 			n++;
168*74a4d8c2SCharles.Forsyth 		}
169*74a4d8c2SCharles.Forsyth 	for(p=o; c = *p++;)
170*74a4d8c2SCharles.Forsyth 		if(f2 != 0) {
171*74a4d8c2SCharles.Forsyth 			PUT(op, c);
172*74a4d8c2SCharles.Forsyth 			f2--;
173*74a4d8c2SCharles.Forsyth 		}
174*74a4d8c2SCharles.Forsyth 	if(f1 < 0) {
175*74a4d8c2SCharles.Forsyth 		f1 = -f1;
176*74a4d8c2SCharles.Forsyth 		while(n < f1) {
177*74a4d8c2SCharles.Forsyth 			PUT(op, ' ');
178*74a4d8c2SCharles.Forsyth 			n++;
179*74a4d8c2SCharles.Forsyth 		}
180*74a4d8c2SCharles.Forsyth 	}
181*74a4d8c2SCharles.Forsyth }
182*74a4d8c2SCharles.Forsyth 
183*74a4d8c2SCharles.Forsyth int
numbconv(Op * op,int base)184*74a4d8c2SCharles.Forsyth numbconv(Op *op, int base)
185*74a4d8c2SCharles.Forsyth {
186*74a4d8c2SCharles.Forsyth 	char b[IDIGIT];
187*74a4d8c2SCharles.Forsyth 	int i, f, n, r;
188*74a4d8c2SCharles.Forsyth 	long v;
189*74a4d8c2SCharles.Forsyth 	short h;
190*74a4d8c2SCharles.Forsyth 
191*74a4d8c2SCharles.Forsyth 	f = 0;
192*74a4d8c2SCharles.Forsyth 	switch(op->f3 & (FLONG|FSHORT|FUNSIGN)) {
193*74a4d8c2SCharles.Forsyth 	case FLONG:
194*74a4d8c2SCharles.Forsyth 		v = *(long*)op->argp;
195*74a4d8c2SCharles.Forsyth 		r = LONG;
196*74a4d8c2SCharles.Forsyth 		break;
197*74a4d8c2SCharles.Forsyth 
198*74a4d8c2SCharles.Forsyth 	case FUNSIGN|FLONG:
199*74a4d8c2SCharles.Forsyth 		v = *(ulong*)op->argp;
200*74a4d8c2SCharles.Forsyth 		r = LONG;
201*74a4d8c2SCharles.Forsyth 		break;
202*74a4d8c2SCharles.Forsyth 
203*74a4d8c2SCharles.Forsyth 	case FSHORT:
204*74a4d8c2SCharles.Forsyth 		h = *(int*)op->argp;
205*74a4d8c2SCharles.Forsyth 		v = h;
206*74a4d8c2SCharles.Forsyth 		r = SHORT;
207*74a4d8c2SCharles.Forsyth 		break;
208*74a4d8c2SCharles.Forsyth 
209*74a4d8c2SCharles.Forsyth 	case FUNSIGN|FSHORT:
210*74a4d8c2SCharles.Forsyth 		h = *(int*)op->argp;
211*74a4d8c2SCharles.Forsyth 		v = (ushort)h;
212*74a4d8c2SCharles.Forsyth 		r = SHORT;
213*74a4d8c2SCharles.Forsyth 		break;
214*74a4d8c2SCharles.Forsyth 
215*74a4d8c2SCharles.Forsyth 	default:
216*74a4d8c2SCharles.Forsyth 		v = *(int*)op->argp;
217*74a4d8c2SCharles.Forsyth 		r = INT;
218*74a4d8c2SCharles.Forsyth 		break;
219*74a4d8c2SCharles.Forsyth 
220*74a4d8c2SCharles.Forsyth 	case FUNSIGN:
221*74a4d8c2SCharles.Forsyth 		v = *(unsigned*)op->argp;
222*74a4d8c2SCharles.Forsyth 		r = INT;
223*74a4d8c2SCharles.Forsyth 		break;
224*74a4d8c2SCharles.Forsyth 	}
225*74a4d8c2SCharles.Forsyth 	if(!(op->f3 & FUNSIGN) && v < 0) {
226*74a4d8c2SCharles.Forsyth 		v = -v;
227*74a4d8c2SCharles.Forsyth 		f = 1;
228*74a4d8c2SCharles.Forsyth 	}
229*74a4d8c2SCharles.Forsyth 	b[IDIGIT-1] = 0;
230*74a4d8c2SCharles.Forsyth 	for(i = IDIGIT-2;; i--) {
231*74a4d8c2SCharles.Forsyth 		n = (ulong)v % base;
232*74a4d8c2SCharles.Forsyth 		n += '0';
233*74a4d8c2SCharles.Forsyth 		if(n > '9'){
234*74a4d8c2SCharles.Forsyth 			n += 'a' - ('9'+1);
235*74a4d8c2SCharles.Forsyth 			if(ucase)
236*74a4d8c2SCharles.Forsyth 				n += 'A'-'a';
237*74a4d8c2SCharles.Forsyth 		}
238*74a4d8c2SCharles.Forsyth 		b[i] = n;
239*74a4d8c2SCharles.Forsyth 		if(i < 2)
240*74a4d8c2SCharles.Forsyth 			break;
241*74a4d8c2SCharles.Forsyth 		v = (ulong)v / base;
242*74a4d8c2SCharles.Forsyth 		if(op->f2 >= 0 && i >= IDIGIT-op->f2)
243*74a4d8c2SCharles.Forsyth 			continue;
244*74a4d8c2SCharles.Forsyth 		if(v <= 0)
245*74a4d8c2SCharles.Forsyth 			break;
246*74a4d8c2SCharles.Forsyth 	}
247*74a4d8c2SCharles.Forsyth 	if(f)
248*74a4d8c2SCharles.Forsyth 		b[--i] = '-';
249*74a4d8c2SCharles.Forsyth 	strconv(b+i, op, op->f1, -1);
250*74a4d8c2SCharles.Forsyth 	return r;
251*74a4d8c2SCharles.Forsyth }
252*74a4d8c2SCharles.Forsyth 
253*74a4d8c2SCharles.Forsyth static	int
noconv(Op * op)254*74a4d8c2SCharles.Forsyth noconv(Op *op)
255*74a4d8c2SCharles.Forsyth {
256*74a4d8c2SCharles.Forsyth 
257*74a4d8c2SCharles.Forsyth 	strconv("***", op, 0, -1);
258*74a4d8c2SCharles.Forsyth 	return 0;
259*74a4d8c2SCharles.Forsyth }
260*74a4d8c2SCharles.Forsyth 
261*74a4d8c2SCharles.Forsyth static	int
cconv(Op * op)262*74a4d8c2SCharles.Forsyth cconv(Op *op)
263*74a4d8c2SCharles.Forsyth {
264*74a4d8c2SCharles.Forsyth 	char b[2];
265*74a4d8c2SCharles.Forsyth 
266*74a4d8c2SCharles.Forsyth 	b[0] = *(int*)op->argp;
267*74a4d8c2SCharles.Forsyth 	b[1] = 0;
268*74a4d8c2SCharles.Forsyth 	strconv(b, op, op->f1, -1);
269*74a4d8c2SCharles.Forsyth 	return INT;
270*74a4d8c2SCharles.Forsyth }
271*74a4d8c2SCharles.Forsyth 
272*74a4d8c2SCharles.Forsyth static	int
dconv(Op * op)273*74a4d8c2SCharles.Forsyth dconv(Op *op)
274*74a4d8c2SCharles.Forsyth {
275*74a4d8c2SCharles.Forsyth 	return numbconv(op, 10);
276*74a4d8c2SCharles.Forsyth }
277*74a4d8c2SCharles.Forsyth 
278*74a4d8c2SCharles.Forsyth static	int
hconv(Op *)279*74a4d8c2SCharles.Forsyth hconv(Op*)
280*74a4d8c2SCharles.Forsyth {
281*74a4d8c2SCharles.Forsyth 	return -FSHORT;
282*74a4d8c2SCharles.Forsyth }
283*74a4d8c2SCharles.Forsyth 
284*74a4d8c2SCharles.Forsyth static	int
lconv(Op *)285*74a4d8c2SCharles.Forsyth lconv(Op*)
286*74a4d8c2SCharles.Forsyth {
287*74a4d8c2SCharles.Forsyth 	return -FLONG;
288*74a4d8c2SCharles.Forsyth }
289*74a4d8c2SCharles.Forsyth 
290*74a4d8c2SCharles.Forsyth static	int
oconv(Op * op)291*74a4d8c2SCharles.Forsyth oconv(Op *op)
292*74a4d8c2SCharles.Forsyth {
293*74a4d8c2SCharles.Forsyth 	return numbconv(op, 8);
294*74a4d8c2SCharles.Forsyth }
295*74a4d8c2SCharles.Forsyth 
296*74a4d8c2SCharles.Forsyth static	int
sconv(Op * op)297*74a4d8c2SCharles.Forsyth sconv(Op *op)
298*74a4d8c2SCharles.Forsyth {
299*74a4d8c2SCharles.Forsyth 	strconv(*(char**)op->argp, op, op->f1, op->f2);
300*74a4d8c2SCharles.Forsyth 	return PTR;
301*74a4d8c2SCharles.Forsyth }
302*74a4d8c2SCharles.Forsyth 
303*74a4d8c2SCharles.Forsyth static	int
uconv(Op *)304*74a4d8c2SCharles.Forsyth uconv(Op*)
305*74a4d8c2SCharles.Forsyth {
306*74a4d8c2SCharles.Forsyth 	return -FUNSIGN;
307*74a4d8c2SCharles.Forsyth }
308*74a4d8c2SCharles.Forsyth 
309*74a4d8c2SCharles.Forsyth static	int
xconv(Op * op)310*74a4d8c2SCharles.Forsyth xconv(Op *op)
311*74a4d8c2SCharles.Forsyth {
312*74a4d8c2SCharles.Forsyth 	return numbconv(op, 16);
313*74a4d8c2SCharles.Forsyth }
314*74a4d8c2SCharles.Forsyth 
315*74a4d8c2SCharles.Forsyth static	int
Xconv(Op * op)316*74a4d8c2SCharles.Forsyth Xconv(Op *op)
317*74a4d8c2SCharles.Forsyth {
318*74a4d8c2SCharles.Forsyth 	int r;
319*74a4d8c2SCharles.Forsyth 
320*74a4d8c2SCharles.Forsyth 	ucase = 1;
321*74a4d8c2SCharles.Forsyth 	r = numbconv(op, 16);
322*74a4d8c2SCharles.Forsyth 	ucase = 0;
323*74a4d8c2SCharles.Forsyth 	return r;
324*74a4d8c2SCharles.Forsyth }
325*74a4d8c2SCharles.Forsyth 
326*74a4d8c2SCharles.Forsyth static	int
percent(Op * op)327*74a4d8c2SCharles.Forsyth percent(Op *op)
328*74a4d8c2SCharles.Forsyth {
329*74a4d8c2SCharles.Forsyth 
330*74a4d8c2SCharles.Forsyth 	PUT(op, '%');
331*74a4d8c2SCharles.Forsyth 	return 0;
332*74a4d8c2SCharles.Forsyth }
333