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