aboutsummaryrefslogtreecommitdiff
path: root/sys/cmd/rc/lex.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/cmd/rc/lex.c')
-rw-r--r--sys/cmd/rc/lex.c97
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('$','#');