changeset 29350:9ae39daf5ff5

maint: merge stable to default.
author John W. Eaton <jwe@octave.org>
date Thu, 04 Feb 2021 10:11:00 -0500
parents fe21f065fc23 (current diff) 6f6b5f2e5d4d (diff)
children 326a7ca62c43
files libinterp/corefcn/call-stack.cc
diffstat 2 files changed, 55 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/call-stack.cc	Wed Feb 03 16:30:53 2021 -0800
+++ b/libinterp/corefcn/call-stack.cc	Thu Feb 04 10:11:00 2021 -0500
@@ -618,11 +618,12 @@
   {
     size_t start = find_current_user_frame ();
 
-    // FIXME: is this supposed to be an error?
-    if (start == 0)
-      error ("already at top level");
+    std::shared_ptr<stack_frame> caller_frame = m_cs[start]->static_link ();
 
-    m_curr_frame = dbupdown (start, -1, false);
+    // Allow evalin ('caller', ...) to work when called from the
+    // top-level prompt.
+
+    m_curr_frame = caller_frame ? caller_frame->index () : 0;
   }
 
   void call_stack::goto_base_frame (void)
--- a/test/eval-command.tst	Wed Feb 03 16:30:53 2021 -0800
+++ b/test/eval-command.tst	Thu Feb 04 10:11:00 2021 -0500
@@ -159,3 +159,53 @@
 %! f4a ();
 %! assert (sigma_call, "function");
 %! clear -global sigma_call
+
+%!function r = f_eval_fun ()
+%!  evalin_value = "this is f_eval_fun";
+%!  r = evalin ("caller", "evalin_value");
+%!endfunction
+%!function r = g_eval_fun ()
+%!  evalin_value = "this is g_eval_fun";
+%!  r = evalin ("caller", "f_eval_fun ()");
+%!endfunction
+%!function r = h_eval_fun ()
+%!  evalin_value = "this is h_eval_fun";
+%!  r = f_eval_fun ();
+%!endfunction
+
+%!shared evalin_value
+%! evalin_value = "this is the caller";
+%!assert <59847> (f_eval_fun (), "this is the caller");
+%!assert <59847> (g_eval_fun (), "this is the caller");
+%!assert <59847> (h_eval_fun (), "this is h_eval_fun");
+
+%!function r = f_asgn_fun ()
+%!  asgnin_value = "this is f_asgn_fun";
+%!  assignin ("caller", "asgnin_value", "f value");
+%!  r = asgnin_value;
+%!endfunction
+%!function r = g_asgn_fun ()
+%!  asgnin_value = "this is g_asgn_fun";
+%!  evalin ("caller", "f_asgn_fun ();");
+%!  r = asgnin_value;
+%!endfunction
+%!function r = h_asgn_fun ()
+%!  asgnin_value = "this is h_asgn_fun";
+%!  f_asgn_fun ();
+%!  r = asgnin_value;
+%!endfunction
+
+%!test <59847>
+%! asgnin_value = "this is the caller";
+%! assert (f_asgn_fun (), "this is f_asgn_fun");
+%! assert (asgnin_value, "f value");
+
+%!test <59847>
+%! asgnin_value = "this is the caller";
+%! assert (g_asgn_fun (), "this is g_asgn_fun");
+%! assert (asgnin_value, "f value");
+
+%!test <59847>
+%! asgnin_value = "this is the caller";
+%! assert (h_asgn_fun (), "f value");
+%! assert (asgnin_value, "this is the caller");