diff options
Diffstat (limited to 'sys/cmd/rc/lex.c')
-rw-r--r-- | sys/cmd/rc/lex.c | 97 |
1 files changed, 93 insertions, 4 deletions
diff --git a/sys/cmd/rc/lex.c b/sys/cmd/rc/lex.c index 4325882..373edd5 100644 --- a/sys/cmd/rc/lex.c +++ b/sys/cmd/rc/lex.c @@ -187,10 +187,6 @@ yylex(void) put3('E','O','F'); return EOF; - case '&': - put1('&'); - return '&'; - case '@': put1('@'); return Tsubshell; @@ -199,6 +195,99 @@ yylex(void) put1('!'); return Tbang; + case '&': + put1('&'); + return '&'; + + case '|': + if(nextis('|')){ + put2('|','|'); + return Toror; + } + node = maketree(); + *w++ = '|'; + + node->type = Tpipe; + node->redir.fd[0] = 1; + node->redir.fd[1] = 1; + goto redir; + + case '>': + node = maketree(); + *w++ = '>'; + node->type = Tredir; + + if(nextis('>')){ + node->redir.type = Rappend; + *w++ = '>'; + }else + node->redir.type = Rwrite; + node->redir.fd[0] = 1; + goto redir; + + case '<': + node = maketree(); + *w++ = '<'; + node->type = Tredir; + + if(nextis('<')){ + node->redir.type = Rhere; + *w++ = '<'; + }else if(nextis('>')){ + node->redir.type = Rrdwr; + *w++ = '>'; + }else{ + node->redir.type = Rread; + } + node->redir.fd[0] = 0; + /* fallthrough */ + redir: + if(nextis('[')){ + *w++='['; + c = advance(); + *w++ = c; + if(c < '0' || '9' < c){ + badredir: + *w = 0; + yyerror(node->type == Tpipe ? "pipe syntax" : "redirection syntax"); + return EOF; + } + node->redir.fd[0] = 0; + do{ + node->redir.fd[0] = 10*node->redir.fd[0]+(c-'0'); + *w++ = c; + c = advance(); + }while('0'<=c && c<='9'); + + if(c == '='){ + *w++ = '='; + if(node->type==Tredir) + node->type = Tdup; + c = advance(); + } + if(c < '0' || '9' < c){ + if(node->type == Tpipe) + goto badredir; + node->redir.type = Rclose; + }else{ + node->redir.type = Rdup; + node->redir.fd[1] = node->redir.fd[0]; + node->redir.fd[0] = 0; + do{ + node->redir.fd[0] = 10*node->redir.fd[0]+(c-'0'); + *w++ = c; + c = advance(); + }while('0'<=c && c<='9'); + } + if(c != ']' || (node->type == Tdup && (node->redir.type = Rhere || node->redir.type == Rappend))) + goto badredir; + *w++ = ']'; + } + *w++ = 0; + yylval.tree = node; + + return node->type; + case '$': if(nextis('#')){ put2('$','#'); |