Commit Diff


commit - 47d4646eebac34c0b94951cfcf1b81ed2ca513e1
commit + 3caf5c238a886d06b438ec6d42f2609b8625463f
blob - cccc40585e853313919e5126dcc42fb64de87a41
blob + 1ff84667b59d9fcfb646a3b1b9e9684cef45d775
--- src/cmd/rc/checkparse
+++ src/cmd/rc/checkparse
@@ -9,6 +9,8 @@ fi
 
 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
@@ -102,15 +102,17 @@ pprompt(void)
 	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) {
@@ -120,9 +122,12 @@ skipwhite(void)
 				advance();
 			}
 		}
-		if(c==' ' || c=='\t')
+		if(c==' ' || c=='\t') {
+			skipped = 1;
 			advance();
-		else return;
+		}
+		else
+			return skipped;
 	}
 }
 
@@ -210,7 +215,8 @@ yylex(void)
 		}
 	}
 	inquote = 0;
-	skipwhite();
+	if(skipwhite() && flag['Z'])
+		return SP;
 	switch(c = advance()){
 	case EOF:
 		lastdol = 0;
@@ -231,7 +237,8 @@ yylex(void)
 	case '&':
 		lastdol = 0;
 		if(nextis('&')){
-			skipnl();
+			if(flag['Y'])
+				skipnl();
 			strcpy(tok, "&&");
 			return ANDAND;
 		}
@@ -240,7 +247,8 @@ yylex(void)
 	case '|':
 		lastdol = 0;
 		if(nextis(c)){
-			skipnl();
+			if(flag['Y'])
+				skipnl();
 			strcpy(tok, "||");
 			return OROR;
 		}
@@ -329,7 +337,7 @@ yylex(void)
 		}
 		*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
@@ -20,6 +20,14 @@ static tree*	words(int tok, int *ptok);
 
 static jmp_buf yyjmp;
 
+static int
+dropnl(int tok)
+{
+	while(tok == '\n')
+		tok = yylex();
+	return tok;
+}
+
 static void
 syntax(int tok)
 {
@@ -191,13 +199,11 @@ cmd(int tok, int *ptok)
 		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:
@@ -224,8 +230,7 @@ cmd(int tok, int *ptok)
 				syntax(tok);
 			break;
 		}
-		skipnl();
-		t4 = cmd(yylex(), ptok);
+		t4 = cmd(dropnl(yylex()), ptok);
 		return mung3(t1, t2, t3, t4);
 
 	case WHILE:
@@ -233,16 +238,14 @@ cmd(int tok, int *ptok)
 		//		{$$=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);
@@ -261,7 +264,7 @@ cmd2(int tok, int *ptok)
 	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;
@@ -277,7 +280,7 @@ cmd3(int tok, int *ptok)
 	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
@@ -244,7 +244,10 @@ pcmdu(io *f, tree *t) /* unambiguous */
 				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
@@ -1,4 +1,4 @@
-%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
@@ -36,3 +36,30 @@ $#$x
 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