|
|
1.1 root 1: #define FUNSIGN 4
2: #define FSHORT 2
3: #define FLONG 1
4: #define PTR sizeof (char *)
5: #define SHORT sizeof (int)
6: #define INT sizeof (int)
7: #define LONG sizeof (long)
8: #define FLOAT sizeof (double)
9: #define FDIGIT 30
10: #define FDEFLT 8
11: #define IDIGIT 20
12: #define MAXCONV 30
13:
14: static char *out;
15: static convcount = { 13 };
16:
17: static noconv();
18: static cconv(), dconv(), hconv(), lconv();
19: static oconv(), sconv(), uconv(), xconv();
20:
21: static econv(), fconv(), gconv(), percent();
22: int printcol;
23: static
24: int (*fmtconv[MAXCONV])() =
25: {
26: noconv,
27: cconv, dconv, hconv, lconv,
28: oconv, sconv, uconv, xconv,
29: econv, fconv, gconv, percent,
30: };
31: static
32: char fmtindex[128] =
33: {
34: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
35: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
36: 0, 0, 0, 0, 0,12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
37: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
38: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
39: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
40: 0, 0, 0, 1, 2, 9,10,11, 3, 0, 0, 0, 4, 0, 0, 5,
41: 0, 0, 0, 6, 0, 7, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0,
42: };
43:
44: fmtinstall(c, f)
45: char c;
46: int (*f)();
47: {
48:
49: c &= 0177;
50: if(fmtindex[c] == 0) {
51: if(convcount >= MAXCONV)
52: return 1;
53: fmtindex[c] = convcount++;
54: }
55: fmtconv[fmtindex[c]] = f;
56: return 0;
57: }
58:
59: char *
60: doprint(s, fmt, argp)
61: char *s;
62: char *fmt;
63: char *argp;
64: {
65: int f1, f2, f3, sf1, c;
66: char *sout;
67:
68: sout = out;
69: out = s;
70: loop:
71: c = *fmt++;
72: if(c != '%') {
73: if(c == 0) {
74: *out = 0;
75: s = out;
76: out = sout;
77: return s;
78: }
79: *out++ = c;
80: printcol++;
81: if(c == '\n')
82: printcol = 0; else
83: if(c == '\t')
84: printcol = (printcol+7) & ~7;
85: goto loop;
86: }
87: f1 = 0;
88: f2 = -1;
89: f3 = 0;
90: c = *fmt++;
91: sf1 = 0;
92: if(c == '-') {
93: sf1 = 1;
94: c = *fmt++;
95: }
96: while(c >= '0' && c <= '9') {
97: f1 = f1*10 + c-'0';
98: c = *fmt++;
99: }
100: if(sf1)
101: f1 = -f1;
102: if(c != '.')
103: goto l1;
104: c = *fmt++;
105: while(c >= '0' && c <= '9') {
106: if(f2 < 0)
107: f2 = 0;
108: f2 = f2*10 + c-'0';
109: c = *fmt++;
110: }
111: l1:
112: if(c == 0)
113: fmt--;
114: c = (*fmtconv[fmtindex[c&0177]])(argp, f1, f2, f3);
115: if(c < 0) {
116: f3 |= -c;
117: c = *fmt++;
118: goto l1;
119: }
120: argp += c;
121: goto loop;
122: }
123:
124: numbconv(o, f1, f2, f3, b)
125: char *o;
126: {
127: char s[IDIGIT];
128: int i, f, n, r;
129: long v;
130:
131: switch(f3 & (FLONG|FSHORT|FUNSIGN)) {
132: case FLONG:
133: v = *(long *)o;
134: r = LONG;
135: break;
136:
137: case FUNSIGN|FLONG:
138: v = *(unsigned long *)o;
139: r = LONG;
140: break;
141:
142: case FSHORT:
143: v = *(short *)o;
144: r = SHORT;
145: break;
146:
147: case FUNSIGN|FSHORT:
148: v = *(unsigned short *)o;
149: r = SHORT;
150: break;
151:
152: default:
153: v = *(int *)o;
154: r = INT;
155: break;
156:
157: case FUNSIGN:
158: v = *(unsigned *)o;
159: r = INT;
160: break;
161: }
162: f = 0;
163: if(!(f3 & FUNSIGN) && v < 0) {
164: v = -v;
165: f = 1;
166: }
167: s[IDIGIT-1] = 0;
168: for(i = IDIGIT-2; i >= 1; i--) {
169: n = (unsigned long)v % b;
170: n += '0';
171: if(n > '9')
172: n += 'a' - ('9'+1);
173: s[i] = n;
174: v = (unsigned long)v / b;
175: if(f2 >= 0 && i >= IDIGIT-f2)
176: continue;
177: if(v <= 0)
178: break;
179: }
180: if(f)
181: s[--i] = '-';
182: strconv(s+i, f1, -1);
183: return r;
184: }
185:
186: strconv(o, f1, f2)
187: char *o;
188: {
189: int n, c;
190: char *s;
191:
192: n = 0;
193: for(s=o; *s++;)
194: n++;
195: if(f1 >= 0)
196: while(n < f1) {
197: *out++ = ' ';
198: printcol++;
199: n++;
200: }
201: for(s=o; c = *s++;)
202: if(f2 != 0) {
203: *out++ = c;
204: printcol++;
205: if(c == '\n')
206: printcol = 0; else
207: if(c == '\t')
208: printcol = (printcol+7) & ~7;
209: f2--;
210: }
211: if(f1 < 0) {
212: f1 = -f1;
213: while(n < f1) {
214: *out++ = ' ';
215: printcol++;
216: n++;
217: }
218: }
219: }
220:
221: static
222: noconv(o, f1, f2, f3)
223: char *o;
224: {
225:
226: strconv("***", 0, -1);
227: return 0;
228: }
229:
230: static
231: cconv(o, f1, f2, f3)
232: int *o;
233: {
234: char s[2];
235:
236: s[0] = *o;
237: s[1] = 0;
238: strconv(s, f1, -1);
239: return INT;
240: }
241:
242: static
243: dconv(o, f1, f2, f3)
244: char *o;
245: {
246: int r;
247:
248: r = numbconv(o, f1, f2, f3, 10);
249: return r;
250: }
251:
252: static
253: hconv(o, f1, f2, f3)
254: {
255: return -FSHORT;
256: }
257:
258: static
259: lconv(o, f1, f2, f3)
260: {
261:
262: return -FLONG;
263: }
264:
265: static
266: oconv(o, f1, f2, f3)
267: char *o;
268: {
269: int r;
270:
271: r = numbconv(o, f1, f2, f3, 8);
272: return r;
273: }
274:
275: static
276: sconv(o, f1, f2, f3)
277: char **o;
278: {
279:
280: strconv(*o, f1, f2);
281: return PTR;
282: }
283:
284: static
285: uconv(o, f1, f2, f3)
286: {
287: return -FUNSIGN;
288: }
289:
290: static
291: xconv(o, f1, f2, f3)
292: char *o;
293: {
294: int r;
295:
296: r = numbconv(o, f1, f2, f3, 16);
297: return r;
298: }
299:
300: double pow10(), frexp();
301: fltconv(f, f1, f2, f3, c)
302: double f;
303: {
304: char s1[FDIGIT+10], s2[FDIGIT+10];
305: double g;
306: int e, d, i, n, s;
307: int c1, c2, c3;
308:
309: s = 0;
310: if(f < 0) {
311: f = -f;
312: s++;
313: }
314:
315: loop:
316: e = 0;
317: g = 0;
318: if(f != 0) {
319: g = frexp(f, &e);
320: e = e * .30103;
321: g = f * pow10(-e);
322: while(g < 1) {
323: e--;
324: g = f * pow10(-e);
325: }
326: while(g >= 10) {
327: e++;
328: g = f * pow10(-e);
329: }
330: }
331: if(f2 < 0)
332: f2 = FDEFLT;
333: if(c == 'g' && f2 > 0)
334: f2--;
335: if(f2 > FDIGIT)
336: f2 = FDIGIT;
337: /*
338: * n is number of digits to convert
339: * 1 before, f2 after, 1 extra for rounding
340: */
341: n = f2 + 2;
342: if(c == 'f') {
343: /*
344: * e+1 before, f2 after, 1 extra
345: */
346: n += e;
347: if(n <= 0) {
348: n = 1;
349: g = 0;
350: }
351: }
352: if(n >= FDIGIT+2) {
353: if(c == 'e')
354: f2 = -1;
355: c = 'e';
356: goto loop;
357: }
358: /*
359: * convert n digits
360: */
361: for(i=0; i<n; i++) {
362: d = g;
363: if(d > g)
364: d--;
365: g -= d;
366: s1[i+1] = d + '0';
367: g *= 10;
368: }
369: /*
370: * round by adding .5 into extra digit
371: */
372: d = 5;
373: for(i=n-1; i>=0; i--) {
374: s1[i+1] += d;
375: d = 0;
376: if(s1[i+1] > '9') {
377: s1[i+1] -= 10;
378: d++;
379: }
380: }
381: i = 1;
382: if(d) {
383: s1[0] = '1';
384: e++;
385: i = 0;
386: }
387: /*
388: * copy into final place
389: * c1 digits of leading '0'
390: * c2 digits from conversion
391: * c3 digits after '.'
392: */
393: d = 0;
394: if(s)
395: s2[d++] = '-';
396: c1 = 0;
397: c2 = f2 + 1;
398: c3 = f2;
399: if(c == 'g')
400: if(e >= -5 && e <= f2) {
401: c1 = -e - 1;
402: c3 = c1;
403: if(c1 < 0)
404: c1 = 0;
405: c3 = f2 - e;
406: c = 'h';
407: }
408: if(c == 'f') {
409: c1 = -e;
410: if(c1 < 0)
411: c1 = 0;
412: if(c1 > f2)
413: c1 = c2;
414: c2 += e;
415: if(c2 < 0)
416: c2 = 0;
417: }
418: while(c1 > 0) {
419: if(c1+c2 == c3)
420: s2[d++] = '.';
421: s2[d++] = '0';
422: c1--;
423: }
424: while(c2 > 0) {
425: if(c1+c2 == c3)
426: s2[d++] = '.';
427: s2[d++] = s1[i++];
428: c2--;
429: }
430: /*
431: * strip trailing '0' on g conv
432: */
433: if(c == 'g' || c == 'h') {
434: for(n=d-1; n>=0; n--)
435: if(s2[n] != '0')
436: break;
437: for(i=n; i>=0; i--)
438: if(s2[i] == '.') {
439: d = n;
440: if(i != n)
441: d++;
442: break;
443: }
444: }
445: if(c == 'e' || c == 'g') {
446: s2[d++] = 'e';
447: s2[d++] = '+';
448: c1 = e;
449: if(c1 < 0) {
450: s2[d-1] = '-';
451: c1 = -c1;
452: }
453: if(c1 >= 100) {
454: s2[d++] = c1/100 + '0';
455: c1 %= 100;
456: }
457: s2[d++] = c1/10 + '0';
458: s2[d++] = c1%10 + '0';
459: }
460:
461: out:
462: s2[d] = 0;
463: strconv(s2, f1, -1);
464: return FLOAT;
465: }
466:
467: static
468: econv(o, f1, f2, f3)
469: double *o;
470: {
471:
472: return fltconv(*o, f1, f2, f3, 'e');
473: }
474:
475: static
476: fconv(o, f1, f2, f3)
477: double *o;
478: {
479:
480: return fltconv(*o, f1, f2, f3, 'f');
481: }
482:
483: static
484: gconv(o, f1, f2, f3)
485: double *o;
486: {
487:
488: return fltconv(*o, f1, f2, f3, 'g');
489: }
490:
491: static
492: percent()
493: {
494:
495: *out++ = '%';
496: return 0;
497: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.