diff src/toplev.h @ 5743:a527e0f77aa5

[project @ 2006-04-06 08:20:21 by jwe]
author jwe
date Thu, 06 Apr 2006 08:20:23 +0000
parents 4c8a2e4e0717
children 1c36a2e82266
line wrap: on
line diff
--- a/src/toplev.h	Thu Apr 06 08:15:49 2006 +0000
+++ b/src/toplev.h	Thu Apr 06 08:20:23 2006 +0000
@@ -26,10 +26,12 @@
 
 #include <cstdio>
 
+#include <list>
 #include <string>
 
 class octave_value;
 class octave_value_list;
+class octave_function;
 class octave_user_function;
 class tree_statement_list;
 class charMatrix;
@@ -45,12 +47,6 @@
 // Current command to execute.
 extern tree_statement_list *global_command;
 
-// Pointer to function that is currently being evaluated.
-extern octave_function *curr_function;
-
-// Pointer to caller of curr_function.
-extern octave_function *curr_caller_function;
-
 // Pointer to parent function that is currently being evaluated.
 extern octave_function *curr_parent_function;
 
@@ -61,6 +57,98 @@
 // TRUE means we've processed all the init code and we are good to go.
 extern bool octave_initialized;
 
+class
+octave_call_stack
+{
+protected:
+
+  octave_call_stack (void) : cs () { }
+
+public:
+
+  typedef std::list<octave_function *>::iterator iterator ;
+
+  static bool instance_ok (void)
+  {
+    bool retval = true;
+
+    if (! instance)
+      instance = new octave_call_stack ();
+
+    if (! instance)
+      {
+	::error ("unable to create call stack object!");
+
+	retval = false;
+      }
+
+    return retval;
+  }
+
+  // Current function (top of stack).
+  static octave_function *current (void)
+  {
+    return instance_ok () ? instance->do_current (): 0;
+  }
+
+  // Caller function, may be built-in.
+  static octave_function *caller (void)
+  {
+    return instance_ok () ? instance->do_caller (): 0;
+  }
+
+  // First scripting language function on the stack.
+  static octave_user_function *caller_script (void)
+  {
+    return instance_ok () ? instance->do_caller_script (): 0;
+  }
+
+  static void push (octave_function *f)
+  {
+    if (instance_ok ())
+      instance->do_push (f);
+  }
+
+  static void pop (void)
+  {
+    if (instance_ok ())
+      instance->do_pop ();
+  }
+  
+  // A function for popping the top of the call stack that is suitable
+  // for use as an unwind_protect handler.
+  static void unwind_pop (void *) { pop (); }
+
+  static void clear (void)
+  {
+    if (instance_ok ())
+      instance->do_clear ();
+  }
+  
+private:
+
+  // The current call stack.
+  std::list<octave_function *> cs;
+
+  static octave_call_stack *instance;
+
+  octave_function *do_current (void) { return cs.empty () ? 0 : cs.front (); }
+
+  octave_function *do_caller (void);
+
+  octave_user_function *do_caller_script (void);
+
+  void do_push (octave_function *f) { cs.push_front (f); }
+
+  void do_pop (void)
+  {
+    if (! cs.empty ())
+      cs.pop_front ();
+  }
+
+  void do_clear (void) { cs.clear (); }
+};
+
 #endif
 
 /*