|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)format.c 5.3 (Berkeley) 6/29/90"; ! 3: #endif ! 4: ! 5: /* ! 6: * adb - formats ! 7: */ ! 8: ! 9: #include "defs.h" ! 10: #include <ctype.h> ! 11: #include <vis.h> ! 12: ! 13: extern char BADMOD[]; ! 14: extern char NOFORK[]; ! 15: ! 16: /* symbol desirability in exform() */ ! 17: enum { IFEXACT, ALWAYS, NEVER } wantsym; ! 18: ! 19: char *exform(); ! 20: ! 21: /* ! 22: * Execute the given format `ecount' times. ! 23: */ ! 24: scanform(forcesym, fmt, space, ptype) ! 25: int forcesym; ! 26: char *fmt; ! 27: int space, ptype; ! 28: { ! 29: register char *p; ! 30: register int c, n; ! 31: register expr_t ntimes = ecount; ! 32: addr_t savdot, newdot; ! 33: ! 34: if (ntimes == 0) ! 35: return; ! 36: for (wantsym = forcesym ? ALWAYS : IFEXACT;; wantsym = IFEXACT) { ! 37: p = fmt; ! 38: savdot = dot; ! 39: while (p != NULL) { /* loop over format items */ ! 40: n = 0; /* get optional count */ ! 41: while (isdigit(c = *p++)) ! 42: n = n * 10 + c - '0'; ! 43: if (c == 0) /* end of format */ ! 44: break; ! 45: p = exform(n ? n : 1, p - (c != '\\'), space, ptype); ! 46: } ! 47: dotinc = (newdot = dot) - savdot; ! 48: dot = savdot; ! 49: if (errflag != NULL && (long)ntimes < 0) { ! 50: errflag = NULL; ! 51: break; ! 52: } ! 53: checkerr(); ! 54: if (--ntimes == 0) ! 55: break; ! 56: dot = newdot; ! 57: } ! 58: } ! 59: ! 60: /* ! 61: * Print a halfword or a word from dot. ! 62: */ ! 63: showdot(fullword, space, ptype) ! 64: int fullword, space, ptype; ! 65: { ! 66: char c = fullword ? '4' : '2'; ! 67: ! 68: wantsym = NEVER; ! 69: (void) exform(1, &c, space, ptype); ! 70: } ! 71: ! 72: /* ! 73: * The following are used inside exform(). ! 74: * ! 75: * The various FT_ values specify the type of the object accessed ! 76: * by some format character. FT_DULL indicates that no object is ! 77: * accessed (or that it is done in some peculiar way). ! 78: * The fsize array holds the size (in bytes) ! 79: * of each of those types; the fmttypes[] array lists the type for ! 80: * each character. To save space, since there are many characters ! 81: * for some of the types, they are stored as strings. ! 82: */ ! 83: enum { FT_DULL, FT_CHAR, FT_HW, FT_FW, FT_ADDR, FT_FLT, FT_DBL, FT_TM }; ! 84: /* these may have to be turned into `#define's */ ! 85: ! 86: static char fsize[] = { /* ordered by enumeration above! */ ! 87: 0, sizeof(char), sizeof(hword_t), sizeof(expr_t), ! 88: sizeof(addr_t), sizeof(float), sizeof(double), sizeof(time_t) ! 89: }; ! 90: ! 91: static struct fmttypes { ! 92: char *ft_chars; ! 93: int ft_type; ! 94: } fmttypes[] = { ! 95: { "\t\" +-NRST^inrst", FT_DULL }, ! 96: { "1BCbc", FT_CHAR }, ! 97: { "2doquvxz", FT_HW }, ! 98: { "4DOQUVXZ", FT_FW }, ! 99: { "p", FT_ADDR }, ! 100: { "f", FT_FLT }, ! 101: { "F", FT_DBL }, ! 102: { "Y", FT_TM }, ! 103: 0 ! 104: }; ! 105: ! 106: /* ! 107: * Execute a single format item `fcount' times; set ! 108: * dotinc and move dot. Return the address of the next ! 109: * format item, or NULL upon error reading an object. ! 110: * ! 111: * I must apologise for the length of this routine, but ! 112: * it is bloated mainly with type correctness. ! 113: */ ! 114: char * ! 115: exform(fcount, fmt, space, ptype) ! 116: int fcount; ! 117: char *fmt; ! 118: int space, ptype; ! 119: { ! 120: register struct fmttypes *ftp; ! 121: register int sz; ! 122: register char *p, *s, fmtchar; ! 123: addr_t savdot, off; ! 124: struct nlist *sp; ! 125: union { ! 126: char c; ! 127: hword_t hw; ! 128: expr_t fw; ! 129: float f; ! 130: double d; ! 131: time_t tm; ! 132: addr_t a; ! 133: } obj; ! 134: ! 135: while (fcount > 0) { ! 136: /* ! 137: * First decode the type to be used with the expression. ! 138: * If address, print dot as a symbol, save it in var 0, ! 139: * and bypass all the nonsense. ! 140: */ ! 141: p = fmt; ! 142: fmtchar = *p++; ! 143: ! 144: /* address: special */ ! 145: if (fmtchar == 'a') { ! 146: pdot(); ! 147: wantsym = NEVER; /* well, hardly ever */ ! 148: var[0] = dot; ! 149: return (p); ! 150: } ! 151: ! 152: for (ftp = fmttypes; (s = ftp->ft_chars) != NULL; ftp++) ! 153: while (*s != 0) ! 154: if (*s++ == fmtchar) ! 155: goto found; ! 156: error(BADMOD); ! 157: /* NOTREACHED */ ! 158: found: ! 159: ! 160: /* plop out a symbol, if desired */ ! 161: if (wantsym == ALWAYS) ! 162: pdot(); ! 163: else if (wantsym == IFEXACT && ! 164: (sp = findsym(dot, ptype, &off)) != NULL && off == 0) ! 165: adbprintf("\n%s:%16t", sp->n_un.n_name); /* \n ??? */ ! 166: wantsym = NEVER; ! 167: ! 168: /* ! 169: * Now read the sort of object we decided fmtchar represents, ! 170: * or compute it from the expression given for dot. ! 171: */ ! 172: sz = fsize[ftp->ft_type]; ! 173: if (space != SP_NONE) { ! 174: /* can just read into the union */ ! 175: if (sz != 0) ! 176: (void) adbread(space, dot, &obj, sz); ! 177: else ! 178: obj.fw = edot; ! 179: } else { ! 180: /* must decode type in order to assign, alas */ ! 181: switch (ftp->ft_type) { ! 182: ! 183: case FT_CHAR: ! 184: obj.c = edot; ! 185: break; ! 186: ! 187: case FT_HW: ! 188: obj.hw = edot; ! 189: break; ! 190: ! 191: case FT_FW: ! 192: obj.fw = edot; ! 193: break; ! 194: ! 195: case FT_DULL: ! 196: case FT_ADDR: ! 197: obj.a = dot; ! 198: break; ! 199: ! 200: case FT_FLT: ! 201: case FT_DBL: ! 202: obj.fw = 0; ! 203: etofloat(edot, &obj.c, ftp->ft_type == FT_DBL); ! 204: break; ! 205: ! 206: case FT_TM: ! 207: obj.fw = 0; ! 208: obj.tm = edot; ! 209: break; ! 210: ! 211: default: ! 212: panic("exform 1"); ! 213: /* NOTREACHED */ ! 214: } ! 215: } ! 216: ! 217: /* if we could not read the object, stop now. */ ! 218: if (errflag) ! 219: return (NULL); ! 220: if (mkfault) ! 221: error((char *)NULL); ! 222: ! 223: /* ! 224: * Now copy the value read (or assigned) to var[0]. ! 225: * Here some of the types are collapsed: since the ! 226: * idea is to be able to get the value back later ! 227: * by reading var[0] and going through the type ! 228: * decoding above, it sometimes suffices to record ! 229: * as many bits as fit in an expr_t (see expr.c). ! 230: * ! 231: * Note that double precision numbers generally lose ! 232: * bits, since sizeof(double) can be > sizeof(expr_t). ! 233: */ ! 234: switch (ftp->ft_type) { ! 235: ! 236: case FT_CHAR: ! 237: var[0] = obj.c; ! 238: break; ! 239: ! 240: case FT_HW: ! 241: var[0] = obj.hw; ! 242: break; ! 243: ! 244: case FT_FW: ! 245: case FT_FLT: ! 246: case FT_DBL: ! 247: case FT_TM: ! 248: var[0] = obj.fw; ! 249: break; ! 250: ! 251: case FT_DULL: ! 252: case FT_ADDR: ! 253: var[0] = obj.a; ! 254: break; ! 255: ! 256: default: ! 257: panic("exform 2"); ! 258: /* NOTREACHED */ ! 259: } ! 260: ! 261: /* set the size, if this object has a size */ ! 262: if (sz) ! 263: dotinc = sz; ! 264: ! 265: /* finally, do the command */ ! 266: if (charpos() == 0) ! 267: adbprintf("%16m"); ! 268: switch (fmtchar) { ! 269: /* ! 270: * Many of the formats translate to a %-8 or %-16 ! 271: * edition of themselves; we use a single string, ! 272: * and modify the format part, for these. ! 273: */ ! 274: static char cfmt[] = "%-*?"; ! 275: ! 276: case ' ': ! 277: case '\t': ! 278: dotinc = 0; ! 279: break; ! 280: ! 281: case 't': ! 282: case 'T': ! 283: adbprintf("%*t", fcount); ! 284: return (p); ! 285: ! 286: case 'r': ! 287: case 'R': ! 288: adbprintf("%*m", fcount); ! 289: return (p); ! 290: ! 291: case 'p': ! 292: psymoff("%R", obj.a, ptype, maxoff, "%16t"); ! 293: break; ! 294: ! 295: case 'c': ! 296: printc(obj.c); ! 297: break; ! 298: ! 299: case 'C': ! 300: printesc(obj.c); ! 301: break; ! 302: ! 303: case 'b': ! 304: case 'B': ! 305: adbprintf("%-8O", (expr_t)(u_char)obj.c); ! 306: break; ! 307: ! 308: case 's': ! 309: case 'S': ! 310: savdot = dot; ! 311: for (;;) { ! 312: if (adbread(space, dot, &obj.c, 1) != 1 || ! 313: iserr() || obj.c == 0) ! 314: break; ! 315: dot = inkdot(1); ! 316: if (fmtchar == 'S') ! 317: printesc(obj.c); ! 318: else ! 319: printc(obj.c); ! 320: endline(); ! 321: } ! 322: dotinc = dot - savdot + 1; ! 323: dot = savdot; ! 324: break; ! 325: ! 326: case '1': ! 327: adbprintf("%-8R", (expr_t)(u_char)obj.c); ! 328: break; ! 329: ! 330: case '2': ! 331: fmtchar = 'r'; ! 332: /* FALLTHROUGH */ ! 333: ! 334: case 'v': ! 335: case 'u': case 'd': ! 336: case 'o': case 'q': ! 337: case 'x': case 'z': ! 338: cfmt[3] = fmtchar; ! 339: adbprintf(cfmt, 8, obj.hw); ! 340: break; ! 341: ! 342: case '4': ! 343: fmtchar = 'R'; ! 344: /* FALLTHROUGH */ ! 345: ! 346: case 'V': ! 347: case 'U': case 'D': ! 348: case 'O': case 'Q': ! 349: case 'X': case 'Z': ! 350: cfmt[3] = fmtchar; ! 351: adbprintf(cfmt, 16, obj.fw); ! 352: break; ! 353: ! 354: case 'Y': ! 355: adbprintf("%-24Y", obj.tm); ! 356: break; ! 357: ! 358: case 'i': ! 359: printins(space); /* also sets dotinc */ ! 360: printc('\n'); ! 361: break; ! 362: ! 363: case 'f': ! 364: s = checkfloat((caddr_t)&obj.f, 0); ! 365: if (s != NULL) ! 366: adbprintf("%-16s", s); ! 367: else ! 368: adbprintf("%-16.9f", obj.f); ! 369: break; ! 370: ! 371: case 'F': ! 372: s = checkfloat((caddr_t)&obj.d, 1); ! 373: if (s != NULL) ! 374: adbprintf("%-32s", s); ! 375: else ! 376: adbprintf("%-32.18f", obj.d); ! 377: break; ! 378: ! 379: case 'n': ! 380: case 'N': ! 381: printc('\n'); ! 382: dotinc = 0; ! 383: break; ! 384: ! 385: case '"': ! 386: while (*p != 0 && *p != '"') ! 387: printc(*p++); ! 388: if (*p) ! 389: p++; ! 390: dotinc = 0; ! 391: break; ! 392: ! 393: case '^': ! 394: dot = inkdot(-dotinc * fcount); ! 395: return (p); ! 396: ! 397: case '+': ! 398: dot = inkdot(fcount); ! 399: return (p); ! 400: ! 401: case '-': ! 402: dot = inkdot(-fcount); ! 403: return (p); ! 404: ! 405: default: ! 406: panic("exform 3"); ! 407: /* NOTREACHED */ ! 408: } ! 409: if (space != SP_NONE) ! 410: dot = inkdot(dotinc); ! 411: fcount--; ! 412: endline(); ! 413: } ! 414: return (p); ! 415: } ! 416: ! 417: /* ! 418: * Print dot in its canonical format. ! 419: */ ! 420: pdot() ! 421: { ! 422: ! 423: psymoff("%R", dot, SP_INSTR, maxoff, ":%16t"); ! 424: } ! 425: ! 426: /* ! 427: * Print character c using ASCII escape conventions. ! 428: */ ! 429: printesc(c) ! 430: register int c; ! 431: ! 432: { ! 433: char visbuf[5]; ! 434: ! 435: vis(visbuf, (char)c, VIS_TAB | VIS_NL | VIS_NOSLASH, 0); ! 436: adbprintf("%s", visbuf); ! 437: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.