Annotation of lucent/sys/src/cmd/rc/code.c, revision 1.1.1.1

1.1       root        1: #include "rc.h"
                      2: #include "io.h"
                      3: #include "exec.h"
                      4: #include "fns.h"
                      5: #include "getflags.h"
                      6: #define        c0      t->child[0]
                      7: #define        c1      t->child[1]
                      8: #define        c2      t->child[2]
                      9: int codep, ncode;
                     10: #define        emitf(x) ((codep!=ncode || morecode()), codebuf[codep].f=(x), codep++)
                     11: #define        emiti(x) ((codep!=ncode || morecode()), codebuf[codep].i=(x), codep++)
                     12: #define        emits(x) ((codep!=ncode || morecode()), codebuf[codep].s=(x), codep++)
                     13: void stuffdot(int);
                     14: char *fnstr(tree*);
                     15: void outcode(tree*, int);
                     16: void codeswitch(tree*, int);
                     17: int iscase(tree*);
                     18: code *codecopy(code*);
                     19: void codefree(code*);
                     20: int morecode(void){
                     21:        ncode+=100;
                     22:        codebuf=(code *)realloc((char *)codebuf, ncode*sizeof codebuf[0]);
                     23:        if(codebuf==0) panic("Can't realloc %d bytes in morecode!",
                     24:                                ncode*sizeof codebuf[0]);
                     25: }
                     26: void stuffdot(int a){
                     27:        if(a<0 || codep<=a) panic("Bad address %d in stuffdot", a);
                     28:        codebuf[a].i=codep;
                     29: }
                     30: int compile(tree *t)
                     31: {
                     32:        ncode=100;
                     33:        codebuf=(code *)emalloc(ncode*sizeof codebuf[0]);
                     34:        codep=0;
                     35:        emiti(0);                       /* reference count */
                     36:        outcode(t, flag['e']?1:0);
                     37:        if(nerror){
                     38:                efree((char *)codebuf);
                     39:                return 0;
                     40:        }
                     41:        readhere();
                     42:        emitf(Xreturn);
                     43:        emitf(0);
                     44:        return 1;
                     45: }
                     46: void cleanhere(char *f)
                     47: {
                     48:        emitf(Xdelhere);
                     49:        emits(strdup(f));
                     50: }
                     51: char *fnstr(tree *t)
                     52: {
                     53:        io *f=openstr();
                     54:        char *v;
                     55:        extern char nl;
                     56:        char svnl=nl;
                     57:        nl=';';
                     58:        pfmt(f, "%t", t);
                     59:        nl=svnl;
                     60:        v=f->strp;
                     61:        f->strp=0;
                     62:        closeio(f);
                     63:        return v;
                     64: }
                     65: void outcode(tree *t, int eflag)
                     66: {
                     67:        int p, q;
                     68:        tree *tt;
                     69:        if(t==0) return;
                     70:        if(t->type!=NOT && t->type!=';') runq->iflast=0;
                     71:        switch(t->type){
                     72:        default:
                     73:                pfmt(err, "bad type %d in outcode\n", t->type);
                     74:                break;
                     75:        case '$':
                     76:                emitf(Xmark);
                     77:                outcode(c0, eflag);
                     78:                emitf(Xdol);
                     79:                break;
                     80:        case '"':
                     81:                emitf(Xmark);
                     82:                outcode(c0, eflag);
                     83:                emitf(Xqdol);
                     84:                break;
                     85:        case SUB:
                     86:                emitf(Xmark);
                     87:                outcode(c0, eflag);
                     88:                emitf(Xmark);
                     89:                outcode(c1, eflag);
                     90:                emitf(Xsub);
                     91:                break;
                     92:        case '&':
                     93:                emitf(Xasync);
                     94:                p=emiti(0);
                     95:                outcode(c0, eflag);
                     96:                emitf(Xexit);
                     97:                stuffdot(p);
                     98:                break;
                     99:        case ';':
                    100:                outcode(c0, eflag);
                    101:                outcode(c1, eflag);
                    102:                break;
                    103:        case '^':
                    104:                emitf(Xmark);
                    105:                outcode(c1, eflag);
                    106:                emitf(Xmark);
                    107:                outcode(c0, eflag);
                    108:                emitf(Xconc);
                    109:                break;
                    110:        case '`':
                    111:                emitf(Xbackq);
                    112:                p=emiti(0);
                    113:                outcode(c0, 0);
                    114:                emitf(Xexit);
                    115:                stuffdot(p);
                    116:                break;
                    117:        case ANDAND:
                    118:                outcode(c0, 0);
                    119:                emitf(Xtrue);
                    120:                p=emiti(0);
                    121:                outcode(c1, eflag);
                    122:                stuffdot(p);
                    123:                break;
                    124:        case ARGLIST:
                    125:                outcode(c1, eflag);
                    126:                outcode(c0, eflag);
                    127:                break;
                    128:        case BANG:
                    129:                outcode(c0, eflag);
                    130:                emitf(Xbang);
                    131:                break;
                    132:        case PCMD:
                    133:        case BRACE:
                    134:                outcode(c0, eflag);
                    135:                break;
                    136:        case COUNT:
                    137:                emitf(Xmark);
                    138:                outcode(c0, eflag);
                    139:                emitf(Xcount);
                    140:                break;
                    141:        case FN:
                    142:                emitf(Xmark);
                    143:                outcode(c0, eflag);
                    144:                if(c1){
                    145:                        emitf(Xfn);
                    146:                        p=emiti(0);
                    147:                        emits(fnstr(c1));
                    148:                        outcode(c1, eflag);
                    149:                        emitf(Xunlocal);        /* get rid of $* */
                    150:                        emitf(Xreturn);
                    151:                        stuffdot(p);
                    152:                }
                    153:                else
                    154:                        emitf(Xdelfn);
                    155:                break;
                    156:        case IF:
                    157:                outcode(c0, 0);
                    158:                emitf(Xif);
                    159:                p=emiti(0);
                    160:                outcode(c1, eflag);
                    161:                emitf(Xwastrue);
                    162:                stuffdot(p);
                    163:                break;
                    164:        case NOT:
                    165:                if(!runq->iflast) yyerror("`if not' does not follow `if(...)'");
                    166:                emitf(Xifnot);
                    167:                p=emiti(0);
                    168:                outcode(c0, eflag);
                    169:                stuffdot(p);
                    170:                break;
                    171:        case OROR:
                    172:                outcode(c0, 0);
                    173:                emitf(Xfalse);
                    174:                p=emiti(0);
                    175:                outcode(c1, eflag);
                    176:                stuffdot(p);
                    177:                break;
                    178:        case PAREN:
                    179:                outcode(c0, eflag);
                    180:                break;
                    181:        case SIMPLE:
                    182:                emitf(Xmark);
                    183:                outcode(c0, eflag);
                    184:                emitf(Xsimple);
                    185:                if(eflag) emitf(Xeflag);
                    186:                break;
                    187:        case SUBSHELL:
                    188:                emitf(Xsubshell);
                    189:                p=emiti(0);
                    190:                outcode(c0, eflag);
                    191:                emitf(Xexit);
                    192:                stuffdot(p);
                    193:                break;
                    194:        case SWITCH:
                    195:                codeswitch(t, eflag);
                    196:                break;
                    197:        case TWIDDLE:
                    198:                emitf(Xmark);
                    199:                outcode(c1, eflag);
                    200:                emitf(Xmark);
                    201:                outcode(c0, eflag);
                    202:                emitf(Xmatch);
                    203:                if(eflag) emitf(Xeflag);
                    204:                break;
                    205:        case WHILE:
                    206:                q=codep;
                    207:                emitf(Xsettrue);
                    208:                outcode(c0, 0);
                    209:                emitf(Xtrue);
                    210:                p=emiti(0);
                    211:                outcode(c1, eflag);
                    212:                emitf(Xjump);
                    213:                emiti(q);
                    214:                stuffdot(p);
                    215:                break;
                    216:        case WORDS:
                    217:                outcode(c1, eflag);
                    218:                outcode(c0, eflag);
                    219:                break;
                    220:        case FOR:
                    221:                emitf(Xmark);
                    222:                if(c1){
                    223:                        outcode(c1, eflag);
                    224:                        emitf(Xglob);
                    225:                }
                    226:                else{
                    227:                        emitf(Xmark);
                    228:                        emitf(Xword);
                    229:                        emits(strdup("*"));
                    230:                        emitf(Xdol);
                    231:                }
                    232:                emitf(Xmark);           /* dummy value for Xlocal */
                    233:                emitf(Xmark);
                    234:                outcode(c0, eflag);
                    235:                emitf(Xlocal);
                    236:                p=emitf(Xfor);
                    237:                q=emiti(0);
                    238:                outcode(c2, eflag);
                    239:                emitf(Xjump);
                    240:                emiti(p);
                    241:                stuffdot(q);
                    242:                emitf(Xunlocal);
                    243:                break;
                    244:        case WORD:
                    245:                emitf(Xword);
                    246:                emits(strdup(t->str));
                    247:                break;
                    248:        case DUP:
                    249:                if(t->rtype==DUPFD){
                    250:                        emitf(Xdup);
                    251:                        emiti(t->fd0);
                    252:                        emiti(t->fd1);
                    253:                }
                    254:                else{
                    255:                        emitf(Xclose);
                    256:                        emiti(t->fd0);
                    257:                }
                    258:                outcode(c1, eflag);
                    259:                emitf(Xpopredir);
                    260:                break;
                    261:        case PIPEFD:
                    262:                emitf(Xpipefd);
                    263:                emiti(t->rtype);
                    264:                p=emiti(0);
                    265:                outcode(c0, eflag);
                    266:                emitf(Xexit);
                    267:                stuffdot(p);
                    268:                break;
                    269:        case REDIR:
                    270:                emitf(Xmark);
                    271:                outcode(c0, eflag);
                    272:                emitf(Xglob);
                    273:                switch(t->rtype){
                    274:                case APPEND:
                    275:                        emitf(Xappend);
                    276:                        break;
                    277:                case WRITE:
                    278:                        emitf(Xwrite);
                    279:                        break;
                    280:                case READ:
                    281:                case HERE:
                    282:                        emitf(Xread);
                    283:                        break;
                    284:                }
                    285:                emiti(t->fd0);
                    286:                outcode(c1, eflag);
                    287:                emitf(Xpopredir);
                    288:                break;
                    289:        case '=':
                    290:                tt=t;
                    291:                for(;t && t->type=='=';t=c2);
                    292:                if(t){
                    293:                        for(t=tt;t->type=='=';t=c2){
                    294:                                emitf(Xmark);
                    295:                                outcode(c1, eflag);
                    296:                                emitf(Xmark);
                    297:                                outcode(c0, eflag);
                    298:                                emitf(Xlocal);
                    299:                        }
                    300:                        t=tt;
                    301:                        outcode(c2, eflag);
                    302:                        for(;t->type=='=';t=c2) emitf(Xunlocal);
                    303:                }
                    304:                else{
                    305:                        for(t=tt;t;t=c2){
                    306:                                emitf(Xmark);
                    307:                                outcode(c1, eflag);
                    308:                                emitf(Xmark);
                    309:                                outcode(c0, eflag);
                    310:                                emitf(Xassign);
                    311:                        }
                    312:                }
                    313:                t=tt;   /* so tests below will work */
                    314:                break;
                    315:        case PIPE:
                    316:                emitf(Xpipe);
                    317:                emiti(t->fd0);
                    318:                emiti(t->fd1);
                    319:                p=emiti(0);
                    320:                q=emiti(0);
                    321:                outcode(c0, eflag);
                    322:                emitf(Xexit);
                    323:                stuffdot(p);
                    324:                outcode(c1, eflag);
                    325:                emitf(Xreturn);
                    326:                stuffdot(q);
                    327:                emitf(Xpipewait);
                    328:                break;
                    329:        }
                    330:        if(t->type!=NOT && t->type!=';')
                    331:                runq->iflast=t->type==IF;
                    332:        else if(c0) runq->iflast=c0->type==IF;
                    333: }
                    334: /*
                    335:  * switch code looks like this:
                    336:  *     Xmark
                    337:  *     (get switch value)
                    338:  *     Xjump   1f
                    339:  * out:        Xjump   leave
                    340:  * 1:  Xmark
                    341:  *     (get case values)
                    342:  *     Xcase   1f
                    343:  *     (commands)
                    344:  *     Xjump   out
                    345:  * 1:  Xmark
                    346:  *     (get case values)
                    347:  *     Xcase   1f
                    348:  *     (commands)
                    349:  *     Xjump   out
                    350:  * 1:
                    351:  * leave:
                    352:  *     Xpopm
                    353:  */
                    354: void codeswitch(tree *t, int eflag)
                    355: {
                    356:        int leave;              /* patch jump address to leave switch */
                    357:        int out;                /* jump here to leave switch */
                    358:        int nextcase;   /* patch jump address to next case */
                    359:        tree *tt;
                    360:        if(c1->child[0]->type!=';'
                    361:        || !iscase(c1->child[0]->child[0])){
                    362:                yyerror("case missing in switch");
                    363:                return;
                    364:        }
                    365:        emitf(Xmark);
                    366:        outcode(c0, eflag);
                    367:        emitf(Xjump);
                    368:        nextcase=emiti(0);
                    369:        out=emitf(Xjump);
                    370:        leave=emiti(0);
                    371:        stuffdot(nextcase);
                    372:        t=c1->child[0];
                    373:        while(t->type==';'){
                    374:                tt=c1;
                    375:                emitf(Xmark);
                    376:                for(t=c0->child[0];t->type==ARGLIST;t=c0) outcode(c1, eflag);
                    377:                emitf(Xcase);
                    378:                nextcase=emiti(0);
                    379:                t=tt;
                    380:                for(;;){
                    381:                        if(t->type==';'){
                    382:                                if(iscase(c0)) break;
                    383:                                outcode(c0, eflag);
                    384:                                t=c1;
                    385:                        }
                    386:                        else{
                    387:                                outcode(t, eflag);
                    388:                                break;
                    389:                        }
                    390:                }
                    391:                emitf(Xjump);
                    392:                emiti(out);
                    393:                stuffdot(nextcase);
                    394:        }
                    395:        stuffdot(leave);
                    396:        emitf(Xpopm);
                    397: }
                    398: int iscase(tree *t)
                    399: {
                    400:        if(t->type!=SIMPLE) return 0;
                    401:        do t=c0; while(t->type==ARGLIST);
                    402:        return t->type==WORD && !t->quoted && strcmp(t->str, "case")==0;
                    403: }
                    404: code *codecopy(code *cp)
                    405: {
                    406:        cp[0].i++;
                    407:        return cp;
                    408: }
                    409: void codefree(code *cp)
                    410: {
                    411:        code *p;
                    412:        if(--cp[0].i!=0) return;
                    413:        for(p=cp+1;p->f;p++){
                    414:                if(p->f==Xappend || p->f==Xclose || p->f==Xread || p->f==Xwrite
                    415:                || p->f==Xasync || p->f==Xbackq || p->f==Xcase || p->f==Xfalse
                    416:                || p->f==Xfor || p->f==Xjump
                    417:                || p->f==Xsubshell || p->f==Xtrue) p++;
                    418:                else if(p->f==Xdup || p->f==Xpipefd) p+=2;
                    419:                else if(p->f==Xpipe) p+=4;
                    420:                else if(p->f==Xword || p->f==Xdelhere) efree((++p)->s);
                    421:                else if(p->f==Xfn){
                    422:                        efree(p[2].s);
                    423:                        p+=2;
                    424:                }
                    425:        }
                    426:        efree((char *)cp);
                    427: }

unix.superglobalmegacorp.com

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