|
|
1.1 root 1: From utstat.toronto.edu!geoff Sun May 13 03:36:46 EDT 1990
2: Received: by pyxis; Sun May 13 03:37 EDT 1990
3: Received: by inet.att.com; Sun May 13 03:36 EDT 1990
4: From: [email protected]
5: Date: Sun, 13 May 90 03:36:46 EDT
6: To: [email protected]
7:
8: Here are the files I changed in mk to make it use varargs
9: (fio/fioprint.c, libc/doprint.c, libc/print.c). The new version of mk
10: seems to work fine on our Suns and SGI (for the first time on the SGI)
11: and lints more cleanly than before. I didn't make it use stdarg.h,
12: but that should be fairly mechanical.
13:
14: The functions called from within doprint now get a va_list* as first
15: argument instead of a char* and the size they return isn't used to
16: advance along the stack (va_arg does that now). This will mean some
17: changes to manual pages (sorry).
18:
19:
20: # To unbundle, sh this file
21: mkdir fio libc
22: echo fio/fioprint.c 1>&2
23: sed 's/^-//' >fio/fioprint.c <<'!'
24: -#define FIO_IMP
25: -#include <varargs.h>
26: -#include <fio.h>
27:
28: -/* VARARGS 2 */
29: -Fprint(f, fmt, va_alist)
30: int f;
31: char *fmt;
32: va_dcl
33: -{
34: - char buf[FIOBSIZE], *out;
35: - register long n;
36: - va_list ap;
37: - extern char *doprint();
38:
39: - va_start(ap);
40: - out = doprint(buf, fmt, &ap);
41: - va_end(ap);
42: - n = out-buf;
43: - if(Fwrite(f, buf, n) != n)
44: - return(-1);
45: - else
46: - return((int)n);
47: -}
48: !
49: echo libc/doprint.c 1>&2
50: sed 's/^-//' >libc/doprint.c <<'!'
51: -#include <varargs.h>
52:
53: -#define SIZE 1024
54: -#define FUNSIGN 4
55: -#define FSHORT 2
56: -#define FLONG 1
57: -#define PTR sizeof (char *)
58: -#define SHORT sizeof (int)
59: -#define INT sizeof (int)
60: -#define LONG sizeof (long)
61: -#define FLOAT sizeof (double)
62: -#define FDIGIT 30
63: -#define FDEFLT 8
64: -#define IDIGIT 40
65: -#define MAXCONV 30
66:
67: static char *out, *eout;
68: static convcount = { 13 };
69:
70: static noconv();
71: static cconv(), dconv(), hconv(), lconv();
72: static oconv(), sconv(), uconv(), xconv();
73:
74: static econv(), fconv(), gconv(), percent();
75: int printcol;
76: static
77: int (*fmtconv[MAXCONV])() =
78: -{
79: - noconv,
80: - cconv, dconv, hconv, lconv,
81: - oconv, sconv, uconv, xconv,
82: - econv, fconv, gconv, percent,
83: -};
84: static
85: char fmtindex[128] =
86: -{
87: - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
88: - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
89: - 0, 0, 0, 0, 0,12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
90: - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
91: - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
92: - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
93: - 0, 0, 0, 1, 2, 9,10,11, 3, 0, 0, 0, 4, 0, 0, 5,
94: - 0, 0, 0, 6, 0, 7, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0,
95: -};
96:
97: fmtinstall(c, f)
98: char c;
99: int (*f)();
100: -{
101:
102: - c &= 0177;
103: - if(fmtindex[c] == 0) {
104: - if(convcount >= MAXCONV)
105: - return 1;
106: - fmtindex[c] = convcount++;
107: - }
108: - fmtconv[fmtindex[c]] = f;
109: - return 0;
110: -}
111:
112: char*
113: donprint(s, es, fmt, argpp)
114: char *s, *es;
115: register char *fmt;
116: va_list *argpp;
117: -{
118: - register int f1, f2, f3, sf1, c;
119: - char *sout, *seout;
120:
121: - sout = out;
122: - seout = eout;
123: - out = s;
124: - eout = es-1;
125: loop:
126: - c = *fmt++;
127: - if(c != '%') {
128: - if(c == 0) {
129: - *out = 0;
130: - s = out;
131: - out = sout;
132: - eout = seout;
133: - return s;
134: - }
135: - if(out < eout)
136: - *out++ = c;
137: - printcol++;
138: - if(c == '\n')
139: - printcol = 0; else
140: - if(c == '\t')
141: - printcol = (printcol+7) & ~7;
142: - goto loop;
143: - }
144: - f1 = 0;
145: - f2 = -1;
146: - f3 = 0;
147: - c = *fmt++;
148: - sf1 = 0;
149: - if(c == '-') {
150: - sf1 = 1;
151: - c = *fmt++;
152: - }
153: - while(c >= '0' && c <= '9') {
154: - f1 = f1*10 + c-'0';
155: - c = *fmt++;
156: - }
157: - if(sf1)
158: - f1 = -f1;
159: - if(c != '.')
160: - goto l1;
161: - c = *fmt++;
162: - while(c >= '0' && c <= '9') {
163: - if(f2 < 0)
164: - f2 = 0;
165: - f2 = f2*10 + c-'0';
166: - c = *fmt++;
167: - }
168: l1:
169: - if(c == 0)
170: - fmt--;
171: - /* NB: first arg is now a (va_list *) */
172: - c = (*fmtconv[fmtindex[c&0177]])(argpp, f1, f2, f3);
173: - if(c < 0) {
174: - f3 |= -c;
175: - c = *fmt++;
176: - goto l1;
177: - }
178: -#ifdef notdef
179: - argp += c; /* increment is now done in called routine by va_arg() */
180: -#endif
181: - goto loop;
182: -}
183:
184: numbconv(o, f1, f2, f3, b)
185: va_list *o;
186: -{
187: - char s[IDIGIT];
188: - register long v;
189: - register int i, f, n, r;
190:
191: - switch(f3 & (FLONG|FSHORT|FUNSIGN)) {
192: - case FLONG:
193: - v = va_arg(*o, long);
194: - r = LONG;
195: - break;
196:
197: - case FUNSIGN|FLONG:
198: - v = va_arg(*o, unsigned long);
199: - r = LONG;
200: - break;
201:
202: - /* NB: a (unsigned) short argument is promoted to an (unsigned) int arg. */
203: - case FSHORT:
204: - v = (short)va_arg(*o, int);
205: - r = SHORT;
206: - break;
207:
208: - case FUNSIGN|FSHORT:
209: - v = (unsigned short)va_arg(*o, unsigned);
210: - r = SHORT;
211: - break;
212:
213: - default:
214: - v = va_arg(*o, int);
215: - r = INT;
216: - break;
217:
218: - case FUNSIGN:
219: - v = va_arg(*o, unsigned);
220: - r = INT;
221: - break;
222: - }
223: - f = 0;
224: - if(!(f3 & FUNSIGN) && v < 0) {
225: - v = -v;
226: - f = 1;
227: - }
228: - s[IDIGIT-1] = 0;
229: - for(i = IDIGIT-2; i >= 1; i--) {
230: - n = (unsigned long)v % b;
231: - n += '0';
232: - if(n > '9')
233: - n += 'a' - ('9'+1);
234: - s[i] = n;
235: - v = (unsigned long)v / b;
236: - if(f2 >= 0 && i >= IDIGIT-f2)
237: - continue;
238: - if(v <= 0)
239: - break;
240: - }
241: - if(f)
242: - s[--i] = '-';
243: - strconv(s+i, f1, -1);
244: - return r;
245: -}
246:
247: char*
248: doprint(s, fmt, argp)
249: char *s, *fmt;
250: va_list *argp;
251: -{
252:
253: - return donprint(s, s+SIZE, fmt, argp);
254: -}
255:
256: -/*
257: - if you change this, change chconv
258: -*/
259:
260: strconv(o, f1, f2)
261: char *o;
262: -{
263: - register int n, c;
264: - register char *s;
265:
266: - n = 0;
267: - for(s = o; *s++;)
268: - n++;
269: - if(f1 >= 0)
270: - while(n < f1) {
271: - if(out < eout)
272: - *out++ = ' ';
273: - printcol++;
274: - n++;
275: - }
276: - for(s=o; c = *s++;)
277: - if(f2 != 0) {
278: - if(out < eout)
279: - *out++ = c;
280: - printcol++;
281: - if(c == '\n')
282: - printcol = 0; else
283: - if(c == '\t')
284: - printcol = (printcol+7) & ~7;
285: - f2--;
286: - }
287: - if(f1 < 0) {
288: - f1 = -f1;
289: - while(n < f1) {
290: - if(out < eout)
291: - *out++ = ' ';
292: - printcol++;
293: - n++;
294: - }
295: - }
296: -}
297:
298: chconv(o, f1)
299: char o;
300: -{
301: - register int n;
302:
303: - n = 1;
304: - if(f1 >= 0)
305: - while(n < f1) {
306: - if(out < eout)
307: - *out++ = ' ';
308: - printcol++;
309: - n++;
310: - }
311: - if(out < eout)
312: - *out++ = o;
313: - printcol++;
314: - if(o == '\n')
315: - printcol = 0; else
316: - if(o == '\t')
317: - printcol = (printcol+7) & ~7;
318: - if(f1 < 0) {
319: - f1 = -f1;
320: - while(n < f1) {
321: - if(out < eout)
322: - *out++ = ' ';
323: - printcol++;
324: - n++;
325: - }
326: - }
327: -}
328:
329: -/* ARGSUSED */
330: static
331: noconv(o, f1, f2, f3)
332: char *o;
333: -{
334:
335: - strconv("***", 0, -1);
336: - return 0;
337: -}
338:
339: -/* ARGSUSED */
340: static
341: cconv(o, f1, f2, f3)
342: va_list *o;
343: -{
344: - chconv((char)va_arg(*o, int), f1);
345: - return INT;
346: -}
347:
348: static
349: dconv(o, f1, f2, f3)
350: va_list *o;
351: -{
352: - int r;
353:
354: - r = numbconv(o, f1, f2, f3, 10);
355: - return r;
356: -}
357:
358: -/* ARGSUSED */
359: static
360: hconv(o, f1, f2, f3)
361: -{
362: - return -FSHORT;
363: -}
364:
365: -/* ARGSUSED */
366: static
367: lconv(o, f1, f2, f3)
368: -{
369:
370: - return -FLONG;
371: -}
372:
373: static
374: oconv(o, f1, f2, f3)
375: va_list *o;
376: -{
377: - int r;
378:
379: - r = numbconv(o, f1, f2, f3, 8);
380: - return r;
381: -}
382:
383: -/* ARGSUSED */
384: static
385: sconv(o, f1, f2, f3)
386: va_list *o;
387: -{
388:
389: - strconv(va_arg(*o, char *), f1, f2);
390: - return PTR;
391: -}
392:
393: -/* ARGSUSED */
394: static
395: uconv(o, f1, f2, f3)
396: -{
397: - return -FUNSIGN;
398: -}
399:
400: static
401: xconv(o, f1, f2, f3)
402: va_list *o;
403: -{
404: - int r;
405:
406: - r = numbconv(o, f1, f2, f3, 16);
407: - return r;
408: -}
409:
410: double pow10(), frexp();
411: -/* ARGSUSED */
412: fltconv(f, f1, f2, f3, c)
413: register double f;
414: -{
415: - char s1[FDIGIT+10], s2[FDIGIT+10];
416: - register double g;
417: - register int d, i, n, s;
418: - double h;
419: - int e;
420: - int c1, c2, c3;
421:
422: - s = 0;
423: - if(f < 0) {
424: - f = -f;
425: - s++;
426: - }
427:
428: loop:
429: - e = 0;
430: - g = 0;
431: - if(f != 0) {
432: - g = frexp(f, &e);
433: - e = e * .30103;
434: - d = e/2;
435: - h = f * pow10(-d); /* 10**-e in 2 parts */
436: - g = h * pow10(d-e);
437: - while(g < 1) {
438: - e--;
439: - g = h * pow10(d-e);
440: - }
441: - while(g >= 10) {
442: - e++;
443: - g = h * pow10(d-e);
444: - }
445: - }
446: - if(f2 < 0)
447: - f2 = FDEFLT;
448: - if(c == 'g' && f2 > 0)
449: - f2--;
450: - if(f2 > FDIGIT)
451: - f2 = FDIGIT;
452: - /*
453: - * n is number of digits to convert
454: - * 1 before, f2 after, 1 extra for rounding
455: - */
456: - n = f2 + 2;
457: - if(c == 'f') {
458: - /*
459: - * e+1 before, f2 after, 1 extra
460: - */
461: - n += e;
462: - if(n <= 0) {
463: - n = 1;
464: - g = 0;
465: - }
466: - }
467: - if(n >= FDIGIT+2) {
468: - if(c == 'e')
469: - f2 = -1;
470: - c = 'e';
471: - goto loop;
472: - }
473: - /*
474: - * convert n digits
475: - */
476: - for(i=0; i<n; i++) {
477: - d = g;
478: - if(d > g)
479: - d--;
480: - g -= d;
481: - s1[i+1] = d + '0';
482: - g *= 10;
483: - }
484: - /*
485: - * round by adding .5 into extra digit
486: - */
487: - d = 5;
488: - for(i=n-1; i>=0; i--) {
489: - s1[i+1] += d;
490: - d = 0;
491: - if(s1[i+1] > '9') {
492: - s1[i+1] -= 10;
493: - d++;
494: - }
495: - }
496: - i = 1;
497: - if(d) {
498: - s1[0] = '1';
499: - e++;
500: - i = 0;
501: - }
502: - /*
503: - * copy into final place
504: - * c1 digits of leading '0'
505: - * c2 digits from conversion
506: - * c3 digits after '.'
507: - */
508: - d = 0;
509: - if(s)
510: - s2[d++] = '-';
511: - c1 = 0;
512: - c2 = f2 + 1;
513: - c3 = f2;
514: - if(c == 'g')
515: - if(e >= -5 && e <= f2) {
516: - c1 = -e - 1;
517: - c3 = c1;
518: - if(c1 < 0)
519: - c1 = 0;
520: - c3 = f2 - e;
521: - c = 'h';
522: - }
523: - if(c == 'f') {
524: - c1 = -e;
525: - if(c1 < 0)
526: - c1 = 0;
527: - if(c1 > f2)
528: - c1 = c2;
529: - c2 += e;
530: - if(c2 < 0)
531: - c2 = 0;
532: - }
533: - while(c1 > 0) {
534: - if(c1+c2 == c3)
535: - s2[d++] = '.';
536: - s2[d++] = '0';
537: - c1--;
538: - }
539: - while(c2 > 0) {
540: - if(c1+c2 == c3)
541: - s2[d++] = '.';
542: - s2[d++] = s1[i++];
543: - c2--;
544: - }
545: - /*
546: - * strip trailing '0' on g conv
547: - */
548: - if(c == 'g' || c == 'h') {
549: - for(n=d-1; n>=0; n--)
550: - if(s2[n] != '0')
551: - break;
552: - for(i=n; i>=0; i--)
553: - if(s2[i] == '.') {
554: - d = n;
555: - if(i != n)
556: - d++;
557: - break;
558: - }
559: - }
560: - if(c == 'e' || c == 'g') {
561: - s2[d++] = 'e';
562: - s2[d++] = '+';
563: - c1 = e;
564: - if(c1 < 0) {
565: - s2[d-1] = '-';
566: - c1 = -c1;
567: - }
568: - if(c1 >= 100) {
569: - s2[d++] = c1/100 + '0';
570: - c1 %= 100;
571: - }
572: - s2[d++] = c1/10 + '0';
573: - s2[d++] = c1%10 + '0';
574: - }
575: - s2[d] = 0;
576: - strconv(s2, f1, -1);
577: - return FLOAT;
578: -}
579:
580: static
581: econv(o, f1, f2, f3)
582: va_list *o;
583: -{
584:
585: - return fltconv(va_arg(*o, double), f1, f2, f3, 'e');
586: -}
587:
588: static
589: fconv(o, f1, f2, f3)
590: va_list *o;
591: -{
592:
593: - return fltconv(va_arg(*o, double), f1, f2, f3, 'f');
594: -}
595:
596: static
597: gconv(o, f1, f2, f3)
598: va_list *o;
599: -{
600:
601: - return fltconv(va_arg(*o, double), f1, f2, f3, 'g');
602: -}
603:
604: static
605: percent()
606: -{
607:
608: - if(out < eout)
609: - *out++ = '%';
610: - return 0;
611: -}
612: !
613: echo libc/print.c 1>&2
614: sed 's/^-//' >libc/print.c <<'!'
615: -#include <varargs.h>
616:
617: -#define SIZE 1024
618: extern int printcol;
619:
620: char *doprint();
621:
622: -/* VARARGS 1 */
623: print(fmt, va_alist)
624: char *fmt;
625: va_dcl
626: -{
627: - char buf[SIZE], *out;
628: - va_list ap;
629:
630: - va_start(ap);
631: - out = doprint(buf, fmt, &ap);
632: - va_end(ap);
633: - return write(1, buf, (int)(out-buf));
634: -}
635:
636: -/* VARARGS 2 */
637: fprint(fd, fmt, va_alist)
638: char *fmt;
639: va_dcl
640: -{
641: - char buf[SIZE], *out;
642: - va_list ap;
643:
644: - va_start(ap);
645: - out = doprint(buf, fmt, &ap);
646: - va_end(ap);
647: - return write(fd, buf, (int)(out-buf));
648: -}
649:
650: -/* VARARGS 2 */
651: sprint(buf, fmt, va_alist)
652: char *buf;
653: char *fmt;
654: va_dcl
655: -{
656: - char *out;
657: - int scol;
658: - va_list ap;
659:
660: - scol = printcol;
661: - va_start(ap);
662: - out = doprint(buf, fmt, &ap);
663: - va_end(ap);
664: - printcol = scol;
665: - return out-buf;
666: -}
667: !
668:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.