Annotation of researchv9/jtools/src/sam/cmd.c, revision 1.1.1.1

1.1       root        1: #include "sam.h"
                      2: #include "parse.h"
                      3: 
                      4: int    nl_cmd(), a_cmd(), b_cmd(), c_cmd(), cd_cmd(), d_cmd(), D_cmd(), e_cmd();
                      5: int    f_cmd(), g_cmd(), i_cmd(), k_cmd(), m_cmd(), n_cmd(), p_cmd(), q_cmd();
                      6: int    s_cmd(), u_cmd(), w_cmd(), x_cmd(), X_cmd(), unix_cmd(), eq_cmd();
                      7: 
                      8: static char    linex[]="\n";
                      9: static char    wordx[]=" \t\n";
                     10: struct cmdtab cmdtab[]={
                     11: /*     cmdc    text    regexp  addr    defcmd  defaddr count   token    fn     */
                     12:        '\n',   0,      0,      0,      0,      aDot,   0,      0,      nl_cmd,
                     13:        'a',    1,      0,      0,      0,      aDot,   0,      0,      a_cmd,
                     14:        'b',    0,      0,      0,      0,      aNo,    0,      linex,  b_cmd,
                     15:        'B',    0,      0,      0,      0,      aNo,    0,      linex,  b_cmd,
                     16:        'c',    1,      0,      0,      0,      aDot,   0,      0,      c_cmd,
                     17:        'd',    0,      0,      0,      0,      aDot,   0,      0,      d_cmd,
                     18:        'D',    0,      0,      0,      0,      aNo,    0,      linex,  D_cmd,
                     19:        'e',    0,      0,      0,      0,      aNo,    0,      wordx,  e_cmd,
                     20:        'f',    0,      0,      0,      0,      aNo,    0,      wordx,  f_cmd,
                     21:        'g',    0,      1,      0,      'p',    aDot,   0,      0,      g_cmd,
                     22:        'i',    1,      0,      0,      0,      aDot,   0,      0,      i_cmd,
                     23:        'k',    0,      0,      0,      0,      aDot,   0,      0,      k_cmd,
                     24:        'm',    0,      0,      1,      0,      aDot,   0,      0,      m_cmd,
                     25:        'n',    0,      0,      0,      0,      aNo,    0,      0,      n_cmd,
                     26:        'p',    0,      0,      0,      0,      aDot,   0,      0,      p_cmd,
                     27:        'q',    0,      0,      0,      0,      aNo,    0,      0,      q_cmd,
                     28:        'r',    0,      0,      0,      0,      aDot,   0,      wordx,  e_cmd,
                     29:        's',    0,      1,      0,      0,      aDot,   1,      0,      s_cmd,
                     30:        't',    0,      0,      1,      0,      aDot,   0,      0,      m_cmd,
                     31:        'u',    0,      0,      0,      0,      aNo,    1,      0,      u_cmd,
                     32:        'v',    0,      1,      0,      'p',    aDot,   0,      0,      g_cmd,
                     33:        'w',    0,      0,      0,      0,      aAll,   0,      wordx,  w_cmd,
                     34:        'x',    0,      1,      0,      'p',    aDot,   0,      0,      x_cmd,
                     35:        'y',    0,      1,      0,      'p',    aDot,   0,      0,      x_cmd,
                     36:        'X',    0,      1,      0,      'f',    aNo,    0,      0,      X_cmd,
                     37:        'Y',    0,      1,      0,      'f',    aNo,    0,      0,      X_cmd,
                     38:        '!',    0,      0,      0,      0,      aNo,    0,      linex,  unix_cmd,
                     39:        '>',    0,      0,      0,      0,      aDot,   0,      linex,  unix_cmd,
                     40:        '<',    0,      0,      0,      0,      aDot,   0,      linex,  unix_cmd,
                     41:        '|',    0,      0,      0,      0,      aDot,   0,      linex,  unix_cmd,
                     42:        '=',    0,      0,      0,      0,      aDot,   0,      linex,  eq_cmd,
                     43:        'c'|0x100,0,    0,      0,      0,      aNo,    0,      wordx,  cd_cmd,
                     44:        0,      0,      0,      0,      0,      0,      0,      0,
                     45: };
                     46: Cmd    *parsecmd();
                     47: Addr   *compoundaddr();
                     48: Addr   *simpleaddr();
                     49: uchar  line[BLOCKSIZE];
                     50: uchar  termline[BLOCKSIZE];
                     51: uchar  *linep=line;
                     52: uchar  *terminp=termline;
                     53: uchar  *termoutp=termline;
                     54: List   cmdlist;
                     55: List   addrlist;
                     56: List   relist;
                     57: List   stringlist;
                     58: int    eof;
                     59: 
                     60: resetcmd(){
                     61:        linep=line;
                     62:        *linep=0;
                     63:        terminp=termoutp=termline;
                     64:        freecmd();
                     65: }
                     66: getc(){
                     67:        if(eof)
                     68:                return -1;
                     69:        if(*linep==0 && inputline()<0){
                     70:                eof=TRUE;
                     71:                return -1;
                     72:        }
                     73:        return *linep++;
                     74: }
                     75: nextc(){
                     76:        if(*linep==0)
                     77:                return -1;
                     78:        return *linep;
                     79: }
                     80: ungetc(){
                     81:        if(--linep<line)
                     82:                panic("ungetc");
                     83: }
                     84: inputline(){
                     85:        register i, c;
                     86:        linep=line;
                     87:        i=0;
                     88:        do{
                     89:                if((c=inputc())<=0)
                     90:                        return -1;
                     91:                if(i==(sizeof line)-1)
                     92:                        error(Etoolong);
                     93:        }while((line[i++]=c)!='\n');
                     94:        line[i]=0;
                     95:        return 1;
                     96: }
                     97: termcommand()
                     98: {
                     99:        register Posn p;
                    100:        dounlock=TRUE;
                    101:        Fgetcset(cmd, cmdpt);
                    102:        for(p=cmdpt; p<cmd->nbytes; p++)
                    103:                *terminp++=Fgetc(cmd);
                    104:        cmdpt=cmd->nbytes;
                    105: }
                    106: inputc()
                    107: {
                    108:        register c, n;
                    109:        uchar cc;
                    110:    Again:
                    111:        if(downloaded){
                    112:                while(termoutp==terminp){
                    113:                        if(cmd && cmd->mod!=0){
                    114:                                Fupdate(cmd, FALSE, downloaded);
                    115:                                cmd->dot.r.p1=cmd->dot.r.p2=cmd->nbytes;
                    116:                                telldot(cmd);
                    117:                        }
                    118:                        if(dounlock){
                    119:                                outT0(Hunlock);
                    120:                                dounlock=FALSE;
                    121:                        }
                    122:                        if(patset)
                    123:                                tellpat();
                    124:                        if(rcv()==0)
                    125:                                return -1;
                    126:                }
                    127:                c= *termoutp++;
                    128:                if(termoutp==terminp)
                    129:                        terminp=termoutp=termline;
                    130:                n=1;
                    131:        }else{
                    132:                n=read(0, (char *)&cc, 1);
                    133:                c=cc;
                    134:        }
                    135:        if(n<=0)
                    136:                return -1;
                    137:        if(c==0 || (c&HIGHBIT)){
                    138:                warn(Wnonascii);
                    139:                goto Again;
                    140:        }
                    141:        return c;
                    142: }
                    143: cmdloop(){
                    144:        Cmd *cmdp;
                    145:        File *ocurfile;
                    146:        int loaded;
                    147:        for(;;){
                    148:                if(!downloaded && curfile && curfile->state==Unread)
                    149:                        load(curfile);
                    150:                if((cmdp=parsecmd(0))==0)
                    151:                        break;
                    152:                ocurfile=curfile;
                    153:                loaded=curfile && curfile->state!=Unread;
                    154:                if(cmdexec(curfile, cmdp)==0)
                    155:                        break;
                    156:                freecmd();
                    157:                update();
                    158:                if(downloaded && curfile &&
                    159:                    (ocurfile!=curfile || (!loaded && curfile->state!=Unread)))
                    160:                        outTs(Hcurrent, curfile->tag);
                    161:        }
                    162: }
                    163: Cmd *
                    164: newcmd(){
                    165:        register Cmd *p;
                    166:        p=new(Cmd, 1);
                    167:        inslist(&cmdlist, cmdlist.nused, (long)p);
                    168:        return p;
                    169: }
                    170: Addr *
                    171: newaddr(){
                    172:        register Addr *p;
                    173:        p=new(Addr, 1);
                    174:        inslist(&addrlist, addrlist.nused, (long)p);
                    175:        return p;
                    176: }
                    177: Regexp *
                    178: newre(){
                    179:        register Regexp *p;
                    180:        p=new(Regexp, 1);
                    181:        inslist(&relist, relist.nused, (long)p);
                    182:        strinit(&p->text);
                    183:        return p;
                    184: }
                    185: String *
                    186: newstring(){
                    187:        register String *p;
                    188:        p=new(String, 1);
                    189:        inslist(&stringlist, stringlist.nused, (long)p);
                    190:        strinit(p);
                    191:        return p;
                    192: }
                    193: freecmd()
                    194: {
                    195:        register i;
                    196:        while(cmdlist.nused>0)
                    197:                free((uchar *)cmdlist.ptr[--cmdlist.nused]);
                    198:        while(addrlist.nused>0)
                    199:                free((uchar *)addrlist.ptr[--addrlist.nused]);
                    200:        while(relist.nused>0){
                    201:                i= --relist.nused;
                    202:                strclose(&((Regexp *)relist.ptr[i])->text);
                    203:                free((uchar *)relist.ptr[i]);   /* WARNING!! */
                    204:        }
                    205:        while(stringlist.nused>0){
                    206:                i= --stringlist.nused;
                    207:                strclose((String *)stringlist.ptr[i]);
                    208:                free((uchar *)stringlist.ptr[i]);
                    209:        }
                    210: }
                    211: lookup(c)
                    212:        register c;
                    213: {
                    214:        register i;
                    215:        for(i=0; cmdtab[i].cmdc; i++)
                    216:                if(cmdtab[i].cmdc==c)
                    217:                        return i;
                    218:        return -1;
                    219: }
                    220: okdelim(c){
                    221:        if(c=='\\' || ('a'<=c && c<='z') || ('A'<=c && c<='Z') || ('0'<=c && c<='9'))
                    222:                error_c(Edelim, c);
                    223: }
                    224: atnl(){
                    225:        skipbl();
                    226:        if(getc()!='\n')
                    227:                error(Enewline);
                    228: }
                    229: getrhs(s, delim, cmd)
                    230:        register String *s;
                    231:        register delim;
                    232: {
                    233:        register c;
                    234:        while((c=getc())>0 && c!=delim && c!='\n'){
                    235:                if(c=='\\'){
                    236:                        if((c=getc())<=0)
                    237:                                error(Ebadrhs);
                    238:                        if(c=='\n'){
                    239:                                ungetc();
                    240:                                c='\\';
                    241:                        }else if(c=='n')
                    242:                                c='\n';
                    243:                        else if(c!=delim && (cmd=='s' || c!='\\'))      /* s does its own */
                    244:                                straddc(s, '\\');
                    245:                }
                    246:                straddc(s, c);
                    247:        }
                    248:        ungetc();       /* let client read whether delimeter, '\n' or whatever */
                    249: }
                    250: String *
                    251: collecttoken(end)
                    252:        register char *end;
                    253: {
                    254:        register String *s=newstring();
                    255:        register c, i;
                    256:        i=0;
                    257:        while((c=nextc())==' ' || c=='\t')
                    258:                i++, straddc(s, getc()); /* blanks significant for getname() */
                    259:        while((c=getc())>0 && strchr(end, c)==0)
                    260:                i++, straddc(s, c);
                    261:        straddc(s, 0);
                    262:        if(c!='\n')
                    263:                atnl();
                    264:        return s;
                    265: }
                    266: String *
                    267: collecttext(){
                    268:        register String *s=newstring();
                    269:        register begline, i;
                    270:        register c, delim;
                    271:        if(skipbl()=='\n'){
                    272:                getc();
                    273:                i=0;
                    274:                do{
                    275:                        begline=i;
                    276:                        while((c=getc())>0 && c!='\n')
                    277:                                i++, straddc(s, c);
                    278:                        i++, straddc(s, '\n');
                    279:                        if(c<0)
                    280:                                goto Return;
                    281:                }while(s->s[begline]!='.' || s->s[begline+1]!='\n');
                    282:                strdelete(s, (long)s->n-2, (long)s->n);
                    283:        }else{
                    284:                okdelim(delim=getc());
                    285:                getrhs(s, delim, 'a');
                    286:                if(nextc()==delim)
                    287:                        getc();
                    288:                atnl();
                    289:        }
                    290:     Return:
                    291:        straddc(s, 0);          /* JUST FOR CMDPRINT() */
                    292:        return s;
                    293: }
                    294: Cmd *
                    295: parsecmd(nest)
                    296: {
                    297:        register i, c;
                    298:        register struct cmdtab *ct;
                    299:        register Cmd *cp, *ncp;
                    300:        Cmd cmd;
                    301:        cmd.next=cmd.ccmd=0;
                    302:        cmd.re=0;
                    303:        cmd.flag=cmd.num=0;
                    304:        cmd.addr=compoundaddr();
                    305:        if(skipbl()==-1)
                    306:                return 0;
                    307:        if((c=getc())==-1)
                    308:                return 0;
                    309:        cmd.cmdc=c;
                    310:        if(cmd.cmdc=='c' && nextc()=='d'){      /* sleazy two-character case */
                    311:                getc();         /* the 'd' */
                    312:                cmd.cmdc='c'|0x100;
                    313:        }
                    314:        i=lookup(cmd.cmdc);
                    315:        if(i>=0){
                    316:                if(cmd.cmdc=='\n')
                    317:                        goto Return;    /* let nl_cmd work it all out */
                    318:                ct= &cmdtab[i];
                    319:                if(ct->defaddr==aNo && cmd.addr)
                    320:                        error(Enoaddr);
                    321:                if(ct->count)
                    322:                        cmd.num=getnum();
                    323:                if(ct->regexp){
                    324:                        /* x without pattern -> .*\n, indicated by cmd.re==0 */
                    325:                        /* X without pattern is all files */
                    326:                        if((ct->cmdc!='x' && ct->cmdc!='X') ||
                    327:                           ((c=nextc())!=' ' && c!='\t' && c!='\n')){
                    328:                                skipbl();
                    329:                                if((c=getc())=='\n' || c<0)
                    330:                                        error(Enopattern);
                    331:                                cmd.re=getregexp(c);
                    332:                                if(ct->cmdc=='s'){
                    333:                                        cmd.ctext=newstring();
                    334:                                        getrhs(cmd.ctext, c, 's');
                    335:                                        if(nextc()==c){
                    336:                                                getc();
                    337:                                                if(nextc()=='g')
                    338:                                                        cmd.flag=getc();
                    339:                                        }
                    340:                        
                    341:                                }
                    342:                        }
                    343:                }
                    344:                if(ct->addr && (cmd.caddr=simpleaddr())==0)
                    345:                        error(Eaddress);
                    346:                if(ct->defcmd){
                    347:                        if(skipbl()=='\n'){
                    348:                                getc();
                    349:                                cmd.ccmd=newcmd();
                    350:                                cmd.ccmd->cmdc=ct->defcmd;
                    351:                        }else if((cmd.ccmd=parsecmd(nest))==0)
                    352:                                panic("defcmd");
                    353:                }else if(ct->text)
                    354:                        cmd.ctext=collecttext();
                    355:                else if(ct->token)
                    356:                        cmd.ctext=collecttoken(ct->token);
                    357:                else
                    358:                        atnl();
                    359:        }else
                    360:                switch(cmd.cmdc){
                    361:                case '{':
                    362:                        cp=0;
                    363:                        do{
                    364:                                if(skipbl()=='\n')
                    365:                                        getc();
                    366:                                ncp=parsecmd(nest+1);
                    367:                                if(cp)
                    368:                                        cp->next=ncp;
                    369:                                else
                    370:                                        cmd.ccmd=ncp;
                    371:                        }while(cp=ncp);
                    372:                        break;
                    373:                case '}':
                    374:                        atnl();
                    375:                        if(nest==0)
                    376:                                error(Enolbrace);
                    377:                        return 0;
                    378:                default:
                    379:                        error_c(Eunk, cmd.cmdc);
                    380:                }
                    381:     Return:
                    382:        cp=newcmd();
                    383:        *cp=cmd;
                    384:        return cp;
                    385: }
                    386: Regexp *                               /* BUGGERED */
                    387: getregexp(delim)
                    388:        register delim;
                    389: {
                    390:        register Regexp *r=newre();
                    391:        register c;
                    392:        for(strzero(&genstr); ; straddc(&genstr, c))
                    393:                if((c=getc())=='\\'){
                    394:                        if(nextc()==delim)
                    395:                                c=getc();
                    396:                        else if(nextc()=='\\'){
                    397:                                straddc(&genstr, c);
                    398:                                c=getc();
                    399:                        }
                    400:                }else if(c==delim || c=='\n')
                    401:                        break;
                    402:        if(c!=delim && c)
                    403:                ungetc();
                    404:        if(genstr.n>0){
                    405:                patset=TRUE;
                    406:                strdupstr(&lastpat, &genstr);
                    407:                straddc(&lastpat, '\0');
                    408:        }
                    409:        if(lastpat.n<=1)
                    410:                error(Epattern);
                    411:        strdupstr(&r->text, &lastpat);
                    412:        return r;
                    413: }
                    414: Addr *
                    415: compoundaddr(){
                    416:        Addr addr;
                    417:        register Addr *ap;
                    418:        addr.aprev=simpleaddr();
                    419:        if((addr.type=skipbl())!=',' && addr.type!=';')
                    420:                return addr.aprev;
                    421:        getc();
                    422:        addr.next=compoundaddr();
                    423:        if(addr.next && addr.next->aprev==0)
                    424:                error(Eaddress);
                    425:        ap=newaddr();
                    426:        *ap=addr;
                    427:        return ap;
                    428: }
                    429: Addr *
                    430: simpleaddr()
                    431: {
                    432:        Addr addr;
                    433:        register Addr *ap, *nap;
                    434:        addr.next=0;
                    435:        switch(skipbl()){
                    436:        case '#':
                    437:                addr.type=getc();
                    438:                addr.num=getnum();
                    439:                break;
                    440:        case '0': case '1': case '2': case '3': case '4':
                    441:        case '5': case '6': case '7': case '8': case '9': 
                    442:                addr.num=getnum();
                    443:                addr.type='l';
                    444:                break;
                    445:        case '/': case '?': case '"':
                    446:                addr.are=getregexp(addr.type=getc());
                    447:                break;
                    448:        case '.':
                    449:        case '$':
                    450:        case '+':
                    451:        case '-':
                    452:        case '\'':
                    453:                addr.type=getc();
                    454:                break;
                    455:        default:
                    456:                return 0;
                    457:        }
                    458:        if(addr.next=simpleaddr())
                    459:                switch(addr.next->type){
                    460:                case '.':
                    461:                case '$':
                    462:                case '\'':
                    463:                        if(addr.type!='"')
                    464:                case '"':
                    465:                                error(Eaddress);
                    466:                        break;
                    467:                case 'l':
                    468:                case '#':
                    469:                        if(addr.type=='"')
                    470:                                break;
                    471:                        /* fall through */
                    472:                case '/':
                    473:                case '?':
                    474:                        if(addr.type!='+' && addr.type!='-'){
                    475:                                /* insert the missing '+' */
                    476:                                nap=newaddr();
                    477:                                nap->type='+';
                    478:                                nap->next=addr.next;
                    479:                                addr.next=nap;
                    480:                        }
                    481:                        break;
                    482:                case '+':
                    483:                case '-':
                    484:                        break;
                    485:                default:
                    486:                        panic("simpleaddr");
                    487:                }
                    488:        ap=newaddr();
                    489:        *ap=addr;
                    490:        return ap;
                    491: }

unix.superglobalmegacorp.com

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