Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

[PATCH] zsh_eval_context: add math context



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}




Messages sorted by: Reverse Date, Date, Thread, Author