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