|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)output.c 5.1 (Berkeley) 1/16/89";
3: #endif
4:
5: /*
6: * adb - output
7: */
8:
9: #include "defs.h"
10: #include <ctype.h>
11: #include <stdio.h>
12: #include <varargs.h>
13:
14: extern char TOODEEP[];
15:
16: int infile;
17: int outfile = 1;
18:
19: char printbuf[LINELEN];
20: char *printptr = printbuf;
21:
22:
23: /*
24: * Print the string s.
25: */
26: prints(s)
27: register char *s;
28: {
29: register int c;
30:
31: while ((c = *s++) != '\0')
32: printc(c);
33: }
34:
35: /*
36: * Print the character c.
37: */
38: printc(c)
39: int c;
40: {
41:
42: if (mkfault)
43: return;
44: switch (c) {
45:
46: case 0:
47: return;
48:
49: case '\n':
50: sendout();
51: return;
52:
53: default:
54: if (isprint(c))
55: *printptr++ = c;
56: break;
57: }
58: if (printptr >= &printbuf[LINELEN - 1]) /* 1 == space for \n */
59: sendout();
60: }
61:
62: /*
63: * Send (write) out the contents of the print buffer, compressing
64: * spaces into tabs.
65: */
66: static
67: sendout()
68: {
69: register char *p, *q;
70: register int c, off = 0, spaces = 0, s;
71: #define tabsize(x) (8 - ((x) & 7))
72:
73: for (q = p = printbuf; p < printptr;) {
74: c = *p++;
75: switch (c) {
76:
77: case ' ':
78: spaces++;
79: break;
80:
81: case '\t':
82: spaces += tabsize(off + spaces);
83: break;
84:
85: default:
86: s = tabsize(off);
87: off += spaces + 1;
88: while (spaces >= s) {
89: *q++ = '\t';
90: spaces -= s;
91: s = 8;
92: }
93: while (--spaces >= 0)
94: *q++ = ' ';
95: spaces = 0;
96: *q++ = c;
97: }
98: }
99: *q++ = '\n';
100: (void) write(outfile, printbuf, q - printbuf);
101: printptr = printbuf;
102: #undef tabsize
103: }
104:
105: charpos()
106: {
107:
108: return (printptr - printbuf);
109: }
110:
111: endline()
112: {
113:
114: if (printptr - printbuf >= maxcol)
115: printc('\n');
116: }
117:
118: flushbuf()
119: {
120:
121: if (printptr != printbuf)
122: sendout();
123: }
124:
125: /* this should not be necessary! */
126: #ifdef lint
127: #undef va_arg
128: #define va_arg(ap, type) (ap = ap, (type)0)
129: #endif
130:
131: /*
132: * Context passed between adbprintf and decodefmt.
133: */
134: struct prf {
135: char *fmt; /* format pointer */
136: va_list ap; /* argument pointer */
137: char *buf; /* digit buffer, or %s string */
138: int adj; /* 'l'eft (-) or 'r'ight adjustment */
139: int width; /* width from format */
140: int prec; /* precision from format */
141: };
142:
143: /*
144: * adb's very own version of printf() ... of course, all the format
145: * escapes are different. Noteworthy are the %<width>m and %<tabstop>t
146: * formats, which move the given width, or to the given tabstop, and
147: * the %?a format, which evaluates one argument, and if not zero, prints
148: * according to format a. (Note that any modifiers must appear in the
149: * `a' part, not in the %? part.)
150: */
151: /* VARARGS1 */
152: adbprintf(fmt, va_alist)
153: char *fmt;
154: va_dcl
155: {
156: register char *s;
157: register int n, c;
158: struct prf prf;
159: char digits[130]; /* good to at least 128 bit expr_t */
160:
161: /* set up the fields adbprf needs */
162: prf.fmt = fmt;
163: va_start(prf.ap);
164: for (;;) {
165: /* look for % conversions */
166: s = prf.fmt;
167: while ((c = *s++) != '%') {
168: if (c == 0)
169: return;
170: printc(c);
171: }
172: prf.fmt = s;
173: prf.buf = digits;
174: dofmt(&prf); /* format one format */
175: n = strlen(s = prf.buf);
176: if (prf.prec >= 0 && n > prf.prec)
177: n = prf.prec;
178: c = prf.width - n;
179: if (prf.adj == 'r')
180: while (--c >= 0)
181: printc(' ');
182: while (--n >= 0)
183: printc(*s++);
184: while (--c >= 0)
185: printc(' ');
186: }
187: va_end(prf.ap);
188: }
189:
190: /*
191: * Do a single format.
192: */
193: static
194: dofmt(prf)
195: register struct prf *prf;
196: {
197: register char *s = prf->fmt;
198: register va_list ap = prf->ap;
199: register int c, n;
200: expr_t v;
201: int pluspref = 0;
202: static char null[] = "";
203:
204: prf->adj = 'r';
205: prf->width = 0;
206: prf->prec = -1;
207: more:
208: c = *s++;
209: sw:
210: switch (c) {
211:
212: case '-':
213: prf->adj = 'l';
214: goto more;
215:
216: case '+':
217: pluspref = 1;
218: goto more;
219:
220: case '*':
221: prf->width = va_arg(ap, int);
222: goto more;
223:
224: case '0': case '1': case '2': case '3': case '4':
225: case '5': case '6': case '7': case '8': case '9':
226: for (n = c - '0'; isdigit(c = *s++);)
227: n = 10 * n + c - '0';
228: prf->width = n;
229: goto sw;
230:
231: case '.':
232: c = *s++;
233: if (c == '*') {
234: prf->prec = va_arg(ap, int);
235: goto more;
236: }
237: for (n = 0; isdigit(c); c = *s++)
238: n = 10 * n + c - '0';
239: prf->prec = n;
240: goto sw;
241:
242: case 'v': case 'V':
243: /* print in signed version of current radix */
244: if ((n = radix) > 0)
245: n = -n;
246: goto rprint;
247:
248: case 'q': case 'Q': n = -8; goto rprint; /* octal */
249: case 'd': case 'D': n = -10; goto rprint; /* decimal */
250: case 'z': case 'Z': n = -16; goto rprint; /* hex */
251: case 'o': case 'O': n = 8; goto rprint; /* and */
252: case 'u': case 'U': n = 10; goto rprint; /* unsigned */
253: case 'x': case 'X': n = 16; goto rprint; /* versions */
254:
255: case 'r': case 'R':
256: n = radix;
257: rprint:
258: if (isupper(c))
259: v = n < 0 ? SF_ARG : UF_ARG;
260: else
261: v = n < 0 ? SH_ARG : UH_ARG;
262: printradix(prf->buf, v, n, pluspref);
263: break;
264:
265: case 'Y':
266: printdate(prf->buf, va_arg(ap, time_t));
267: break;
268:
269: case 'c':
270: *prf->buf = va_arg(ap, int);
271: prf->buf[1] = 0;
272: break;
273:
274: case 's':
275: prf->buf = va_arg(ap, char *);
276: break;
277:
278: case 'f':
279: /* here comes stdio ... sigh */
280: (void) sprintf(prf->buf, "%+*.*e", prf->width,
281: prf->prec >= 0 ? prf->prec : 16, va_arg(ap, double));
282: prf->prec = -1;
283: break;
284:
285: case 'm':
286: prf->buf = null;
287: break;
288:
289: case 't':
290: if (prf->width)
291: prf->width -= charpos() % prf->width;
292: prf->buf = null;
293: break;
294:
295: case '?':
296: c = va_arg(ap, int);
297: prf->fmt = s;
298: prf->ap = ap;
299: dofmt(prf);
300: if (c == 0)
301: prf->buf = null;
302: return;
303:
304: default:
305: panic("dofmt");
306: /* NOTREACHED */
307: }
308: prf->fmt = s;
309: prf->ap = ap;
310: }
311:
312: /*
313: * Print the date into the buffer at `p'.
314: */
315: static
316: printdate(p, tm)
317: register char *p;
318: time_t tm;
319: {
320: char *asc = ctime(&tm);
321: char *strncpy();
322:
323: (void) strncpy(p, asc + 20, 4); /* "1988" */
324: (void) strncpy(p + 4, asc + 3, 16); /* " Aug 18 03:04:49" */
325: p[20] = 0;
326: }
327:
328: /*
329: * Print the value `val' in base `base' into the buffer at `p'.
330: * If base is negative, assume the number is signed.
331: */
332: static
333: printradix(p, val, base, pluspref)
334: register char *p;
335: register expr_t val;
336: register int base;
337: int pluspref;
338: {
339: register char *d;
340: register expr_t high;
341: char digs[128]; /* good to 128 bits minimum */
342:
343: if (base < 0) {
344: base = -base;
345: if ((sexpr_t)val < 0) {
346: val = -val;
347: *p++ = '-';
348: } else if (pluspref)
349: *p++ = '+';
350: } else if (pluspref)
351: *p++ = '+';
352:
353: d = digs;
354: switch (base) {
355:
356: case 8:
357: while (val != 0) {
358: *d++ = val & 7;
359: val >>= 3;
360: }
361: *d++ = 0;
362: break;
363:
364: case 16:
365: do {
366: *d++ = val & 15;
367: } while ((val >>= 4) != 0);
368: break;
369:
370: default:
371: do {
372: high = val / base;
373: *d++ = val - (high * base);
374: } while ((val = high) != 0);
375: break;
376: }
377: while (d > digs)
378: *p++ = "0123456789abcdef"[*--d];
379: *p = 0;
380: }
381:
382: /*
383: * BEGIN XXX
384: * THIS BELONGS ELSEWHERE
385: */
386: #define MAXIFD 5
387: struct {
388: int fd;
389: expr_t v9;
390: } istack[MAXIFD];
391: int ifiledepth;
392:
393: iclose(stack, err)
394: int stack, err;
395: {
396:
397: if (err) {
398: if (infile) {
399: (void) close(infile);
400: infile = 0;
401: }
402: while (--ifiledepth >= 0)
403: if (istack[ifiledepth].fd)
404: (void) close(istack[ifiledepth].fd);
405: ifiledepth = 0;
406: } else if (stack == 0) {
407: if (infile) {
408: (void) close(infile);
409: infile = 0;
410: }
411: } else if (stack > 0) {
412: if (ifiledepth >= MAXIFD)
413: error(TOODEEP);
414: istack[ifiledepth].fd = infile;
415: istack[ifiledepth].v9 = var[9];
416: ifiledepth++;
417: infile = 0;
418: } else {
419: if (infile) {
420: (void) close(infile);
421: infile = 0;
422: }
423: if (ifiledepth > 0) {
424: infile = istack[--ifiledepth].fd;
425: var[9] = istack[ifiledepth].v9;
426: }
427: }
428: }
429:
430: oclose()
431: {
432:
433: if (outfile != 1) {
434: flushbuf();
435: (void) close(outfile);
436: outfile = 1;
437: }
438: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.