Annotation of coherent/a/usr/bob/korn/tree.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * command tree climbing
                      3:  */
                      4: 
                      5: static char *RCSid = "$Header: /newbits/usr/bin/korn/RCS/tree.c,v 1.2 91/08/01 12:41:25 bin Exp Locker: bin $";
                      6: 
                      7: #include <stddef.h>
                      8: #include <stdlib.h>
                      9: #include <string.h>
                     10: #include <stdio.h>
                     11: #include <errno.h>
                     12: #include <setjmp.h>
                     13: #include <varargs.h>
                     14: #include "sh.h"
                     15: #include "tree.h"
                     16: 
                     17: #define        FSTRING (FILE*)NULL
                     18: 
                     19: static int     tputc ARGS((int c, FILE *f));
                     20: static void    tputC ARGS((int c, FILE *f));
                     21: static void    tputS ARGS((char *wp, FILE *f));
                     22: 
                     23: /*
                     24:  * print a command tree
                     25:  */
                     26: 
                     27: void
                     28: ptree(t, f)
                     29:        register struct op *t;
                     30:        register FILE *f;
                     31: {
                     32:        register char **w;
                     33:        struct ioword **ioact;
                     34:        struct op *t1;
                     35: 
                     36:  Chain:
                     37:        if (t == NULL)
                     38:                return;
                     39:        switch (t->type) {
                     40:          case TCOM:
                     41:                for (w = t->vars; *w != NULL; )
                     42:                        fptreef(f, "%S ", *w++);
                     43:                for (w = t->args; *w != NULL; )
                     44:                        fptreef(f, "%S ", *w++);
                     45:                break;
                     46:          case TEXEC:
                     47:                t = t->left;
                     48:                goto Chain;
                     49:          case TPAREN:
                     50:                fptreef(f, "(%T)", t->left);
                     51:                break;
                     52:          case TPIPE:
                     53:                fptreef(f, "%T | ", t->left);
                     54:                t = t->right;
                     55:                goto Chain;
                     56:          case TLIST:
                     57:                fptreef(f, "%T%;", t->left);
                     58:                t = t->right;
                     59:                goto Chain;
                     60:          case TOR:
                     61:          case TAND:
                     62:                fptreef(f, "%T %s %T",
                     63:                        t->left, (t->type==TOR) ? "||" : "&&", t->right);
                     64:                break;
                     65:          case TFOR:
                     66:                fptreef(f, "for %s ", t->str);
                     67:                if (t->vars != NULL) {
                     68:                        fptreef(f, "in ");
                     69:                        for (w = t->vars; *w; )
                     70:                                fptreef(f, "%S ", *w++);
                     71:                        fptreef(f, "%;");
                     72:                }
                     73:                fptreef(f, "do %T%;done ", t->left);
                     74:                break;
                     75:          case TCASE:
                     76:                fptreef(f, "case %S in%;", t->str);
                     77:                for (t1 = t->left; t1 != NULL; t1 = t1->right) {
                     78:                        fptreef(f, "(");
                     79:                        for (w = t1->vars; *w != NULL; w++)
                     80:                                fptreef(f, "%S%c", *w, (w[1] != NULL) ? '|' : ')');
                     81:                        fptreef(f, " %T;;%;", t1->left);
                     82:                }
                     83:                fptreef(f, "esac ");
                     84:                break;
                     85:          case TIF:
                     86:                fptreef(f, "if %T%;", t->left);
                     87:                t = t->right;
                     88:                if (t->left != NULL)
                     89:                        fptreef(f, "then %T%;", t->left);
                     90:                if (t->right != NULL)
                     91:                        fptreef(f, "else %T%;", t->right);
                     92:                fptreef(f, "fi ");
                     93:                break;
                     94:          case TWHILE:
                     95:          case TUNTIL:
                     96:                fptreef(f, "%s %T%;do %T%;done ",
                     97:                        (t->type==TWHILE) ? "while" : "until",
                     98:                        t->left, t->right);
                     99:                break;
                    100:          case TBRACE:
                    101:                fptreef(f, "{%;%T%;} ", t->left);
                    102:                break;
                    103:          case TASYNC:
                    104:                fptreef(f, "%T &", t->left);
                    105:                break;
                    106:          case TFUNCT:
                    107:                fptreef(f, "function %s %T", t->str, t->left);
                    108:                break;
                    109:          case TTIME:
                    110:                fptreef(f, "time %T", t->left);
                    111:                break;
                    112:          default:
                    113:                fptreef(f, "<botch>");
                    114:                break;
                    115:        }
                    116:        if ((ioact = t->ioact) != NULL)
                    117:                while (*ioact != NULL)
                    118:                        pioact(f, *ioact++);
                    119: }
                    120: 
                    121: /*
                    122:  * print out a redirection node.
                    123:  */
                    124: pioact(f, iop)
                    125:        register FILE *f;
                    126:        register struct ioword *iop;
                    127: {
                    128:        char    *redir = NULL;
                    129: 
                    130:        switch (iop->flag & (IOREAD|IOHERE|IOWRITE|IOCAT|IOXHERE|IODUP)) {
                    131:        case IOREAD:            redir = "<";    break;
                    132:        case IOREAD|IOHERE:     redir = "<<";   break;
                    133:        case IOREAD|IODUP:      redir = "<&";   break;
                    134:        case IOWRITE:           redir = ">";    break;
                    135:        case IOWRITE|IOCAT:     redir = ">>";   break;
                    136:        case IOWRITE|IODUP:     redir = ">&";   break;
                    137:        case IOXHERE:           redir = "<<";   break;
                    138:        default:                redir = ">?<";  break;
                    139:        }
                    140:        fptreef(f, "%c%s%S ", '0' + iop->unit, redir, iop->name);
                    141: }
                    142: 
                    143: 
                    144: /*
                    145:  * variants of fputc, fputs for ptreef and snptreef
                    146:  */
                    147: 
                    148: static char   *snpf_s;         /* snptreef string */
                    149: static int     snpf_n;         /* snptreef length */
                    150: 
                    151: static int
                    152: tputc(c, f)
                    153:        int c;
                    154:        register FILE *f;
                    155: {
                    156:        if (f != NULL)
                    157:                putc(c, f);
                    158:        else
                    159:                if (--snpf_n >= 0)
                    160:                        *snpf_s++ = c;
                    161:        return c;
                    162: }
                    163: 
                    164: static void
                    165: tputC(c, f)
                    166:        register int c;
                    167:        register FILE *f;
                    168: {
                    169:        if ((c&0x60) == 0) {            /* C0|C1 */
                    170:                tputc((c&0x80) ? '$' : '^', f);
                    171:                tputc((c&0x7F|0x40), f);
                    172:        } else if ((c&0x7F) == 0x7F) {  /* DEL */
                    173:                tputc((c&0x80) ? '$' : '^', f);
                    174:                tputc('?', f);
                    175:        } else
                    176:                tputc(c, f);
                    177: }
                    178: 
                    179: static void
                    180: tputS(wp, f)
                    181:        register char *wp;
                    182:        register FILE *f;
                    183: {
                    184:        register int c;
                    185: 
                    186:        while (1)
                    187:                switch ((c = *wp++)) {
                    188:                  case EOS:
                    189:                        return;
                    190:                  case CHAR:
                    191:                        tputC(*wp++, f);
                    192:                        break;
                    193:                  case QCHAR:
                    194:                        tputc('\\', f);
                    195:                        tputC(*wp++, f);
                    196:                        break;
                    197:                  case OQUOTE:
                    198:                  case CQUOTE:
                    199:                        tputc('"', f);
                    200:                        break;
                    201:                  case OSUBST:
                    202:                        tputc('$', f);
                    203:                        tputc('{', f);
                    204:                        while ((c = *wp++) != 0)
                    205:                                tputc(c, f);
                    206:                        if (*wp != CSUBST)
                    207:                                tputC(*wp++, f);
                    208:                        break;
                    209:                  case CSUBST:
                    210:                        tputc('}', f);
                    211:                        break;
                    212:                  case COMSUB:
                    213:                        tputc('$', f);
                    214:                        tputc('(', f);
                    215:                        while (*wp != 0)
                    216:                                tputC(*wp++, f);
                    217:                        tputc(')', f);
                    218:                        break;
                    219:                }
                    220: }
                    221: 
                    222: /* TODO: use varargs properly */
                    223: 
                    224: /* VARARGS */ int
                    225: fptreef(f, va_alist) va_dcl
                    226:        register FILE *f;
                    227: {
                    228:        va_list va;
                    229:        char *fmt;
                    230: 
                    231:        va_start(va);
                    232:        fmt = va_arg(va, char *);
                    233:        vfptreef(f, fmt, va);
                    234:        va_end(va);
                    235:        return 0;
                    236: }
                    237: 
                    238: /* VARARGS */ int
                    239: snptreef(s, n, va_alist) va_dcl
                    240:        char *s;
                    241:        int n;
                    242: {
                    243:        va_list va;
                    244:        char *fmt;
                    245: 
                    246:        snpf_s = s;
                    247:        snpf_n = n;
                    248:        va_start(va);
                    249:        fmt = va_arg(va, char *);
                    250:        vfptreef(FSTRING, fmt, va);
                    251:        tputc('\0', FSTRING);
                    252:        va_end(va);
                    253:        return 0;
                    254: }
                    255: 
                    256: vfptreef(f, fmt, va)
                    257:        register FILE *f;
                    258:        register char *fmt;
                    259:        register va_list va;
                    260: {
                    261:        register int c;
                    262: 
                    263:        while ((c = *fmt++))
                    264:            if (c == '%') {
                    265:                register long n;
                    266:                register char *p;
                    267:                int neg;
                    268: 
                    269:                switch ((c = *fmt++)) {
                    270:                  case 'c':
                    271:                        tputc(va_arg(va, int), f);
                    272:                        break;
                    273:                  case 's':
                    274:                        p = va_arg(va, char *);
                    275:                        while (*p)
                    276:                                tputc(*p++, f);
                    277:                        break;
                    278:                  case 'S':     /* word */
                    279:                        p = va_arg(va, char *);
                    280:                        tputS(p, f);
                    281:                        break;
                    282:                  case 'd': case 'u': /* decimal */
                    283:                        n = (c == 'd') ? va_arg(va, int) : va_arg(va, unsigned int);
                    284:                        neg = c=='d' && n<0;
                    285:                        p = ulton((neg) ? -n : n, 10);
                    286:                        if (neg)
                    287:                                *--p = '-';
                    288:                        while (*p)
                    289:                                tputc(*p++, f);
                    290:                        break;
                    291:                  case 'T':     /* format tree */
                    292:                        ptree(va_arg(va, struct op *), f);
                    293:                        break;
                    294:                  case ';':     /* newline or ; */
                    295:                        p = (f == FSTRING) ? "; " : "\n";
                    296:                        while (*p)
                    297:                                tputc(*p++, f);
                    298:                        break;
                    299:                  default:
                    300:                        tputc(c, f);
                    301:                        break;
                    302:                }
                    303:            } else
                    304:                tputc(c, f);
                    305: }
                    306: 
                    307: /*
                    308:  * copy tree (for function definition)
                    309:  */
                    310: 
                    311: static struct ioword **iocopy();
                    312: 
                    313: struct op *
                    314: tcopy(t, ap)
                    315:        register struct op *t;
                    316:        Area *ap;
                    317: {
                    318:        register struct op *r;
                    319:        register char **tw, **rw;
                    320: 
                    321:        if (t == NULL)
                    322:                return NULL;
                    323: 
                    324:        r = (struct op *) alloc(sizeof(struct op), ap);
                    325: 
                    326:        r->type = t->type;
                    327: 
                    328:        /* this will copy function and for identifiers quite accidently */
                    329:        r->str = (t->str == NULL) ? NULL : wdcopy(t->str, ap);
                    330: 
                    331:        if (t->vars == NULL)
                    332:                r->vars = NULL;
                    333:        else {
                    334:                for (tw = t->vars; *tw++ != NULL; )
                    335:                        ;
                    336:                rw = r->vars = (char **)
                    337:                        alloc((int)(tw - t->vars) * sizeof(*tw), ap);
                    338:                for (tw = t->vars; *tw != NULL; )
                    339:                        *rw++ = wdcopy(*tw++, ap);
                    340:                *rw = NULL;
                    341:        }
                    342: 
                    343:        if (t->args == NULL)
                    344:                r->args = NULL;
                    345:        else {
                    346:                for (tw = t->args; *tw++ != NULL; )
                    347:                        ;
                    348:                rw = r->args = (char **)
                    349:                        alloc((int)(tw - t->args) * sizeof(*tw), ap);
                    350:                for (tw = t->args; *tw != NULL; )
                    351:                        *rw++ = wdcopy(*tw++, ap);
                    352:                *rw = NULL;
                    353:        }
                    354: 
                    355:        r->ioact = (t->ioact == NULL) ? NULL : iocopy(t->ioact, ap);
                    356: 
                    357:        r->left = tcopy(t->left, ap);
                    358:        r->right = tcopy(t->right, ap);
                    359: 
                    360:        return r;
                    361: }
                    362: 
                    363: char *
                    364: wdcopy(wp, ap)
                    365:        char *wp;
                    366:        Area *ap;
                    367: {
                    368:        size_t len = wdscan(wp, EOS) - wp;
                    369:        return memcpy(alloc(len, ap), wp, len);
                    370: }
                    371: 
                    372: /* return the position of prefix c in wp plus 1 */
                    373: char *
                    374: wdscan(wp, c)
                    375:        register char *wp;
                    376:        register int c;
                    377: {
                    378:        register int nest = 0;
                    379: 
                    380:        while (1)
                    381:                switch (*wp++) {
                    382:                  case EOS:
                    383:                        return wp;
                    384:                  case CHAR:
                    385:                  case QCHAR:
                    386:                        wp++;
                    387:                        break;
                    388:                  case OQUOTE:
                    389:                  case CQUOTE:
                    390:                        break;
                    391:                  case OSUBST:
                    392:                        nest++;
                    393:                        while (*wp++ != 0)
                    394:                                ;
                    395:                        if (*wp != CSUBST)
                    396:                                wp++;
                    397:                        break;
                    398:                  case CSUBST:
                    399:                        if (c == CSUBST && nest == 0)
                    400:                                return wp;
                    401:                        nest--;
                    402:                        break;
                    403:                  case COMSUB:
                    404:                        while (*wp++ != 0)
                    405:                                ;
                    406:                        break;
                    407:                }
                    408: }
                    409: 
                    410: static struct ioword **
                    411: iocopy(iow, ap)
                    412:        register struct ioword **iow;
                    413:        Area *ap;
                    414: {
                    415:        register struct ioword **ior;
                    416:        register int i;
                    417: 
                    418:        for (ior = iow; *ior++ != NULL; )
                    419:                ;
                    420:        ior = (struct ioword **) alloc((int)(ior - iow) * sizeof(*ior), ap);
                    421: 
                    422:        for (i = 0; iow[i] != NULL; i++) {
                    423:                register struct ioword *p, *q;
                    424: 
                    425:                p = iow[i];
                    426:                q = (struct ioword *) alloc(sizeof(*p), ap);
                    427:                ior[i] = q;
                    428:                *q = *p;
                    429:                if (p->name != NULL)
                    430:                        q->name = wdcopy(p->name, ap);
                    431:        }
                    432:        ior[i] = NULL;
                    433: 
                    434:        return ior;
                    435: }
                    436: 
                    437: /*
                    438:  * free tree (for function definition)
                    439:  */
                    440: 
                    441: static void iofree();
                    442: 
                    443: void
                    444: tfree(t, ap)
                    445:        register struct op *t;
                    446:        Area *ap;
                    447: {
                    448:        register char **w;
                    449: 
                    450:        if (t == NULL)
                    451:                return;
                    452: 
                    453:        if (t->str != NULL)
                    454:                afree((Void*)t->str, ap);
                    455: 
                    456:        if (t->vars != NULL) {
                    457:                for (w = t->vars; *w != NULL; w++)
                    458:                        afree((Void*)*w, ap);
                    459:                afree((Void*)t->vars, ap);
                    460:        }
                    461: 
                    462:        if (t->args != NULL) {
                    463:                for (w = t->args; *w != NULL; w++)
                    464:                        afree((Void*)*w, ap);
                    465:                afree((Void*)t->args, ap);
                    466:        }
                    467: 
                    468:        if (t->ioact != NULL)
                    469:                iofree(t->ioact, ap);
                    470: 
                    471:        tfree(t->left, ap);
                    472:        tfree(t->right, ap);
                    473: 
                    474:        afree((Void*)t, ap);
                    475: }
                    476: 
                    477: static void
                    478: iofree(iow, ap)
                    479:        struct ioword **iow;
                    480:        Area *ap;
                    481: {
                    482:        register struct ioword **iop;
                    483:        register struct ioword *p;
                    484: 
                    485:        for (iop = iow; (p = *iop++) != NULL; ) {
                    486:                if (p->name != NULL)
                    487:                        afree((Void*)p->name, ap);
                    488:                afree((Void*)p, ap);
                    489:        }
                    490: }
                    491: 

unix.superglobalmegacorp.com

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