changeset 5744:1c36a2e82266

[project @ 2006-04-06 19:38:34 by jwe]
author jwe
date Thu, 06 Apr 2006 19:38:35 +0000
parents a527e0f77aa5
children 0559ebb94bf0
files src/ChangeLog src/debug.cc src/error.cc src/input.cc src/ov-fcn.h src/ov-usr-fcn.cc src/ov-usr-fcn.h src/parse.y src/toplev.cc src/toplev.h src/variables.cc
diffstat 11 files changed, 161 insertions(+), 50 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,7 +1,10 @@
 2006-04-06  John W. Eaton  <jwe@octave.org>
 
-	* parse.y (Fmfilename): If no function is on the call stack check
-	to see whether we are reading a script file.
+	* parse.y (parse_and_execute, parse_fcn_file):
+	Create octave_script_function object and push it on the call stack. 
+
+	* parse.y (Fmfilename): Check for script or user function file on
+	call stack.
 
 	* ov-builtin.cc (octave_builtin::do_multi_index_op):
 	Use octave_call_stack instead of curr_function to save pointer to
@@ -34,12 +37,15 @@
 	* parse.y (Fmfilename): Likewise.  Check for scripting language
 	caller, not any calling function.
 
-2006-04-05  John W. Eaton  <jwe@octave.org>
+	* ov-usr-fcn.h (octave_user_script): New class.
+	* ov-fcn.h (octave_function::is_user_script): New virtual function.
 
 	* toplev.h, toplev.cc (octave_call_stack): New class.
 
 	* debug.cc (Fdbwhere): Use get_user_function here.
 
+2006-04-05  John W. Eaton  <jwe@octave.org>
+
 	* Makefile.in (mk-pkg-add): Use mfilename to simplify.
 	(PKG_ADD): Don't pass --prefix arg to mk-pkg-add.
 	(PKG_ADD.inst): Delete target.
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -59,7 +59,7 @@
   octave_user_function *dbg_fcn = 0;
 
   if (fname == "")
-    dbg_fcn = octave_call_stack::caller_script ();
+    dbg_fcn = octave_call_stack::caller_user_function ();
   else
     {
       symbol_record *ptr = curr_sym_tab->lookup (fname);
--- a/src/error.cc
+++ b/src/error.cc
@@ -378,7 +378,8 @@
       int l = -1;
       int c = -1;
 
-      octave_user_function *fcn = octave_call_stack::caller_script ();
+      octave_function *fcn
+	= octave_call_stack::caller_user_script_or_function ();
 
       if (fcn)
 	{
@@ -545,7 +546,7 @@
 
       if ((interactive || forced_interactive)
 	  && Vdebug_on_warning
-	  && octave_call_stack::caller_script ())
+	  && octave_call_stack::caller_user_script_or_function ())
 	{
 	  unwind_protect_bool (Vdebug_on_warning);
 	  Vdebug_on_warning = false;
@@ -584,7 +585,7 @@
 
   if ((interactive || forced_interactive)
       && Vdebug_on_error && init_state == 0
-      && octave_call_stack::caller_script ())
+      && octave_call_stack::caller_user_script_or_function ())
     {
       unwind_protect_bool (Vdebug_on_error);
       Vdebug_on_error = false;
--- a/src/input.cc
+++ b/src/input.cc
@@ -547,7 +547,8 @@
 
   if (debug)
     {
-      octave_user_function *caller = octave_call_stack::caller_script ();
+      octave_function *caller
+	= octave_call_stack::caller_user_script_or_function ();
 
       if (caller)
 	{
--- a/src/ov-fcn.h
+++ b/src/ov-fcn.h
@@ -70,6 +70,8 @@
 
   virtual bool is_nested_function (void) const { return false; }
 
+  virtual bool is_user_script (void) const { return false; }
+
   virtual bool is_user_function (void) const { return false; }
 
   virtual bool takes_varargs (void) const { return false; }
--- a/src/ov-usr-fcn.cc
+++ b/src/ov-usr-fcn.cc
@@ -59,6 +59,12 @@
 				     "user-defined function",
 				     "user-defined function");
 
+DEFINE_OCTAVE_ALLOCATOR (octave_user_script);
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_user_script,
+				     "user-defined script",
+				     "user-defined script");
+
 // Ugh.  This really needs to be simplified (code/data?
 // extrinsic/intrinsic state?).
 
@@ -746,7 +752,7 @@
 
   if (nargin == 0)
     {
-      octave_function *fcn = octave_call_stack::caller_script ();
+      octave_user_function *fcn = octave_call_stack::caller_user_function ();
 
       if (fcn)
 	{
@@ -790,7 +796,7 @@
 
   if (nargin == 0)
     {
-      octave_function *fcn = octave_call_stack::caller_script ();
+      octave_user_function *fcn = octave_call_stack::caller_user_function ();
 
       if (fcn)
 	{
@@ -836,7 +842,7 @@
 
   if (nargin == 1)
     {
-      octave_function *fcn = octave_call_stack::caller_script ();
+      octave_user_function *fcn = octave_call_stack::caller_user_function ();
 
       if (fcn)
 	{
--- a/src/ov-usr-fcn.h
+++ b/src/ov-usr-fcn.h
@@ -44,7 +44,47 @@
 class symbol_table;
 class symbol_record;
 
-// Builtin functions.
+// Scripts.
+
+class
+octave_user_script : public octave_function
+{
+public:
+
+  octave_user_script (void) { }
+
+  octave_user_script (const std::string& fnm, const std::string& nm,
+		      const std::string& ds)
+    : octave_function (nm, ds), file_name (fnm) { }
+
+  ~octave_user_script (void) { }
+
+  // Scripts and user functions are both considered "scripts" because
+  // they are written in Octave's scripting language.
+
+  bool is_user_script (void) const { return true; }
+
+  void stash_fcn_file_name (const std::string& nm) { file_name = nm; }
+
+  std::string fcn_file_name (void) const { return file_name; }
+
+private:
+
+  // The name of the file we parsed
+  std::string file_name;
+
+  // No copying!
+
+  octave_user_script (const octave_user_script& f);
+
+  octave_user_script& operator = (const octave_user_script& f);
+
+  DECLARE_OCTAVE_ALLOCATOR
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+// User-defined functions.
 
 class
 octave_user_function : public octave_function
--- a/src/parse.y
+++ b/src/parse.y
@@ -2997,6 +2997,10 @@
     {
       unwind_protect::add (safe_fclose, f);
 
+      octave_user_script *script = new octave_user_script (s, s, "");
+      octave_call_stack::push (script);
+      unwind_protect::add (octave_call_stack::unwind_pop_script, 0);
+
       unwind_protect_int (input_line_number);
       unwind_protect_int (current_input_column);
 
@@ -3377,6 +3381,10 @@
 
 	  bind_builtin_variable ("current_script_file_name", ff);
 
+	  octave_user_script *script = new octave_user_script (ff, ff, "");
+	  octave_call_stack::push (script);
+	  unwind_protect::add (octave_call_stack::unwind_pop_script, 0);
+
 	  parse_and_execute (ffile);
 
 	  script_file_executed = true;
@@ -3619,29 +3627,9 @@
 	}
     }
 
-  // XXX FIXME XXX -- the logic below fails for the following
-  // situation, because script files are not functions that can be
-  // entered into the call stack.
-  //
-  // foo.m:
-  // -----
-  //   function foo ()
-  //     bar;
-  //
-  // bar.m:
-  // -----
-  //   mfilename ();
-  //
-  // foo ()
-  //    ==> foo
-  //
-  // though it should report "bar".  Perhaps we need a dummy function
-  // object that can be used for scripts to at least hold file names
-  // and some other information so we could store it on the call stack.
-
   std::string fname;
 
-  octave_user_function *fcn = octave_call_stack::caller_script ();
+  octave_function *fcn = octave_call_stack::caller_user_script_or_function ();
 
   if (fcn)
     {
@@ -3650,8 +3638,6 @@
       if (fname.empty ())
         fname = fcn->name ();
     }
-  else if (reading_script_file)
-    fname = curr_fcn_file_full_name;
 
   if (arg == "fullpathext")
     retval = fname;
--- a/src/toplev.cc
+++ b/src/toplev.cc
@@ -109,8 +109,27 @@
   return retval;
 }
 
+octave_user_script *
+octave_call_stack::do_caller_user_script (void)
+{
+  octave_user_script *retval = 0;
+
+  for (iterator p = cs.begin (); p != cs.end (); p++)
+    {
+      octave_function *f = *p;
+
+      if (f && f->is_user_script ())
+	{
+	  retval = dynamic_cast<octave_user_script *> (f);
+	  break;
+	}
+    }
+
+  return retval;
+}
+
 octave_user_function *
-octave_call_stack::do_caller_script (void)
+octave_call_stack::do_caller_user_function (void)
 {
   octave_user_function *retval = 0;
 
@@ -128,6 +147,34 @@
   return retval;
 }
 
+octave_function *
+octave_call_stack::do_caller_user_script_or_function (void)
+{
+  octave_function *retval = 0;
+
+  for (iterator p = cs.begin (); p != cs.end (); p++)
+    {
+      octave_function *f = *p;
+
+      if (f && (f->is_user_script () || f->is_user_function ()))
+	{
+	  retval = f;
+	  break;
+	}
+    }
+
+  return retval;
+}
+
+void
+octave_call_stack::unwind_pop_script (void *)
+{
+  octave_function *f = top ();
+  pop ();
+  assert (f && f->is_user_script ());
+  delete f;
+}
+
 static void
 recover_from_exception (void)
 {
--- a/src/toplev.h
+++ b/src/toplev.h
@@ -32,7 +32,7 @@
 class octave_value;
 class octave_value_list;
 class octave_function;
-class octave_user_function;
+class octave_user_script;
 class tree_statement_list;
 class charMatrix;
 
@@ -86,10 +86,7 @@
   }
 
   // Current function (top of stack).
-  static octave_function *current (void)
-  {
-    return instance_ok () ? instance->do_current (): 0;
-  }
+  static octave_function *current (void) { return top (); }
 
   // Caller function, may be built-in.
   static octave_function *caller (void)
@@ -97,10 +94,22 @@
     return instance_ok () ? instance->do_caller (): 0;
   }
 
-  // First scripting language function on the stack.
-  static octave_user_function *caller_script (void)
+  // First script on the stack.
+  static octave_user_script *caller_script (void)
   {
-    return instance_ok () ? instance->do_caller_script (): 0;
+    return instance_ok () ? instance->do_caller_user_script (): 0;
+  }
+
+  // First user-defined function on the stack.
+  static octave_user_function *caller_user_function (void)
+  {
+    return instance_ok () ? instance->do_caller_user_function (): 0;
+  }
+
+  // First user-defined function on the stack.
+  static octave_function *caller_user_script_or_function (void)
+  {
+    return instance_ok () ? instance->do_caller_user_script_or_function (): 0;
   }
 
   static void push (octave_function *f)
@@ -109,6 +118,11 @@
       instance->do_push (f);
   }
 
+  static octave_function *top (void)
+  {
+    return instance_ok () ? instance->do_top (): 0;
+  }
+
   static void pop (void)
   {
     if (instance_ok ())
@@ -119,6 +133,10 @@
   // for use as an unwind_protect handler.
   static void unwind_pop (void *) { pop (); }
 
+  // A function for popping an octave_user_script from the top of the
+  // call stack that is suitable for use as an unwind_protect handler.
+  static void unwind_pop_script (void *);
+
   static void clear (void)
   {
     if (instance_ok ())
@@ -132,14 +150,18 @@
 
   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);
+  octave_user_script *do_caller_user_script (void);
+
+  octave_user_function *do_caller_user_function (void);
+
+  octave_function *do_caller_user_script_or_function (void);
 
   void do_push (octave_function *f) { cs.push_front (f); }
 
+  octave_function *do_top (void) { return cs.empty () ? 0 : cs.front (); }
+
   void do_pop (void)
   {
     if (! cs.empty ())
--- a/src/variables.cc
+++ b/src/variables.cc
@@ -1946,7 +1946,7 @@
     }
   else if (args.length () == 0)
     {
-      octave_user_function *fcn = octave_call_stack::caller_script ();
+      octave_user_function *fcn = octave_call_stack::caller_user_function ();
 
       if (fcn)
         mlock (fcn->name ());
@@ -1980,7 +1980,7 @@
     }
   else if (args.length () == 0)
     {
-      octave_user_function *fcn = octave_call_stack::caller_script ();
+      octave_user_function *fcn = octave_call_stack::caller_user_function ();
 
       if (fcn)
         mlock (fcn->name ());
@@ -2015,7 +2015,7 @@
     }
   else if (args.length () == 0)
     {
-      octave_user_function *fcn = octave_call_stack::caller_script ();
+      octave_user_function *fcn = octave_call_stack::caller_user_function ();
 
       if (fcn)
         retval = mislocked (fcn->name ());