Annotation of lucent/sys/src/cmd/rc/code.c, revision 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.