Module Name:    src
Committed By:   christos
Date:           Thu Mar 31 16:12:09 UTC 2016

Modified Files:
        src/bin/sh: parser.c

Log Message:
This is an internally visible change - no effect visible to the
user is expected. With the previous commits to parser.c, we no
longer need to handle reading here documents in the (massive)
readtoken1() function. That allows its code to be simplified and
made easier to read and understand (several goto's goto goto heaven.
RIP) (from kre@)


To generate a diff of this commit:
cvs rdiff -u -r1.112 -r1.113 src/bin/sh/parser.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/bin/sh/parser.c
diff -u src/bin/sh/parser.c:1.112 src/bin/sh/parser.c:1.113
--- src/bin/sh/parser.c:1.112	Sun Mar 27 10:40:20 2016
+++ src/bin/sh/parser.c	Thu Mar 31 12:12:09 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: parser.c,v 1.112 2016/03/27 14:40:20 christos Exp $	*/
+/*	$NetBSD: parser.c,v 1.113 2016/03/31 16:12:09 christos Exp $	*/
 
 /*-
  * Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)parser.c	8.7 (Berkeley) 5/16/95";
 #else
-__RCSID("$NetBSD: parser.c,v 1.112 2016/03/27 14:40:20 christos Exp $");
+__RCSID("$NetBSD: parser.c,v 1.113 2016/03/31 16:12:09 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -1460,7 +1460,7 @@ parseredir(const char *out,  int c)
 STATIC int
 readtoken1(int firstc, char const *syn, int magicq)
 {
-	int c = firstc;
+	int c;
 	char * out;
 	int len;
 	struct nodelist *bqlist;
@@ -1484,161 +1484,160 @@ readtoken1(int firstc, char const *syn, 
 	parenlevel = 0;
 
 	STARTSTACKSTR(out);
-	loop: {	/* for each line, until end of word */
-		for (;;) {	/* until end of line or end of word */
-			CHECKSTRSPACE(4, out);	/* permit 4 calls to USTPUTC */
-			switch(syntax[c]) {
-			case CNL:	/* '\n' */
-				if (syntax == BASESYNTAX)
-					goto endword;	/* exit outer loop */
-				USTPUTC(c, out);
+
+	for (c = firstc ;; c = pgetc_macro()) {	/* until of token */
+		CHECKSTRSPACE(4, out);	/* permit 4 calls to USTPUTC */
+		switch (syntax[c]) {
+		case CNL:	/* '\n' */
+			if (syntax == BASESYNTAX)
+				break;	/* exit loop */
+			USTPUTC(c, out);
+			plinno++;
+			if (doprompt)
+				setprompt(2);
+			else
+				setprompt(0);
+			continue;
+
+		case CWORD:
+			USTPUTC(c, out);
+			continue;
+		case CCTL:
+			if (!magicq || ISDBLQUOTE())
+				USTPUTC(CTLESC, out);
+			USTPUTC(c, out);
+			continue;
+		case CBACK:	/* backslash */
+			c = pgetc();
+			if (c == PEOF) {
+				USTPUTC('\\', out);
+				pungetc();
+				continue;
+			}
+			if (c == '\n') {
 				plinno++;
 				if (doprompt)
 					setprompt(2);
 				else
 					setprompt(0);
-				c = pgetc();
-				goto loop;		/* continue outer loop */
-			case CWORD:
-				USTPUTC(c, out);
-				break;
-			case CCTL:
-				if (!magicq || ISDBLQUOTE())
-					USTPUTC(CTLESC, out);
-				USTPUTC(c, out);
-				break;
-			case CBACK:	/* backslash */
-				c = pgetc();
-				if (c == PEOF) {
-					USTPUTC('\\', out);
-					pungetc();
-					break;
-				}
-				if (c == '\n') {
-					plinno++;
-					if (doprompt)
-						setprompt(2);
-					else
-						setprompt(0);
-					break;
-				}
-				quotef = 1;
-				if (ISDBLQUOTE() && c != '\\' &&
-				    c != '`' && c != '$' &&
-				    (c != '"' || magicq))
-					USTPUTC('\\', out);
-				if (SQSYNTAX[c] == CCTL)
-					USTPUTC(CTLESC, out);
-				else if (!magicq) {
-					USTPUTC(CTLQUOTEMARK, out);
-					USTPUTC(c, out);
-					if (varnest != 0)
-						USTPUTC(CTLQUOTEEND, out);
-					break;
-				}
+				continue;
+			}
+			quotef = 1;	/* current token is quoted */
+			if (ISDBLQUOTE() && c != '\\' && c != '`' &&
+			    c != '$' && (c != '"' || magicq))
+				USTPUTC('\\', out);
+			if (SQSYNTAX[c] == CCTL)
+				USTPUTC(CTLESC, out);
+			else if (!magicq) {
+				USTPUTC(CTLQUOTEMARK, out);
 				USTPUTC(c, out);
-				break;
-			case CSQUOTE:
-				if (syntax != SQSYNTAX) {
-					if (!magicq)
-						USTPUTC(CTLQUOTEMARK, out);
-					quotef = 1;
-					TS_PUSH();
-					syntax = SQSYNTAX;
-					quoted = SQ;
-					break;
-				}
-				if (magicq && arinest == 0 && varnest == 0) {
-					/* Ignore inside quoted here document */
-					USTPUTC(c, out);
-					break;
-				}
-				/* End of single quotes... */
-				TS_POP();
-				if (syntax == BASESYNTAX && varnest != 0)
+				if (varnest != 0)
 					USTPUTC(CTLQUOTEEND, out);
-				break;
-			case CDQUOTE:
-				if (magicq && arinest == 0 && varnest == 0) {
-					/* Ignore inside here document */
-					USTPUTC(c, out);
-					break;
-				}
+				continue;
+			}
+			USTPUTC(c, out);
+			continue;
+		case CSQUOTE:
+			if (syntax != SQSYNTAX) {
+				if (!magicq)
+					USTPUTC(CTLQUOTEMARK, out);
 				quotef = 1;
-				if (arinest) {
-					if (ISDBLQUOTE()) {
-						TS_POP();
-					} else {
-						TS_PUSH();
-						syntax = DQSYNTAX;
-						SETDBLQUOTE();
-						USTPUTC(CTLQUOTEMARK, out);
-					}
-					break;
-				}
-				if (magicq)
-					break;
+				TS_PUSH();
+				syntax = SQSYNTAX;
+				quoted = SQ;
+				continue;
+			}
+			if (magicq && arinest == 0 && varnest == 0) {
+				/* Ignore inside quoted here document */
+				USTPUTC(c, out);
+				continue;
+			}
+			/* End of single quotes... */
+			TS_POP();
+			if (syntax == BASESYNTAX && varnest != 0)
+				USTPUTC(CTLQUOTEEND, out);
+			continue;
+		case CDQUOTE:
+			if (magicq && arinest == 0 && varnest == 0) {
+				/* Ignore inside here document */
+				USTPUTC(c, out);
+				continue;
+			}
+			quotef = 1;
+			if (arinest) {
 				if (ISDBLQUOTE()) {
 					TS_POP();
-					if (varnest != 0)
-						USTPUTC(CTLQUOTEEND, out);
 				} else {
 					TS_PUSH();
 					syntax = DQSYNTAX;
 					SETDBLQUOTE();
 					USTPUTC(CTLQUOTEMARK, out);
 				}
-				break;
-			case CVAR:	/* '$' */
-				PARSESUB();		/* parse substitution */
-				break;
-			case CENDVAR:	/* CLOSEBRACE */
-				if (varnest > 0 && !ISDBLQUOTE()) {
-					TS_POP();
-					USTPUTC(CTLENDVAR, out);
-				} else {
-					USTPUTC(c, out);
-				}
-				break;
-			case CLP:	/* '(' in arithmetic */
-				parenlevel++;
+				continue;
+			}
+			if (magicq)
+				continue;
+			if (ISDBLQUOTE()) {
+				TS_POP();
+				if (varnest != 0)
+					USTPUTC(CTLQUOTEEND, out);
+			} else {
+				TS_PUSH();
+				syntax = DQSYNTAX;
+				SETDBLQUOTE();
+				USTPUTC(CTLQUOTEMARK, out);
+			}
+			continue;
+		case CVAR:	/* '$' */
+			PARSESUB();		/* parse substitution */
+			continue;
+		case CENDVAR:	/* CLOSEBRACE */
+			if (varnest > 0 && !ISDBLQUOTE()) {
+				TS_POP();
+				USTPUTC(CTLENDVAR, out);
+			} else {
 				USTPUTC(c, out);
-				break;
-			case CRP:	/* ')' in arithmetic */
-				if (parenlevel > 0) {
-					USTPUTC(c, out);
-					--parenlevel;
-				} else {
-					if (pgetc() == ')') {
-						if (--arinest == 0) {
-							TS_POP();
-							USTPUTC(CTLENDARI, out);
-						} else
-							USTPUTC(')', out);
-					} else {
-						/*
-						 * unbalanced parens
-						 *  (don't 2nd guess - no error)
-						 */
-						pungetc();
+			}
+			continue;
+		case CLP:	/* '(' in arithmetic */
+			parenlevel++;
+			USTPUTC(c, out);
+			continue;;
+		case CRP:	/* ')' in arithmetic */
+			if (parenlevel > 0) {
+				USTPUTC(c, out);
+				--parenlevel;
+			} else {
+				if (pgetc() == ')') {
+					if (--arinest == 0) {
+						TS_POP();
+						USTPUTC(CTLENDARI, out);
+					} else
 						USTPUTC(')', out);
-					}
+				} else {
+					/*
+					 * unbalanced parens
+					 *  (don't 2nd guess - no error)
+					 */
+					pungetc();
+					USTPUTC(')', out);
 				}
-				break;
-			case CBQUOTE:	/* '`' */
-				out = parsebackq(stack, out, &bqlist, 1);
-				break;
-			case CEOF:
-				goto endword;		/* exit outer loop */
-			default:
-				if (varnest == 0 && !ISDBLQUOTE())
-					goto endword;	/* exit outer loop */
-				USTPUTC(c, out);
 			}
-			c = pgetc_macro();
+			continue;
+		case CBQUOTE:	/* '`' */
+			out = parsebackq(stack, out, &bqlist, 1);
+			continue;
+		case CEOF:		/* --> c == PEOF */
+			break;		/* will exit loop */
+		default:
+			if (varnest == 0 && !ISDBLQUOTE())
+				break;	/* exit loop */
+			USTPUTC(c, out);
+			continue;
 		}
+		break;	/* break from switch -> break from for loop too */
 	}
-endword:
+
 	if (syntax == ARISYNTAX) {
 		cleanup_state_stack(stack);
 		synerror("Missing '))'");
@@ -1653,13 +1652,14 @@ endword:
 		/* { */
 		synerror("Missing '}'");
 	}
+
 	USTPUTC('\0', out);
 	len = out - stackblock();
 	out = stackblock();
+
 	if (!magicq) {
 		if ((c == '<' || c == '>')
-		 && quotef == 0
-		 && (*out == '\0' || is_number(out))) {
+		 && quotef == 0 && (*out == '\0' || is_number(out))) {
 			parseredir(out, c);
 			cleanup_state_stack(stack);
 			return lasttoken = TREDIR;
@@ -1667,6 +1667,7 @@ endword:
 			pungetc();
 		}
 	}
+
 	quoteflag = quotef;
 	backquotelist = bqlist;
 	grabstackblock(len);

Reply via email to