|
|
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.