|
|
1.1 root 1: /* C compiler: output functions */
2:
3: #include "c.h"
4:
5: static char buf1[4*1024], buf2[512]; /* output buffers */
6: static struct io {
7: int fd; /* file descriptor */
8: char *bp; /* buffer pointer */
9: char *buffer; /* buffer proper */
10: char *limit; /* high water limit */
11: } iob[] = {
12: 0, 0, 0, 0,
13: 1, buf1, buf1, buf1 + sizeof buf1 - 80,
14: 2, buf2, buf2, buf2 + sizeof buf2 - 80
15: }, *io[] = {
16: &iob[0], /* used by stringf */
17: &iob[1], /* output */
18: &iob[2] /* standard error & other files; used by fprint */
19: };
20: static int fd = 1; /* current output file */
21:
22: char *bp = buf1; /* current output buffer pointer */
23:
24: /* outputInit - initialize output system */
25: void outputInit(fd) {
26: io[1]->fd = fd;
27: }
28:
29: /* fprint - formatted output to file descriptor f */
30: #ifdef __STDC__
31: void fprint(int f, char *fmt, ...) {
32: #else
33: void fprint(f, fmt, va_alist) char *fmt; va_dcl {
34: #endif
35: va_list ap;
36:
37: va_init(ap, fmt);
38: vfprint(f, fmt, ap);
39: va_end(ap);
40: }
41:
42: /* outflush - flush output buffer; writes last buffer first */
43: void outflush() {
44: struct io *iop = io[fd];
45:
46: assert(fd);
47: if (bp > iop->buffer)
48: write(iop->fd, iop->buffer, bp - iop->buffer);
49: bp = iop->bp = iop->buffer;
50: }
51:
52: /* outs - output string s */
53: void outs(s) char *s; {
54: char *p;
55:
56: for (p = bp; *p = *s++; p++)
57: ;
58: bp = p;
59: if (bp > io[fd]->limit)
60: outflush();
61: }
62:
63: /* print - formatted output to standard output */
64: #ifdef __STDC__
65: void print(char *fmt, ...) {
66: #else
67: void print(fmt, va_alist) char *fmt; va_dcl {
68: #endif
69: va_list ap;
70:
71: va_init(ap, fmt);
72: vprint(fmt, ap);
73: va_end(ap);
74: }
75:
76: /* stringf - formatted output to a saved string */
77: #ifdef __STDC__
78: char *stringf(char *fmt, ...) {
79: #else
80: char *stringf(fmt, va_alist) char *fmt; va_dcl {
81: #endif
82: char buf[1024];
83: va_list ap;
84:
85: va_init(ap, fmt);
86: fd = 0;
87: io[1]->bp = bp;
88: bp = io[0]->bp = io[0]->buffer = buf;
89: io[0]->limit = buf + sizeof buf;
90: vprint(fmt, ap);
91: *bp = 0;
92: bp = io[1]->bp;
93: fd = 1;
94: va_end(ap);
95: return string(buf);
96: }
97:
98: /* vfprint - formatted output to file descriptor f */
99: void vfprint(f, fmt, ap) char *fmt; va_list ap; {
100: if (f == 1)
101: vprint(fmt, ap);
102: else {
103: fd = 2;
104: io[1]->bp = bp;
105: io[2]->fd = f;
106: bp = io[2]->bp;
107: vprint(fmt, ap);
108: outflush();
109: bp = io[1]->bp;
110: fd = 1;
111: }
112: }
113:
114: /* vprint - formatted output to standard output */
115: void vprint(fmt, ap) char *fmt; va_list ap; {
116: for (; *fmt; fmt++)
117: if (*fmt == '%')
118: switch (*++fmt) {
119: case 'c': { *bp++ = va_arg(ap, int);
120: } break;
121: case 'd': { int n = va_arg(ap, int);
122: unsigned m;
123: char buf[25], *s = buf + sizeof buf;
124: *--s = 0;
125: if (n == INT_MIN)
126: m = (unsigned)INT_MAX + 1;
127: else if (n < 0)
128: m = -n;
129: else
130: m = n;
131: do
132: *--s = m%10 + '0';
133: while (m /= 10);
134: if (n < 0)
135: *--s = '-';
136: outs(s);
137: } break;
138: case 'o': { unsigned n = va_arg(ap, unsigned);
139: char buf[25], *s = buf + sizeof buf;
140: *--s = 0;
141: do
142: *--s = (n&7) + '0';
143: while (n >>= 3);
144: outs(s);
145: } break;
146: case 'x': { unsigned n = va_arg(ap, unsigned);
147: char buf[25], *s = buf + sizeof buf;
148: *--s = 0;
149: do
150: *--s = "0123456789abcdef"[n&0xf];
151: while (n >>= 4);
152: outs(s);
153: } break;
154: case 's': { char *s = va_arg(ap, char *);
155: if (s)
156: outs(s);
157: } break;
158: case 'S': { char *s = va_arg(ap, char *);
159: int n = va_arg(ap, int);
160: if (s)
161: while (n-- > 0)
162: *bp++ = *s++;
163: } break;
164: case 'k': { int t = va_arg(ap, int);
165: static char *tokens[] = {
166: #define xx(a,b,c,d,e,f,g) g,
167: #define yy xx
168: #include "token.h"
169: };
170: assert(tokens[t&0177]);
171: outs(tokens[t&0177]);
172: } break;
173: case 't': { Type ty = va_arg(ap, Type);
174: outtype(ty ? ty : voidtype);
175: } break;
176: case 'w': { Coordinate *p = va_arg(ap, Coordinate *);
177: if (p->file && *p->file)
178: print("%s:", p->file);
179: print("%d", p->y);
180: break; } break;
181: default: *bp++ = *fmt; break;
182: }
183: else if ((*bp++ = *fmt) == '\n' && bp > io[fd]->limit)
184: outflush();
185: }
186:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.