Annotation of lucent/sys/src/cmd/rc/lex.c, revision 1.1

1.1     ! root        1: #include "rc.h"
        !             2: #include "exec.h"
        !             3: #include "io.h"
        !             4: #include "getflags.h"
        !             5: #include "fns.h"
        !             6: int getnext(void);
        !             7: int wordchr(int c)
        !             8: {
        !             9:        return !strchr("\n \t#;&|^$=`'{}()<>", c) && c!=EOF;
        !            10: }
        !            11: int idchr(int c)
        !            12: {
        !            13:        /*
        !            14:         * Formerly:
        !            15:         * return 'a'<=c && c<='z' || 'A'<=c && c<='Z' || '0'<=c && c<='9'
        !            16:         *      || c=='_' || c=='*';
        !            17:         */
        !            18:        return c>' ' && !strchr("!\"#$%&'()+,-./:;<=>?@[\\]^`{|}~", c);
        !            19: }
        !            20: int future=EOF;
        !            21: int doprompt=1;
        !            22: int inquote;
        !            23: /*
        !            24:  * Look ahead in the input stream
        !            25:  */
        !            26: int nextc(void){
        !            27:        if(future==EOF) future=getnext();
        !            28:        return future;
        !            29: }
        !            30: /*
        !            31:  * Consume the lookahead character.
        !            32:  */
        !            33: int advance(void){
        !            34:        int c=nextc();
        !            35:        lastc=future;
        !            36:        future=EOF;
        !            37:        return c;
        !            38: }
        !            39: /*
        !            40:  * read a character from the input stream
        !            41:  */    
        !            42: int getnext(void){
        !            43:        register int c;
        !            44:        static peekc=EOF;
        !            45:        if(peekc!=EOF){
        !            46:                c=peekc;
        !            47:                peekc=EOF;
        !            48:                return c;
        !            49:        }
        !            50:        if(runq->eof) return EOF;
        !            51:        if(doprompt) pprompt();
        !            52:        c=rchr(runq->cmdfd);
        !            53:        if(!inquote && c=='\\'){
        !            54:                c=rchr(runq->cmdfd);
        !            55:                if(c=='\n'){
        !            56:                        doprompt=1;
        !            57:                        c=' ';
        !            58:                }
        !            59:                else{
        !            60:                        peekc=c;
        !            61:                        c='\\';
        !            62:                }
        !            63:        }
        !            64:        doprompt=doprompt || c=='\n' || c==EOF;
        !            65:        if(c==EOF) runq->eof++;
        !            66:        else if(flag['V'] || ndot>=2 && flag['v']) pchr(err, c);
        !            67:        return c;
        !            68: }
        !            69: void pprompt(void){
        !            70:        var *prompt;
        !            71:        if(runq->iflag){
        !            72:                pstr(err, promptstr);
        !            73:                flush(err);
        !            74:                prompt=vlook("prompt");
        !            75:                if(prompt->val && prompt->val->next)
        !            76:                        promptstr=prompt->val->next->word;
        !            77:                else
        !            78:                        promptstr="\t";
        !            79:        }
        !            80:        runq->lineno++;
        !            81:        doprompt=0;
        !            82: }
        !            83: void skipwhite(void){
        !            84:        int c;
        !            85:        for(;;){
        !            86:                c=nextc();
        !            87:                if(c=='#'){     /* Why did this used to be  if(!inquote && c=='#') ?? */
        !            88:                        for(;;){
        !            89:                                c=nextc();
        !            90:                                if(c=='\n' || c==EOF) break;
        !            91:                                advance();
        !            92:                        }
        !            93:                }
        !            94:                if(c==' ' || c=='\t') advance();
        !            95:                else return;
        !            96:        }
        !            97: }
        !            98: void skipnl(void){
        !            99:        register int c;
        !           100:        for(;;){
        !           101:                skipwhite();
        !           102:                c=nextc();
        !           103:                if(c!='\n') return;
        !           104:                advance();
        !           105:        }
        !           106: }
        !           107: int nextis(int c){
        !           108:        if(nextc()==c){
        !           109:                advance();
        !           110:                return 1;
        !           111:        }
        !           112:        return 0;
        !           113: }
        !           114: char *addtok(char *p, int val){
        !           115:        if(p==0) return 0;
        !           116:        if(p==&tok[NTOK]){
        !           117:                *p=0;
        !           118:                yyerror("token buffer too short");
        !           119:                return 0;
        !           120:        }
        !           121:        *p++=val;
        !           122:        return p;
        !           123: }
        !           124: char *addutf(char *p, int c){
        !           125:        p=addtok(p, c);
        !           126:        if(twobyte(c))   /* 2-byte escape */
        !           127:                return addtok(p, advance());
        !           128:        if(threebyte(c)){       /* 3-byte escape */
        !           129:                p=addtok(p, advance());
        !           130:                return addtok(p, advance());
        !           131:        }
        !           132:        return p;
        !           133: }
        !           134: int lastdol;   /* was the last token read '$' or '$#' or '"'? */
        !           135: int lastword;  /* was the last token read a word or compound word terminator? */
        !           136: int yylex(void){
        !           137:        register int c, d=nextc();
        !           138:        register char *w=tok;
        !           139:        register struct tree *t;
        !           140:        yylval.tree=0;
        !           141:        /*
        !           142:         * Embarassing sneakiness:  if the last token read was a quoted or unquoted
        !           143:         * WORD then we alter the meaning of what follows.  If the next character
        !           144:         * is `(', we return SUB (a subscript paren) and consume the `('.  Otherwise,
        !           145:         * if the next character is the first character of a simple or compound word,
        !           146:         * we insert a `^' before it.
        !           147:         */
        !           148:        if(lastword){
        !           149:                lastword=0;
        !           150:                if(d=='('){
        !           151:                        advance();
        !           152:                        strcpy(tok, "( [SUB]");
        !           153:                        return SUB;
        !           154:                }
        !           155:                if(wordchr(d) || d=='\'' || d=='`' || d=='$' || d=='"'){
        !           156:                        strcpy(tok, "^");
        !           157:                        return '^';
        !           158:                }
        !           159:        }
        !           160:        inquote=0;
        !           161:        skipwhite();
        !           162:        switch(c=advance()){
        !           163:        case EOF:
        !           164:                lastdol=0;
        !           165:                strcpy(tok, "EOF");
        !           166:                return EOF;
        !           167:        case '$':
        !           168:                lastdol=1;
        !           169:                if(nextis('#')){
        !           170:                        strcpy(tok, "$#");
        !           171:                        return COUNT;
        !           172:                }
        !           173:                if(nextis('"')){
        !           174:                        strcpy(tok, "$\"");
        !           175:                        return '"';
        !           176:                }
        !           177:                strcpy(tok, "$");
        !           178:                return '$';
        !           179:        case '&':
        !           180:                lastdol=0;
        !           181:                if(nextis('&')){
        !           182:                        skipnl();
        !           183:                        strcpy(tok, "&&");
        !           184:                        return ANDAND;
        !           185:                }
        !           186:                strcpy(tok, "&");
        !           187:                return '&';
        !           188:        case '|':
        !           189:                lastdol=0;
        !           190:                if(nextis(c)){
        !           191:                        skipnl();
        !           192:                        strcpy(tok, "||");
        !           193:                        return OROR;
        !           194:                }
        !           195:        case '<':
        !           196:        case '>':
        !           197:                lastdol=0;
        !           198:                /*
        !           199:                 * funny redirection tokens:
        !           200:                 *      redir:  arrow | arrow '[' fd ']'
        !           201:                 *      arrow:  '<' | '<<' | '>' | '>>' | '|'
        !           202:                 *      fd:     digit | digit '=' | digit '=' digit
        !           203:                 *      digit:  '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'
        !           204:                 * some possibilities are nonsensical and get a message.
        !           205:                 */
        !           206:                *w++=c;
        !           207:                t=newtree();
        !           208:                switch(c){
        !           209:                case '|':
        !           210:                        t->type=PIPE;
        !           211:                        t->fd0=1;
        !           212:                        t->fd1=0;
        !           213:                        break;
        !           214:                case '>':
        !           215:                        t->type=REDIR;
        !           216:                        if(nextis(c)){
        !           217:                                t->rtype=APPEND;
        !           218:                                *w++=c;
        !           219:                        }
        !           220:                        else t->rtype=WRITE;
        !           221:                        t->fd0=1;
        !           222:                        break;
        !           223:                case '<':
        !           224:                        t->type=REDIR;
        !           225:                        if(nextis(c)){
        !           226:                                t->rtype=HERE;
        !           227:                                *w++=c;
        !           228:                        }
        !           229:                        else t->rtype=READ;
        !           230:                        t->fd0=0;
        !           231:                        break;
        !           232:                }
        !           233:                if(nextis('[')){
        !           234:                        *w++='[';
        !           235:                        c=advance();
        !           236:                        *w++=c;
        !           237:                        if(c<'0' || '9'<c){
        !           238:                        RedirErr:
        !           239:                                *w=0;
        !           240:                                yyerror(t->type==PIPE?"pipe syntax"
        !           241:                                                :"redirection syntax");
        !           242:                                return EOF;
        !           243:                        }
        !           244:                        t->fd0=0;
        !           245:                        do{
        !           246:                                t->fd0=t->fd0*10+c-'0';
        !           247:                                *w++=c;
        !           248:                                c=advance();
        !           249:                        }while('0'<=c && c<='9');
        !           250:                        if(c=='='){
        !           251:                                *w++='=';
        !           252:                                if(t->type==REDIR) t->type=DUP;
        !           253:                                c=advance();
        !           254:                                if('0'<=c && c<='9'){
        !           255:                                        t->rtype=DUPFD;
        !           256:                                        t->fd1=t->fd0;
        !           257:                                        t->fd0=0;
        !           258:                                        do{
        !           259:                                                t->fd0=t->fd0*10+c-'0';
        !           260:                                                *w++=c;
        !           261:                                                c=advance();
        !           262:                                        }while('0'<=c && c<='9');
        !           263:                                }
        !           264:                                else{
        !           265:                                        if(t->type==PIPE) goto RedirErr;
        !           266:                                        t->rtype=CLOSE;
        !           267:                                }
        !           268:                        }
        !           269:                        if(c!=']'
        !           270:                        || t->type==DUP && (t->rtype==HERE || t->rtype==APPEND))
        !           271:                                goto RedirErr;
        !           272:                        *w++=']';
        !           273:                }
        !           274:                *w='\0';
        !           275:                yylval.tree=t;
        !           276:                if(t->type==PIPE) skipnl();
        !           277:                return t->type;
        !           278:        case '\'':
        !           279:                lastdol=0;
        !           280:                lastword=1;
        !           281:                inquote=1;
        !           282:                for(;;){
        !           283:                        c=advance();
        !           284:                        if(c==EOF) break;
        !           285:                        if(c=='\''){
        !           286:                                if(nextc()!='\'')
        !           287:                                        break;
        !           288:                                advance();
        !           289:                        }
        !           290:                        w=addutf(w, c);
        !           291:                }
        !           292:                if(w!=0) *w='\0';
        !           293:                t=token(tok, WORD);
        !           294:                t->quoted=1;
        !           295:                yylval.tree=t;
        !           296:                return t->type;
        !           297:        }
        !           298:        if(!wordchr(c)){
        !           299:                lastdol=0;
        !           300:                tok[0]=c;
        !           301:                tok[1]='\0';
        !           302:                return c;
        !           303:        }
        !           304:        for(;;){
        !           305:                /* next line should have (char)c==GLOB, but ken's compiler is broken */
        !           306:                if(c=='*' || c=='[' || c=='?' || c==(unsigned char)GLOB)
        !           307:                        w=addtok(w, GLOB);
        !           308:                w=addutf(w, c);
        !           309:                c=nextc();
        !           310:                if(lastdol?!idchr(c):!wordchr(c)) break;
        !           311:                advance();
        !           312:        }
        !           313: Out:
        !           314:        lastword=1;
        !           315:        lastdol=0;
        !           316:        if(w!=0) *w='\0';
        !           317:        t=klook(tok);
        !           318:        if(t->type!=WORD) lastword=0;
        !           319:        t->quoted=0;
        !           320:        yylval.tree=t;
        !           321:        return t->type;
        !           322: }

unix.superglobalmegacorp.com

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