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