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);
 }
 
 
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to