summary refs log tree commit diff
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2014-10-28 17:22:16 +0800
committerHerbert Xu <herbert@gondor.apana.org.au>2014-10-28 17:22:16 +0800
commit7c245aa8ed33ba5db30eef9369d67036a05b0371 (patch)
treeb9cf64a4db6dd9b17b4c6b265a50966613c965d9
parent[PARSER] Removed unnecessary pungetc on EOF from parser (diff)
downloaddash-7c245aa8ed33ba5db30eef9369d67036a05b0371.tar.gz
dash-7c245aa8ed33ba5db30eef9369d67036a05b0371.zip
[PARSER] Simplify EOF/newline handling in list parser
This patch simplifies the EOF and new handling in the list parser.
In particular, it eliminates a case where we may leave here-documents
unfinished upon EOF.

It also removes special EOF/newline handling from parsecmd.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--ChangeLog1
-rw-r--r--src/parser.c60
2 files changed, 27 insertions, 34 deletions
diff --git a/ChangeLog b/ChangeLog
index 70ccfed..8e0d276 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,7 @@
 2014-10-28  Herbert Xu <herbert@gondor.apana.org.au>
 
 	* Removed unnecessary pungetc on EOF from parser.
+	* Simplify EOF/newline handling in list parser.
 
 2014-10-27  Herbert Xu <herbert@gondor.apana.org.au>
 
diff --git a/src/parser.c b/src/parser.c
index f0c919d..382ddf2 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -135,19 +135,13 @@ static inline int realeofmark(const char *eofmark)
 union node *
 parsecmd(int interact)
 {
-	int t;
-
 	tokpushback = 0;
+	checkkwd = 0;
+	heredoclist = 0;
 	doprompt = interact;
 	if (doprompt)
 		setprompt(doprompt);
 	needprompt = 0;
-	t = readtoken();
-	if (t == TEOF)
-		return NEOF;
-	if (t == TNL)
-		return NULL;
-	tokpushback++;
 	return list(1);
 }
 
@@ -158,11 +152,27 @@ list(int nlflag)
 	union node *n1, *n2, *n3;
 	int tok;
 
-	checkkwd = CHKNL | CHKKWD | CHKALIAS;
-	if (nlflag == 2 && tokendlist[peektoken()])
-		return NULL;
 	n1 = NULL;
 	for (;;) {
+		switch (peektoken()) {
+		case TNL:
+			if (!(nlflag & 1))
+				break;
+			parseheredoc();
+			return n1;
+
+		case TEOF:
+			if (!n1 && (nlflag & 1))
+				n1 = NEOF;
+			parseheredoc();
+			return n1;
+		}
+
+		checkkwd = CHKNL | CHKKWD | CHKALIAS;
+		if (nlflag == 2 && tokendlist[peektoken()])
+			return n1;
+		nlflag |= 2;
+
 		n2 = andor();
 		tok = readtoken();
 		if (tok == TBACKGND) {
@@ -189,29 +199,15 @@ list(int nlflag)
 			n1 = n3;
 		}
 		switch (tok) {
-		case TBACKGND:
-		case TSEMI:
-			tok = readtoken();
-			/* fall through */
 		case TNL:
-			if (tok == TNL) {
-				parseheredoc();
-				if (nlflag == 1)
-					return n1;
-			} else {
-				tokpushback++;
-			}
-			checkkwd = CHKNL | CHKKWD | CHKALIAS;
-			if (tokendlist[peektoken()])
-				return n1;
-			break;
 		case TEOF:
-			if (heredoclist)
-				parseheredoc();
 			tokpushback++;
-			return n1;
+			/* fall through */
+		case TBACKGND:
+		case TSEMI:
+			break;
 		default:
-			if (nlflag == 1)
+			if ((nlflag & 1))
 				synexpect(-1);
 			tokpushback++;
 			return n1;
@@ -1443,10 +1439,6 @@ parsearith: {
 
 #ifdef mkinit
 INCLUDE "parser.h"
-RESET {
-	tokpushback = 0;
-	checkkwd = 0;
-}
 #endif