Index: /trunk/src/kmk/Makefile.am
===================================================================
--- /trunk/src/kmk/Makefile.am	(revision 1438)
+++ /trunk/src/kmk/Makefile.am	(revision 1439)
@@ -124,5 +124,5 @@
 	-DCONFIG_WITH_FILE_SIZE \
 	-DCONFIG_WITH_WHICH \
-	-DCONFIG_WITH_EVALCTX \
+	-DCONFIG_WITH_EVALPLUS \
 	-DCONFIG_WITH_MAKE_STATS \
 	-DCONFIG_PRETTY_COMMAND_PRINTING \
Index: /trunk/src/kmk/Makefile.kmk
===================================================================
--- /trunk/src/kmk/Makefile.kmk	(revision 1438)
+++ /trunk/src/kmk/Makefile.kmk	(revision 1439)
@@ -124,5 +124,5 @@
 	CONFIG_WITH_FILE_SIZE \
 	CONFIG_WITH_WHICH \
-	CONFIG_WITH_EVALCTX \
+	CONFIG_WITH_EVALPLUS \
 	CONFIG_WITH_MAKE_STATS \
 	CONFIG_PRETTY_COMMAND_PRINTING \
Index: /trunk/src/kmk/function.c
===================================================================
--- /trunk/src/kmk/function.c	(revision 1438)
+++ /trunk/src/kmk/function.c	(revision 1439)
@@ -1513,5 +1513,5 @@
 
 
-#ifdef CONFIG_WITH_EVALCTX
+#ifdef CONFIG_WITH_EVALPLUS
 /* Same as func_eval except that we push and pop the local variable
    context before evaluating the buffer. */
@@ -1537,5 +1537,37 @@
   return o;
 }
-#endif /* CONFIG_WITH_EVALCTX */
+
+/* A mix of func_eval and func_value, saves memory for the expansion. 
+  This implements both evalval and evalvalctx, the latter has its own
+  variable context just like evalctx. */
+static char *
+func_evalval (char *o, char **argv, const char *funcname)
+{
+  /* Look up the variable.  */
+  struct variable *v = lookup_variable (argv[0], strlen (argv[0]));
+  if (v)
+    {
+      char *buf;
+      unsigned int len;
+      int var_ctx;
+
+      /* Eval the value.  Pop the current variable buffer setting so that the
+         eval'd code can use its own without conflicting. (really necessary?)  */
+
+      install_variable_buffer (&buf, &len);
+      var_ctx = !strcmp(funcname, "evalvalctx");
+      if (var_ctx)
+        push_new_variable_scope ();
+
+      eval_buffer (v->value);
+
+      if (var_ctx)
+        pop_variable_scope ();
+      restore_variable_buffer (buf, len);
+    }
+
+  return o;
+}
+#endif /* CONFIG_WITH_EVALPLUS */
 
 static char *
@@ -3577,6 +3609,10 @@
   { STRING_SIZE_TUPLE("value"),         0,  1,  1,  func_value},
   { STRING_SIZE_TUPLE("eval"),          0,  1,  1,  func_eval},
-#ifdef CONFIG_WITH_EVALCTX
+#ifdef CONFIG_WITH_EVALPLUS
   { STRING_SIZE_TUPLE("evalctx"),       0,  1,  1,  func_evalctx},
+  { STRING_SIZE_TUPLE("evalval"),       0,  1,  0,  func_evalval},
+  { STRING_SIZE_TUPLE("evalvalctx"),    0,  1,  0,  func_evalval},
+  { STRING_SIZE_TUPLE("evalcall"),      1,  0,  1,  func_call},
+  { STRING_SIZE_TUPLE("evalcall2"),     1,  0,  1,  func_call},
 #endif
 #ifdef EXPERIMENTAL
@@ -3817,4 +3853,8 @@
   const struct function_table_entry *entry_p;
   struct variable *v;
+#ifdef CONFIG_WITH_EVALPLUS
+  char *buf;
+  unsigned int len;
+#endif
 
   /* There is no way to define a variable with a space in the name, so strip
@@ -3888,19 +3928,48 @@
     }
 
-  /* Expand the body in the context of the arguments, adding the result to
-     the variable buffer.  */
-
-  v->exp_count = EXP_COUNT_MAX;
-
   saved_args = max_args;
   max_args = i;
-  o = variable_expand_string (o, body, flen+3);
+
+#ifdef CONFIG_WITH_EVALPLUS
+  if (!strcmp (funcname, "call"))
+    {
+#endif
+      /* Expand the body in the context of the arguments, adding the result to
+         the variable buffer.  */
+    
+      v->exp_count = EXP_COUNT_MAX;
+      o = variable_expand_string (o, body, flen+3);
+      v->exp_count = 0;
+
+      o += strlen (o);
+#ifdef CONFIG_WITH_EVALPLUS
+    }
+  else if (!strcmp (funcname, "evalcall"))
+    {
+      /* Evaluate the variable value directly without expanding it first.  */
+
+      install_variable_buffer (&buf, &len);
+      eval_buffer (v->value);
+      restore_variable_buffer (buf, len);
+    }
+  else /* evalcall2: */
+    {
+      /* Expand the body first and then evaluate the output. */
+
+      v->exp_count = EXP_COUNT_MAX;
+      o = variable_expand_string (o, body, flen+3);
+      v->exp_count = 0;
+
+      install_variable_buffer (&buf, &len);
+      eval_buffer (o);
+      restore_variable_buffer (buf, len);
+    }
+#endif /* CONFIG_WITH_EVALPLUS */
+
   max_args = saved_args;
 
-  v->exp_count = 0;
-
   pop_variable_scope ();
 
-  return o + strlen (o);
+  return o;
 }
 
Index: /trunk/src/kmk/variable.c
===================================================================
--- /trunk/src/kmk/variable.c	(revision 1438)
+++ /trunk/src/kmk/variable.c	(revision 1439)
@@ -973,6 +973,8 @@
 #endif
   register struct variable *v;
+#ifndef KMK
   char buf[200];
-#ifdef KMK
+#else
+  char buf[1024];
   const char *envvar;
 #endif
@@ -1042,5 +1044,5 @@
   && defined (CONFIG_WITH_FILE_SIZE) \
   && defined (CONFIG_WITH_WHICH) \
-  && defined (CONFIG_WITH_EVALCTX) \
+  && defined (CONFIG_WITH_EVALPLUS) \
   && defined (CONFIG_WITH_MAKE_STATS) \
   && defined (KMK_HELPERS)
@@ -1060,5 +1062,5 @@
                           " file-size"
                           " which"
-                          " evalctx"
+                          " evalctx evalval evalvalctx evalcall evalcall2"
                           " make-stats"
                           " kb-src-tool kb-obj-base kb-obj-suff kb-src-prop kb-src-one "
@@ -1106,6 +1108,6 @@
   strcat (buf, " which");
 #  endif
-#  if defined (CONFIG_WITH_EVALCTX)
-  strcat (buf, " evalctx");
+#  if defined (CONFIG_WITH_EVALPLUS)
+  strcat (buf, " evalctx evalval evalvalctx evalcall evalcall2");
 #  endif
 #  if defined (CONFIG_WITH_MAKE_STATS)
