commit - 47d4646eebac34c0b94951cfcf1b81ed2ca513e1
commit + 3caf5c238a886d06b438ec6d42f2609b8625463f
blob - cccc40585e853313919e5126dcc42fb64de87a41
blob + 1ff84667b59d9fcfb646a3b1b9e9684cef45d775
--- src/cmd/rc/checkparse
+++ src/cmd/rc/checkparse
for i in $files
do
- echo '#' $i
- diff <(./o.rc -DY $i 2>&1) <(./o.rc -D $i 2>&1)
+ if ! diff <(./o.rc -DY $i 2>&1) <(./o.rc -D $i 2>&1); then
+ echo '#' $i
+ exit 1
+ fi
done
blob - 0bdbbb4b8845a68489cbbfd841817cf78532f8a2
blob + 5833847988c2b5fa0eab8ac64f3f380575b8a0e1
--- src/cmd/rc/lex.c
+++ src/cmd/rc/lex.c
doprompt = 0;
}
-void
+int
skipwhite(void)
{
- int c;
+ int c, skipped;
+ skipped = 0;
for(;;){
c = nextc();
/* Why did this used to be if(!inquote && c=='#') ?? */
if(c=='#'){
incomm = 1;
+ skipped = 1;
for(;;){
c = nextc();
if(c=='\n' || c==EOF) {
advance();
}
}
- if(c==' ' || c=='\t')
+ if(c==' ' || c=='\t') {
+ skipped = 1;
advance();
- else return;
+ }
+ else
+ return skipped;
}
}
}
}
inquote = 0;
- skipwhite();
+ if(skipwhite() && flag['Z'])
+ return SP;
switch(c = advance()){
case EOF:
lastdol = 0;
case '&':
lastdol = 0;
if(nextis('&')){
- skipnl();
+ if(flag['Y'])
+ skipnl();
strcpy(tok, "&&");
return ANDAND;
}
case '|':
lastdol = 0;
if(nextis(c)){
- skipnl();
+ if(flag['Y'])
+ skipnl();
strcpy(tok, "||");
return OROR;
}
}
*w='\0';
yylval.tree = t;
- if(t->type==PIPE)
+ if(t->type==PIPE && flag['Y'])
skipnl();
if(t->type==REDIR) {
skipwhite();
blob - 6071bdffefb01f52f6fda74521d977abb3f6992d
blob + 466b7da28e02ac00c7dcf005f3d1c04db2d52806
--- src/cmd/rc/parse.c
+++ src/cmd/rc/parse.c
static jmp_buf yyjmp;
+static int
+dropnl(int tok)
+{
+ while(tok == '\n')
+ tok = yylex();
+ return tok;
+}
+
static void
syntax(int tok)
{
tok = yylex();
if(tok == NOT) {
t1 = yylval.tree;
- skipnl();
- t2 = cmd(yylex(), ptok);
+ t2 = cmd(dropnl(yylex()), ptok);
return mung1(t1, t2);
}
t2 = paren(tok);
- skipnl();
- t3 = cmd(yylex(), ptok);
+ t3 = cmd(dropnl(yylex()), ptok);
return mung2(t1, t2, t3);
case FOR:
syntax(tok);
break;
}
- skipnl();
- t4 = cmd(yylex(), ptok);
+ t4 = cmd(dropnl(yylex()), ptok);
return mung3(t1, t2, t3, t4);
case WHILE:
// {$$=mung2($1, $2, $4);}
t1 = yylval.tree;
t2 = paren(yylex());
- skipnl();
- t3 = cmd(yylex(), ptok);
+ t3 = cmd(dropnl(yylex()), ptok);
return mung2(t1, t2, t3);
case SWITCH:
// | SWITCH word {skipnl();} brace
// {$$=tree2(SWITCH, $2, $4);}
t1 = yyword(yylex(), &tok);
- while(tok == '\n')
- tok = yylex();
+ tok = dropnl(tok); // doesn't work in yacc grammar but works here!
t2 = brace(tok);
*ptok = yylex();
return tree2(SWITCH, t1, t2);
t1 = cmd3(tok, &tok);
while(tok == ANDAND || tok == OROR) {
op = tok;
- t2 = cmd3(yylex(), &tok);
+ t2 = cmd3(dropnl(yylex()), &tok);
t1 = tree2(op, t1, t2);
}
*ptok = tok;
t1 = cmd4(tok, &tok);
while(tok == PIPE) {
t2 = yylval.tree;
- t3 = cmd4(yylex(), &tok);
+ t3 = cmd4(dropnl(yylex()), &tok);
t1 = mung2(t2, t1, t3);
}
*ptok = tok;
blob - 26bd883bcd545cc44c7ba45c37ab71ac92bd69e5
blob + cae8473799b10636d8043a14cba7b95a101cfbdd
--- src/cmd/rc/pcmd.c
+++ src/cmd/rc/pcmd.c
pfmt(f, "[%d]", t->fd0);
break;
}
- pfmt(f, "%u %u)", c0, c1);
+ if(t->rtype == HERE)
+ pfmt(f, "HERE %u)", c1);
+ else
+ pfmt(f, "%u %u)", c0, c1);
break;
case '=':
pfmt(f, "(%u=%u %u)", c0, c1, c2);
blob - 5c98ef80c8b00edbc894857b552b5e300552f3a0
blob + e3decd414616d65922bbf5c7025677a6b35a1568
--- src/cmd/rc/syn.y
+++ src/cmd/rc/syn.y
-%term FOR IN WHILE IF NOT TWIDDLE BANG SUBSHELL SWITCH FN
+%term FOR IN WHILE IF NOT TWIDDLE BANG SUBSHELL SWITCH FN SP
%term WORD REDIR REDIRW DUP PIPE SUB
%term SIMPLE ARGLIST WORDS BRACE PAREN PCMD PIPEFD /* not used in syntax */
/* operator priorities -- lowest first */
blob - 8cb11e0f7954cb8cf3493f0a328917fbe95f154b
blob + 5c6581327e689c6efca1708614892dec4b0f2203
--- src/cmd/rc/test.rc
+++ src/cmd/rc/test.rc
x for in while if not ~ ! @ switch fn
x not$y
a;b;c
+if(x)
+y
+if(x)
+{
+y
+}
+if not
+z
+for(x)
+y
+for(x in y)
+z
+while(x)
+y
+# yacc doesn't accept a newline before the brace
+# even though the rule is written as if it would
+switch x {
+}
+switch (x) {
+}
+z
+x &&
+y
+x ||
+y
+x |
+y