svn commit: r228013 - head/bin/sh

Jilles Tjoelker jilles at FreeBSD.org
Sat Nov 26 23:28:32 UTC 2011


Author: jilles
Date: Sat Nov 26 23:28:31 2011
New Revision: 228013
URL: http://svn.freebsd.org/changeset/base/228013

Log:
  sh: Reduce one level of evaltree() recursion when executing 'case'.
  Free expanded case text before executing commands.
  Remove impossible evalskip checks (expanding an argument cannot set
  evalskip anymore since $(break) and the like are properly executed in a
  subshell environment).

Modified:
  head/bin/sh/eval.c

Modified: head/bin/sh/eval.c
==============================================================================
--- head/bin/sh/eval.c	Sat Nov 26 23:27:41 2011	(r228012)
+++ head/bin/sh/eval.c	Sat Nov 26 23:28:31 2011	(r228013)
@@ -89,7 +89,7 @@ int oexitstatus;		/* saved exit status *
 
 static void evalloop(union node *, int);
 static void evalfor(union node *, int);
-static void evalcase(union node *, int);
+static union node *evalcase(union node *, int);
 static void evalsubshell(union node *, int);
 static void evalredir(union node *, int);
 static void expredir(union node *);
@@ -256,7 +256,7 @@ evaltree(union node *n, int flags)
 			evalfor(n, flags & ~EV_EXIT);
 			break;
 		case NCASE:
-			evalcase(n, flags);
+			next = evalcase(n, flags);
 			break;
 		case NDEFUN:
 			defun(n->narg.text, n->narg.next);
@@ -370,7 +370,7 @@ out:
 
 
 
-static void
+static union node *
 evalcase(union node *n, int flags)
 {
 	union node *cp;
@@ -383,26 +383,24 @@ evalcase(union node *n, int flags)
 	oexitstatus = exitstatus;
 	exitstatus = 0;
 	expandarg(n->ncase.expr, &arglist, EXP_TILDE);
-	for (cp = n->ncase.cases ; cp && evalskip == 0 ; cp = cp->nclist.next) {
+	for (cp = n->ncase.cases ; cp ; cp = cp->nclist.next) {
 		for (patp = cp->nclist.pattern ; patp ; patp = patp->narg.next) {
 			if (casematch(patp, arglist.list->text)) {
+				popstackmark(&smark);
 				while (cp->nclist.next &&
 				    cp->type == NCLISTFALLTHRU) {
-					if (evalskip != 0)
-						break;
 					evaltree(cp->nclist.body,
 					    flags & ~EV_EXIT);
+					if (evalskip != 0)
+						return (NULL);
 					cp = cp->nclist.next;
 				}
-				if (evalskip == 0) {
-					evaltree(cp->nclist.body, flags);
-				}
-				goto out;
+				return (cp->nclist.body);
 			}
 		}
 	}
-out:
 	popstackmark(&smark);
+	return (NULL);
 }
 
 


More information about the svn-src-head mailing list