commit - ff74f7cdda7b08da6fe7c8bbcca990305fd6b547
commit + 601e07b63653d0fed91594ebba261b733d017653
blob - 1ff84667b59d9fcfb646a3b1b9e9684cef45d775
blob + 0a1472b2ed3a31f2706a579b04ab485ad3df13f8
--- src/cmd/rc/checkparse
+++ src/cmd/rc/checkparse
#!/bin/bash
+aflag=false
+if [ "$1" = -a ]; then
+ aflag=true
+ shift
+fi
+
files="$@"
if [ $# = 0 ]; then
files=$(echo ./test.rc;
grep -l '^#!/usr/local/plan9/bin/rc' /usr/local/plan9/bin/{*,*/*} 2>/dev/null;
- grep -l '^#!/bin/rc' $HOME/pub/plan9/rc/bin/{*,*/*} 2>/dev/null)
+ grep -R -l '^#!/bin/rc' $HOME/pub/plan9 | egrep -v 'plan9/(lib/(oui|pci)|sys/man|sys/lib/man|sys/lib/scsicodes)' 2>/dev/null)
fi
for i in $files
do
if ! diff <(./o.rc -DY $i 2>&1) <(./o.rc -D $i 2>&1); then
- echo '#' $i
- exit 1
+ echo '^^^' $i
+ ! $aflag && exit 1
fi
done
+
blob - 48bd70deddbec479756021e1f21ec3040a8944dd
blob + e4410c00266a8ed192440a7c16b68a7ce0093a32
--- src/cmd/rc/lex.c
+++ src/cmd/rc/lex.c
lastword = 0;
if(d=='('){
advance();
- strcpy(tok, "( [SUB]");
+ strcpy(tok, "(");
return SUB;
}
if(wordchr(d) || d=='\'' || d=='`' || d=='$' || d=='"'){
blob - a46931dcf32dfcf548ea15deb7cd03187306d288
blob + dd102190335f2fee362f41db5244b1d40e2692bf
--- src/cmd/rc/parse.c
+++ src/cmd/rc/parse.c
static tree* cmd(int tok, int *ptok);
static tree* cmd2(int tok, int *ptok);
static tree* cmd3(int tok, int *ptok);
-static tree* cmd4(int tok, int *ptok);
static tree* cmds(int tok, int *ptok, int nlok);
static tree* epilog(int tok, int *ptok);
static int iswordtok(int tok);
static void
syntax(int tok)
{
- char buf[100];
- snprint(buf, sizeof buf, "syntax error %d", tok);
- yyerror(buf);
+ USED(tok);
+ yyerror("syntax error");
longjmp(yyjmp, 1);
}
static tree*
cmd(int tok, int *ptok)
{
- tok = dropsp(tok);
- switch(tok) {
- default:
- return cmd2(tok, ptok);
-
- }
-}
-
-static tree*
-cmd2(int tok, int *ptok)
-{
int op;
tree *t1, *t2;
// | cmd ANDAND cmd {$$=tree2(ANDAND, $1, $3);}
// | cmd OROR cmd {$$=tree2(OROR, $1, $3);}
- t1 = cmd3(tok, &tok);
+ tok = dropsp(tok);
+ t1 = cmd2(tok, &tok);
while(tok == ANDAND || tok == OROR) {
op = tok;
- t2 = cmd3(dropnl(yylex()), &tok);
+ t2 = cmd2(dropnl(yylex()), &tok);
t1 = tree2(op, t1, t2);
}
*ptok = tok;
}
static tree*
-cmd3(int tok, int *ptok)
+cmd2(int tok, int *ptok)
{
tree *t1, *t2, *t3;
// | cmd PIPE cmd {$$=mung2($2, $1, $3);}
- t1 = cmd4(tok, &tok);
+ t1 = cmd3(tok, &tok);
while(tok == PIPE) {
t2 = yylval.tree;
- t3 = cmd4(dropnl(yylex()), &tok);
+ t3 = cmd3(dropnl(yylex()), &tok);
t1 = mung2(t2, t1, t3);
}
*ptok = tok;
}
static tree*
-cmd4(int tok, int *ptok)
+cmd3(int tok, int *ptok)
{
tree *t1, *t2, *t3, *t4;
case SUBSHELL:
// | BANG cmd {$$=mung1($1, $2);}
// | SUBSHELL cmd {$$=mung1($1, $2);}
- // Note: cmd3: ! x | y is !{x | y} not {!x} | y.
+ // Note: cmd2: ! x | y is !{x | y} not {!x} | y.
t1 = yylval.tree;
- return mung1(t1, cmd3(yylex(), ptok));
+ return mung1(t1, cmd2(yylex(), ptok));
case REDIR:
case DUP:
// | redir cmd %prec BANG {$$=mung2($1, $1->child[0], $2);}
- // Note: cmd3: {>x echo a | tr a-z A-Z} writes A to x.
+ // Note: cmd2: {>x echo a | tr a-z A-Z} writes A to x.
t1 = yyredir(tok, &tok);
- t2 = cmd3(tok, ptok);
+ t2 = cmd2(tok, ptok);
return mung2(t1, t1->child[0], t2);
case '{':
t1 = yyword(tok, &tok, 0);
if(tok == '=') {
// assignment
- // Note: cmd3: {x=1 true | echo $x} echoes 1.
+ // Note: cmd2: {x=1 true | echo $x} echoes 1.
t1 = tree2('=', t1, yyword(yylex(), &tok, 1));
- t2 = cmd3(tok, ptok);
+ t2 = cmd2(tok, ptok);
return mung3(t1, t1->child[0], t1->child[1], t2);
}
goto out;
for(;;) {
if(iswordtok(tok)) {
+ // No free carats around parens.
+ if(t->type == PAREN || tok == '(')
+ syntax(tok);
t = tree2('^', t, word1(tok, &tok));
continue;
}
blob - f667b84015bca41c032ab585cfbc6dacdb686c54
blob + 4a33d87c1be5a1a1ac0a3400b626c5a25460b746
--- src/cmd/rc/test.rc
+++ src/cmd/rc/test.rc
# x y=z
# x =y
# x -flag=y
+
+>z x | y
+
+# rejected now, was like parens were spaces before.
+# echo Formatting Venti arenas and indices (this takes a while).
+
+
+# echo $STATLINE(1)^$STATLINE(3)' '$STATLINE(2)' '$STATLINE(4)' '$LSLINE(6)