Annotation of 43BSDReno/bin/adb/common_source/format.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.