[PATCH] zsh_eval_context: add math context

dana <[email protected]>
Newsgroups gmane.comp.shells.zsh.devel
Message-ID <[email protected]>
this adds a 'math' context to zsh_eval_context when a math function is
executed. also adds tests promised in w/54575

dana


diff --git a/Doc/Zsh/params.yo b/Doc/Zsh/params.yo
index 635589be4..790fb9258 100644
--- a/Doc/Zsh/params.yo
+++ b/Doc/Zsh/params.yo
@@ -1082,7 +1082,7 @@ Code specified by the tt(-c) option to the command line that invoked
 the shell.
 )
 item(tt(cmdsubst))(
-Command substitution using of the tt(`)var(...)tt(`),
+Command substitution using the tt(`)var(...)tt(`),
 tt($+LPAR())var(...)tt(RPAR()), tt(${{)var(name)tt(}) var(...)tt(}),
 tt(${|)var(...)tt(}), or tt(${ )var(...)tt( }) constructs.
 )
@@ -1120,6 +1120,11 @@ The tt(>LPAR())var(...)tt(RPAR()) form of process substitution.
 item(tt(loadautofunc))(
 Code read directly from a file to define an autoloaded function.
 )
+item(tt(math))(
+Code executed in the tt($+LPAR()LPAR())var(...)tt(RPAR()RPAR()) or
+tt(LPAR()LPAR())var(...)tt(RPAR()RPAR()) constructs,
+or by the tt(let) builtin.
+)
 item(tt(outsubst))(
 The tt(<LPAR())var(...)tt(RPAR()) form of process substitution.
 )
diff --git a/Src/exec.c b/Src/exec.c
index 2c730b910..22649ae62 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -263,6 +263,11 @@ static int doneps4;
 static char *STTYval;
 static char *blank_env[] = { NULL };
 
+/* total allocated elements in zsh_eval_context array */
+static int zsh_eval_context_len;
+/* number of in-use elements in zsh_eval_context array */
+static int zsh_eval_context_alen;
+
 /* Execution functions. */
 
 static int (*execfuncs[WC_COUNT-WC_CURSH]) (Estate, int) = {
@@ -1241,30 +1246,44 @@ execstring(char *s, int dont_change_job, int exiting, char *context)
     popheap();
 }
 
+/* append a context to the zsh_eval_context array */
+
 /**/
 mod_export void
-execode(Eprog p, int dont_change_job, int exiting, char *context)
+zsh_eval_context_push(char *context)
 {
-    struct estate s;
-    static int zsh_eval_context_len;
-    int alen;
-
     if (!zsh_eval_context_len) {
 	zsh_eval_context_len = 16;
-	alen = 0;
+	zsh_eval_context_alen = 0;
 	zsh_eval_context = (char **)zalloc(zsh_eval_context_len *
 					   sizeof(*zsh_eval_context));
-    } else {
-	alen = arrlen(zsh_eval_context);
-	if (zsh_eval_context_len == alen + 1) {
-	    zsh_eval_context_len *= 2;
-	    zsh_eval_context = zrealloc(zsh_eval_context,
-					zsh_eval_context_len *
-					sizeof(*zsh_eval_context));
-	}
-    }
-    zsh_eval_context[alen] = context;
-    zsh_eval_context[alen+1] = NULL;
+    } else if (zsh_eval_context_len == zsh_eval_context_alen + 1) {
+	zsh_eval_context_len *= 2;
+	zsh_eval_context = zrealloc(zsh_eval_context,
+				    zsh_eval_context_len *
+				    sizeof(*zsh_eval_context));
+    }
+    zsh_eval_context[zsh_eval_context_alen] = context;
+    zsh_eval_context[++zsh_eval_context_alen] = NULL;
+}
+
+/* remove the last context from the zsh_eval_context array */
+
+/**/
+mod_export void
+zsh_eval_context_pop()
+{
+    if (zsh_eval_context_alen)
+	zsh_eval_context[--zsh_eval_context_alen] = NULL;
+}
+
+/**/
+mod_export void
+execode(Eprog p, int dont_change_job, int exiting, char *context)
+{
+    struct estate s;
+
+    zsh_eval_context_push(context);
 
     s.prog = p;
     s.pc = p->prog;
@@ -1279,7 +1298,7 @@ execode(Eprog p, int dont_change_job, int exiting, char *context)
      * zsh_eval_context may have been altered by a recursive
      * call, but that's OK since we're using the global value.
      */
-    zsh_eval_context[alen] = NULL;
+    zsh_eval_context_pop();
 }
 
 /* Execute a simplified command. This is used to execute things that
diff --git a/Src/math.c b/Src/math.c
index d97dae238..811f8a95b 100644
--- a/Src/math.c
+++ b/Src/math.c
@@ -1623,7 +1623,13 @@ mathparse(int pc)
 	    push((noeval ? zero_mnumber : getcvar(yylval)), yylval, 0);
 	    break;
 	case FUNC:
-	    push((noeval ? zero_mnumber : callmathfunc(yylval)), yylval, 0);
+	    if (noeval) {
+		push(zero_mnumber, yylval, 0);
+	    } else {
+		zsh_eval_context_push("math");
+		push(callmathfunc(yylval), yylval, 0);
+		zsh_eval_context_pop();
+	    }
 	    break;
 	case M_INPAR:
 	    mathparse(TOPPREC);
diff --git a/Test/D04parameter.ztst b/Test/D04parameter.ztst
index e192d480d..289512efc 100644
--- a/Test/D04parameter.ztst
+++ b/Test/D04parameter.ztst
@@ -1649,11 +1649,60 @@
    print $zsh_eval_context[1]
    [[ $ZSH_EVAL_CONTEXT = ${(j.:.)zsh_eval_context} ]] || print Not equal!
    (( icontext = ${#zsh_eval_context} + 1 ))
-   contextfn() { print $(print $zsh_eval_context[icontext,-1]); }
+   contextfn() { print -r - $zsh_eval_context[icontext,-1] }
+   functions -M contextfn
    contextfn
+   () { contextfn }
+   () { trap contextfn EXIT }
+   eval contextfn
+   print -r - $( contextfn )
+   print -r - ${ contextfn }
+   : ${| contextfn }
+   (( contextfn(0) ))
+   : $(( contextfn(0) ))
+   let 'contextfn(0)'
+   : /(e*contextfn*)
+   : /(o+contextfn)
+   cat <( contextfn )
+   cat < <( contextfn )
+   cat =( contextfn )
+   : >( contextfn )
+   : > >( contextfn )
+   source <( <<< contextfn )
+   $ZTST_testdir/../Src/zsh -fc 'print -r - $zsh_eval_context'
+   () { () { print -r - $( : $(( contextfn(0) )) ) } }
 0:$ZSH_EVAL_CONTEXT and $zsh_eval_context
 >toplevel
->shfunc cmdsubst
+>shfunc
+>shfunc shfunc
+>trap shfunc
+>eval shfunc
+>cmdsubst shfunc
+>cmdsubst shfunc
+>cmdsubst shfunc
+>math shfunc
+>math shfunc
+>math shfunc
+>globqual shfunc
+>globsort shfunc
+>outsubst shfunc
+>outsubst shfunc
+>equalsubst shfunc
+>insubst shfunc
+>insubst shfunc
+>file shfunc
+>cmdarg
+>shfunc shfunc cmdsubst math shfunc
+
+  (( icontext = ${#zsh_eval_context} + 1 ))
+  contextfn() {
+    print -r - $#zsh_eval_context[icontext,-1] $zsh_eval_context[icontext,-1]
+  }
+  cmd='() { eval contextfn }'
+  repeat 48 cmd="() { $cmd }"
+  eval $cmd
+0:zsh_eval_context resizing
+*>52 eval shfunc * shfunc eval shfunc
 
    foo="123456789"
    print ${foo:3}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.