Annotation of 43BSD/bin/csh/sh.exp.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1980 Regents of the University of California.
                      3:  * All rights reserved.  The Berkeley Software License Agreement
                      4:  * specifies the terms and conditions for redistribution.
                      5:  */
                      6: 
                      7: #ifndef lint
                      8: static char *sccsid = "@(#)sh.exp.c    5.3 (Berkeley) 6/23/85";
                      9: #endif
                     10: 
                     11: #include "sh.h"
                     12: 
                     13: /*
                     14:  * C shell
                     15:  */
                     16: 
                     17: #define IGNORE 1       /* in ignore, it means to ignore value, just parse */
                     18: #define NOGLOB 2       /* in ignore, it means not to globone */
                     19: 
                     20: #define        ADDOP   1
                     21: #define        MULOP   2
                     22: #define        EQOP    4
                     23: #define        RELOP   8
                     24: #define        RESTOP  16
                     25: #define        ANYOP   31
                     26: 
                     27: #define        EQEQ    1
                     28: #define        GTR     2
                     29: #define        LSS     4
                     30: #define        NOTEQ   6
                     31: #define EQMATCH 7
                     32: #define NOTEQMATCH 8
                     33: 
                     34: exp(vp)
                     35:        register char ***vp;
                     36: {
                     37: 
                     38:        return (exp0(vp, 0));
                     39: }
                     40: 
                     41: exp0(vp, ignore)
                     42:        register char ***vp;
                     43:        bool ignore;
                     44: {
                     45:        register int p1 = exp1(vp, ignore);
                     46:        
                     47: #ifdef EDEBUG
                     48:        etraci("exp0 p1", p1, vp);
                     49: #endif
                     50:        if (**vp && eq(**vp, "||")) {
                     51:                register int p2;
                     52: 
                     53:                (*vp)++;
                     54:                p2 = exp0(vp, (ignore&IGNORE) || p1);
                     55: #ifdef EDEBUG
                     56:                etraci("exp0 p2", p2, vp);
                     57: #endif
                     58:                return (p1 || p2);
                     59:        }
                     60:        return (p1);
                     61: }
                     62: 
                     63: exp1(vp, ignore)
                     64:        register char ***vp;
                     65: {
                     66:        register int p1 = exp2(vp, ignore);
                     67: 
                     68: #ifdef EDEBUG
                     69:        etraci("exp1 p1", p1, vp);
                     70: #endif
                     71:        if (**vp && eq(**vp, "&&")) {
                     72:                register int p2;
                     73: 
                     74:                (*vp)++;
                     75:                p2 = exp1(vp, (ignore&IGNORE) || !p1);
                     76: #ifdef EDEBUG
                     77:                etraci("exp1 p2", p2, vp);
                     78: #endif
                     79:                return (p1 && p2);
                     80:        }
                     81:        return (p1);
                     82: }
                     83: 
                     84: exp2(vp, ignore)
                     85:        register char ***vp;
                     86:        bool ignore;
                     87: {
                     88:        register int p1 = exp2a(vp, ignore);
                     89: 
                     90: #ifdef EDEBUG
                     91:        etraci("exp3 p1", p1, vp);
                     92: #endif
                     93:        if (**vp && eq(**vp, "|")) {
                     94:                register int p2;
                     95: 
                     96:                (*vp)++;
                     97:                p2 = exp2(vp, ignore);
                     98: #ifdef EDEBUG
                     99:                etraci("exp3 p2", p2, vp);
                    100: #endif
                    101:                return (p1 | p2);
                    102:        }
                    103:        return (p1);
                    104: }
                    105: 
                    106: exp2a(vp, ignore)
                    107:        register char ***vp;
                    108:        bool ignore;
                    109: {
                    110:        register int p1 = exp2b(vp, ignore);
                    111: 
                    112: #ifdef EDEBUG
                    113:        etraci("exp2a p1", p1, vp);
                    114: #endif
                    115:        if (**vp && eq(**vp, "^")) {
                    116:                register int p2;
                    117: 
                    118:                (*vp)++;
                    119:                p2 = exp2a(vp, ignore);
                    120: #ifdef EDEBUG
                    121:                etraci("exp2a p2", p2, vp);
                    122: #endif
                    123:                return (p1 ^ p2);
                    124:        }
                    125:        return (p1);
                    126: }
                    127: 
                    128: exp2b(vp, ignore)
                    129:        register char ***vp;
                    130:        bool ignore;
                    131: {
                    132:        register int p1 = exp2c(vp, ignore);
                    133: 
                    134: #ifdef EDEBUG
                    135:        etraci("exp2b p1", p1, vp);
                    136: #endif
                    137:        if (**vp && eq(**vp, "&")) {
                    138:                register int p2;
                    139: 
                    140:                (*vp)++;
                    141:                p2 = exp2b(vp, ignore);
                    142: #ifdef EDEBUG
                    143:                etraci("exp2b p2", p2, vp);
                    144: #endif
                    145:                return (p1 & p2);
                    146:        }
                    147:        return (p1);
                    148: }
                    149: 
                    150: exp2c(vp, ignore)
                    151:        register char ***vp;
                    152:        bool ignore;
                    153: {
                    154:        register char *p1 = exp3(vp, ignore);
                    155:        register char *p2;
                    156:        register int i;
                    157: 
                    158: #ifdef EDEBUG
                    159:        etracc("exp2c p1", p1, vp);
                    160: #endif
                    161:        if (i = isa(**vp, EQOP)) {
                    162:                (*vp)++;
                    163:                if (i == EQMATCH || i == NOTEQMATCH)
                    164:                        ignore |= NOGLOB;
                    165:                p2 = exp3(vp, ignore);
                    166: #ifdef EDEBUG
                    167:                etracc("exp2c p2", p2, vp);
                    168: #endif
                    169:                if (!(ignore&IGNORE)) switch (i) {
                    170: 
                    171:                case EQEQ:
                    172:                        i = eq(p1, p2);
                    173:                        break;
                    174: 
                    175:                case NOTEQ:
                    176:                        i = !eq(p1, p2);
                    177:                        break;
                    178: 
                    179:                case EQMATCH:
                    180:                        i = Gmatch(p1, p2);
                    181:                        break;
                    182: 
                    183:                case NOTEQMATCH:
                    184:                        i = !Gmatch(p1, p2);
                    185:                        break;
                    186:                }
                    187:                xfree(p1), xfree(p2);
                    188:                return (i);
                    189:        }
                    190:        i = egetn(p1);
                    191:        xfree(p1);
                    192:        return (i);
                    193: }
                    194: 
                    195: char *
                    196: exp3(vp, ignore)
                    197:        register char ***vp;
                    198:        bool ignore;
                    199: {
                    200:        register char *p1, *p2;
                    201:        register int i;
                    202: 
                    203:        p1 = exp3a(vp, ignore);
                    204: #ifdef EDEBUG
                    205:        etracc("exp3 p1", p1, vp);
                    206: #endif
                    207:        if (i = isa(**vp, RELOP)) {
                    208:                (*vp)++;
                    209:                if (**vp && eq(**vp, "="))
                    210:                        i |= 1, (*vp)++;
                    211:                p2 = exp3(vp, ignore);
                    212: #ifdef EDEBUG
                    213:                etracc("exp3 p2", p2, vp);
                    214: #endif
                    215:                if (!(ignore&IGNORE)) switch (i) {
                    216: 
                    217:                case GTR:
                    218:                        i = egetn(p1) > egetn(p2);
                    219:                        break;
                    220: 
                    221:                case GTR|1:
                    222:                        i = egetn(p1) >= egetn(p2);
                    223:                        break;
                    224: 
                    225:                case LSS:
                    226:                        i = egetn(p1) < egetn(p2);
                    227:                        break;
                    228: 
                    229:                case LSS|1:
                    230:                        i = egetn(p1) <= egetn(p2);
                    231:                        break;
                    232:                }
                    233:                xfree(p1), xfree(p2);
                    234:                return (putn(i));
                    235:        }
                    236:        return (p1);
                    237: }
                    238: 
                    239: char *
                    240: exp3a(vp, ignore)
                    241:        register char ***vp;
                    242:        bool ignore;
                    243: {
                    244:        register char *p1, *p2, *op;
                    245:        register int i;
                    246: 
                    247:        p1 = exp4(vp, ignore);
                    248: #ifdef EDEBUG
                    249:        etracc("exp3a p1", p1, vp);
                    250: #endif
                    251:        op = **vp;
                    252:        if (op && any(op[0], "<>") && op[0] == op[1]) {
                    253:                (*vp)++;
                    254:                p2 = exp3a(vp, ignore);
                    255: #ifdef EDEBUG
                    256:                etracc("exp3a p2", p2, vp);
                    257: #endif
                    258:                if (op[0] == '<')
                    259:                        i = egetn(p1) << egetn(p2);
                    260:                else
                    261:                        i = egetn(p1) >> egetn(p2);
                    262:                xfree(p1), xfree(p2);
                    263:                return (putn(i));
                    264:        }
                    265:        return (p1);
                    266: }
                    267: 
                    268: char *
                    269: exp4(vp, ignore)
                    270:        register char ***vp;
                    271:        bool ignore;
                    272: {
                    273:        register char *p1, *p2;
                    274:        register int i = 0;
                    275: 
                    276:        p1 = exp5(vp, ignore);
                    277: #ifdef EDEBUG
                    278:        etracc("exp4 p1", p1, vp);
                    279: #endif
                    280:        if (isa(**vp, ADDOP)) {
                    281:                register char *op = *(*vp)++;
                    282: 
                    283:                p2 = exp4(vp, ignore);
                    284: #ifdef EDEBUG
                    285:                etracc("exp4 p2", p2, vp);
                    286: #endif
                    287:                if (!(ignore&IGNORE)) switch (op[0]) {
                    288: 
                    289:                case '+':
                    290:                        i = egetn(p1) + egetn(p2);
                    291:                        break;
                    292: 
                    293:                case '-':
                    294:                        i = egetn(p1) - egetn(p2);
                    295:                        break;
                    296:                }
                    297:                xfree(p1), xfree(p2);
                    298:                return (putn(i));
                    299:        }
                    300:        return (p1);
                    301: }
                    302: 
                    303: char *
                    304: exp5(vp, ignore)
                    305:        register char ***vp;
                    306:        bool ignore;
                    307: {
                    308:        register char *p1, *p2;
                    309:        register int i = 0;
                    310: 
                    311:        p1 = exp6(vp, ignore);
                    312: #ifdef EDEBUG
                    313:        etracc("exp5 p1", p1, vp);
                    314: #endif
                    315:        if (isa(**vp, MULOP)) {
                    316:                register char *op = *(*vp)++;
                    317: 
                    318:                p2 = exp5(vp, ignore);
                    319: #ifdef EDEBUG
                    320:                etracc("exp5 p2", p2, vp);
                    321: #endif
                    322:                if (!(ignore&IGNORE)) switch (op[0]) {
                    323: 
                    324:                case '*':
                    325:                        i = egetn(p1) * egetn(p2);
                    326:                        break;
                    327: 
                    328:                case '/':
                    329:                        i = egetn(p2);
                    330:                        if (i == 0)
                    331:                                error("Divide by 0");
                    332:                        i = egetn(p1) / i;
                    333:                        break;
                    334: 
                    335:                case '%':
                    336:                        i = egetn(p2);
                    337:                        if (i == 0)
                    338:                                error("Mod by 0");
                    339:                        i = egetn(p1) % i;
                    340:                        break;
                    341:                }
                    342:                xfree(p1), xfree(p2);
                    343:                return (putn(i));
                    344:        }
                    345:        return (p1);
                    346: }
                    347: 
                    348: char *
                    349: exp6(vp, ignore)
                    350:        register char ***vp;
                    351: {
                    352:        int ccode, i;
                    353:        register char *cp, *dp, *ep;
                    354: 
                    355:        if (**vp == 0)
                    356:                bferr("Expression syntax");
                    357:        if (eq(**vp, "!")) {
                    358:                (*vp)++;
                    359:                cp = exp6(vp, ignore);
                    360: #ifdef EDEBUG
                    361:                etracc("exp6 ! cp", cp, vp);
                    362: #endif
                    363:                i = egetn(cp);
                    364:                xfree(cp);
                    365:                return (putn(!i));
                    366:        }
                    367:        if (eq(**vp, "~")) {
                    368:                (*vp)++;
                    369:                cp = exp6(vp, ignore);
                    370: #ifdef EDEBUG
                    371:                etracc("exp6 ~ cp", cp, vp);
                    372: #endif
                    373:                i = egetn(cp);
                    374:                xfree(cp);
                    375:                return (putn(~i));
                    376:        }
                    377:        if (eq(**vp, "(")) {
                    378:                (*vp)++;
                    379:                ccode = exp0(vp, ignore);
                    380: #ifdef EDEBUG
                    381:                etraci("exp6 () ccode", ccode, vp);
                    382: #endif
                    383:                if (*vp == 0 || **vp == 0 || ***vp != ')')
                    384:                        bferr("Expression syntax");
                    385:                (*vp)++;
                    386:                return (putn(ccode));
                    387:        }
                    388:        if (eq(**vp, "{")) {
                    389:                register char **v;
                    390:                struct command faket;
                    391:                char *fakecom[2];
                    392: 
                    393:                faket.t_dtyp = TCOM;
                    394:                faket.t_dflg = 0;
                    395:                faket.t_dcar = faket.t_dcdr = faket.t_dspr = (struct command *)0;
                    396:                faket.t_dcom = fakecom;
                    397:                fakecom[0] = "{ ... }";
                    398:                fakecom[1] = NOSTR;
                    399:                (*vp)++;
                    400:                v = *vp;
                    401:                for (;;) {
                    402:                        if (!**vp)
                    403:                                bferr("Missing }");
                    404:                        if (eq(*(*vp)++, "}"))
                    405:                                break;
                    406:                }
                    407:                if (ignore&IGNORE)
                    408:                        return ("");
                    409:                psavejob();
                    410:                if (pfork(&faket, -1) == 0) {
                    411:                        *--(*vp) = 0;
                    412:                        evalav(v);
                    413:                        exitstat();
                    414:                }
                    415:                pwait();
                    416:                prestjob();
                    417: #ifdef EDEBUG
                    418:                etraci("exp6 {} status", egetn(value("status")), vp);
                    419: #endif
                    420:                return (putn(egetn(value("status")) == 0));
                    421:        }
                    422:        if (isa(**vp, ANYOP))
                    423:                return ("");
                    424:        cp = *(*vp)++;
                    425:        if (*cp == '-' && any(cp[1], "erwxfdzo")) {
                    426:                struct stat stb;
                    427: 
                    428:                if (isa(**vp, ANYOP))
                    429:                        bferr("Missing file name");
                    430:                dp = *(*vp)++;
                    431:                if (ignore&IGNORE)
                    432:                        return ("");
                    433:                ep = globone(dp);
                    434:                switch (cp[1]) {
                    435: 
                    436:                case 'r':
                    437:                        i = !access(ep, 4);
                    438:                        break;
                    439: 
                    440:                case 'w':
                    441:                        i = !access(ep, 2);
                    442:                        break;
                    443: 
                    444:                case 'x':
                    445:                        i = !access(ep, 1);
                    446:                        break;
                    447: 
                    448:                default:
                    449:                        if (stat(ep, &stb)) {
                    450:                                xfree(ep);
                    451:                                return ("0");
                    452:                        }
                    453:                        switch (cp[1]) {
                    454: 
                    455:                        case 'f':
                    456:                                i = (stb.st_mode & S_IFMT) == S_IFREG;
                    457:                                break;
                    458: 
                    459:                        case 'd':
                    460:                                i = (stb.st_mode & S_IFMT) == S_IFDIR;
                    461:                                break;
                    462: 
                    463:                        case 'z':
                    464:                                i = stb.st_size == 0;
                    465:                                break;
                    466: 
                    467:                        case 'e':
                    468:                                i = 1;
                    469:                                break;
                    470: 
                    471:                        case 'o':
                    472:                                i = stb.st_uid == uid;
                    473:                                break;
                    474:                        }
                    475:                }
                    476: #ifdef EDEBUG
                    477:                etraci("exp6 -? i", i, vp);
                    478: #endif
                    479:                xfree(ep);
                    480:                return (putn(i));
                    481:        }
                    482: #ifdef EDEBUG
                    483:        etracc("exp6 default", cp, vp);
                    484: #endif
                    485:        return (ignore&NOGLOB ? savestr(cp) : globone(cp));
                    486: }
                    487: 
                    488: evalav(v)
                    489:        register char **v;
                    490: {
                    491:        struct wordent paraml;
                    492:        register struct wordent *hp = &paraml;
                    493:        struct command *t;
                    494:        register struct wordent *wdp = hp;
                    495:        
                    496:        set("status", "0");
                    497:        hp->prev = hp->next = hp;
                    498:        hp->word = "";
                    499:        while (*v) {
                    500:                register struct wordent *new = (struct wordent *) calloc(1, sizeof *wdp);
                    501: 
                    502:                new->prev = wdp;
                    503:                new->next = hp;
                    504:                wdp->next = new;
                    505:                wdp = new;
                    506:                wdp->word = savestr(*v++);
                    507:        }
                    508:        hp->prev = wdp;
                    509:        alias(&paraml);
                    510:        t = syntax(paraml.next, &paraml, 0);
                    511:        if (err)
                    512:                error(err);
                    513:        execute(t, -1);
                    514:        freelex(&paraml), freesyn(t);
                    515: }
                    516: 
                    517: isa(cp, what)
                    518:        register char *cp;
                    519:        register int what;
                    520: {
                    521: 
                    522:        if (cp == 0)
                    523:                return ((what & RESTOP) != 0);
                    524:        if (cp[1] == 0) {
                    525:                if (what & ADDOP && (*cp == '+' || *cp == '-'))
                    526:                        return (1);
                    527:                if (what & MULOP && (*cp == '*' || *cp == '/' || *cp == '%'))
                    528:                        return (1);
                    529:                if (what & RESTOP && (*cp == '(' || *cp == ')' || *cp == '!' ||
                    530:                                      *cp == '~' || *cp == '^' || *cp == '"'))
                    531:                        return (1);
                    532:        } else if (cp[2] == 0) {
                    533:                if (what & RESTOP) {
                    534:                        if (cp[0] == '|' && cp[1] == '&')
                    535:                                return (1);
                    536:                        if (cp[0] == '<' && cp[1] == '<')
                    537:                                return (1);
                    538:                        if (cp[0] == '>' && cp[1] == '>')
                    539:                                return (1);
                    540:                }
                    541:                if (what & EQOP) {
                    542:                        if (cp[0] == '=') {
                    543:                                if (cp[1] == '=')
                    544:                                        return (EQEQ);
                    545:                                if (cp[1] == '~')
                    546:                                        return (EQMATCH);
                    547:                        } else if (cp[0] == '!') {
                    548:                                if (cp[1] == '=')
                    549:                                        return (NOTEQ);
                    550:                                if (cp[1] == '~')
                    551:                                        return (NOTEQMATCH);
                    552:                        }
                    553:                }
                    554:        }
                    555:        if (what & RELOP) {
                    556:                if (*cp == '<')
                    557:                        return (LSS);
                    558:                if (*cp == '>')
                    559:                        return (GTR);
                    560:        }
                    561:        return (0);
                    562: }
                    563: 
                    564: egetn(cp)
                    565:        register char *cp;
                    566: {
                    567: 
                    568:        if (*cp && *cp != '-' && !digit(*cp))
                    569:                bferr("Expression syntax");
                    570:        return (getn(cp));
                    571: }
                    572: 
                    573: /* Phew! */
                    574: 
                    575: #ifdef EDEBUG
                    576: etraci(str, i, vp)
                    577:        char *str;
                    578:        int i;
                    579:        char ***vp;
                    580: {
                    581: 
                    582:        printf("%s=%d\t", str, i);
                    583:        blkpr(*vp);
                    584:        printf("\n");
                    585: }
                    586: 
                    587: etracc(str, cp, vp)
                    588:        char *str, *cp;
                    589:        char ***vp;
                    590: {
                    591: 
                    592:        printf("%s=%s\t", str, cp);
                    593:        blkpr(*vp);
                    594:        printf("\n");
                    595: }
                    596: #endif

unix.superglobalmegacorp.com

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