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