changeset 7719:87eda1f8faaa

octave_user_code: new base class for octave_user_script and octave_user_function
author John W. Eaton <jwe@octave.org>
date Wed, 16 Apr 2008 22:08:15 -0400
parents 62279ce5654c
children 4e2eafef689c
files src/ChangeLog src/debug.cc src/debug.h src/error.cc src/input.cc src/ov-base.cc src/ov-base.h src/ov-usr-fcn.cc src/ov-usr-fcn.h src/ov.cc src/ov.h src/parse.y src/toplev.cc src/toplev.h
diffstat 14 files changed, 227 insertions(+), 85 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Wed Apr 16 21:50:59 2008 -0400
+++ b/src/ChangeLog	Wed Apr 16 22:08:15 2008 -0400
@@ -1,5 +1,45 @@
 2008-04-16  John W. Eaton  <jwe@octave.org>
 
+	* parse.y (Fautoload, Fmfilename): Call
+	octave_call_stack::caller_user_code, not
+	octave_call_stack::caller_user_script_or_function.
+	* toplev.cc, toplev.h (octave_call_stack::caller_user_code):
+	Rename from octave_call_stack::caller_user_script_or_function.
+	(octave_call_stack::do_caller_user_code): Rename from
+	octave_call_stack::do_caller_user_script_or_function.
+	* ov-usr-fcn.h (class octave_user_code): New class, derived from
+	octave_fucntion.
+	(class octave_user_function, class octave_user_script): Derive
+	from octave_user_code, not octave_function.
+	(octave_user_script::user_code_value,
+	octave_user_function::user_code_value): New functions.
+	* ov.cc (octave_value::user_script_value,
+	octave_value::user_code_value): New functions.
+	* ov.h: Provide decls.
+	(octave_value::is_user_code, octave_value::is_user_script):
+	New functions.
+	* ov-base.cc (octave_base_value::user_script_value,
+	octave_base_value::user_code_value): New virutal functions.
+	* ov-base.h: Provide decls.
+	(octave_base_value::is_user_script, octave_base_value::is_user_code):
+	New virtual functions.
+	* error.cc (verror, pr_where, error_2, warning_1):
+	Call octave_call_stack::caller_user_code instead of
+	octave_call_stack::caller_user_script_or_function
+	* input.cc (get_user_input): Likewise.
+	* debug.h (bp_table::breakpoint_map): Use pointer to
+	octave_user_code instead of octave_user_function.
+	* debug.cc (get_user_code): Rename from get_user_function.
+	Return pointer to octave_user_code instead of octave_user_function.
+	Change all uses.
+	(bp_table::do_add_breakpoint, bp_table::do_remove_breakpoint,
+	bp_table::do_remove_all_breakpoints_in_file,
+	bp_table::do_get_breakpoint_list):
+	Avoid dereferencing invalid pointers.
+	(parse_dbfunction_params): Call
+	octave_call_stack::caller_user_code, not
+	octave_call_stack::caller_user_script_or_function. 
+
 	* load-save.cc (Fsave): Fix continuation character in doc string.
 
 	* pt-walk.h (tree_walker::visit_function_def): New function.
--- a/src/debug.cc	Wed Apr 16 21:50:59 2008 -0400
+++ b/src/debug.cc	Wed Apr 16 22:08:15 2008 -0400
@@ -62,10 +62,10 @@
 // empty, search backward for the first user-defined function in the
 // current call stack.
 
-static octave_user_function *
-get_user_function (const std::string& fname = std::string ())
+static octave_user_code *
+get_user_code (const std::string& fname = std::string ())
 {
-  octave_user_function *dbg_fcn = 0;
+  octave_user_code *dbg_fcn = 0;
 
   if (fname.empty ())
     dbg_fcn = octave_call_stack::caller_user_function ();
@@ -74,7 +74,7 @@
       octave_value fcn = symbol_table::find_function (fname);
 
       if (fcn.is_defined ())
-	dbg_fcn = fcn.user_function_value ();
+	dbg_fcn = fcn.user_code_value ();
     }
 
   return dbg_fcn;
@@ -94,10 +94,10 @@
     return;
 
   // If we are already in a debugging function.
-  if (octave_call_stack::caller_user_function ())
+  if (octave_call_stack::caller_user_code ())
     {
       idx = 0;
-      symbol_name = get_user_function ()->name ();
+      symbol_name = get_user_code ()->name ();
     }
   else if (args(0).is_map ())
     {
@@ -154,24 +154,27 @@
 
   octave_idx_type len = line.size ();
 
-  octave_user_function *dbg_fcn = get_user_function (fname);
+  octave_user_code *dbg_fcn = get_user_code (fname);
 
   if (dbg_fcn)
     {
       tree_statement_list *cmds = dbg_fcn->body ();
 
-      for (int i = 0; i < len; i++)
+      if (cmds)
 	{
-	  const_intmap_iterator p = line.find (i);
-
-	  if (p != line.end ())
+	  for (int i = 0; i < len; i++)
 	    {
-	      int lineno = p->second;
+	      const_intmap_iterator p = line.find (i);
+
+	      if (p != line.end ())
+		{
+		  int lineno = p->second;
 
-	      retval[i] = cmds->set_breakpoint (lineno);
+		  retval[i] = cmds->set_breakpoint (lineno);
 
-	      if (retval[i] != 0)
-		bp_map[fname] = dbg_fcn;
+		  if (retval[i] != 0)
+		    bp_map[fname] = dbg_fcn;
+		}
 	    }
 	}
     }
@@ -197,28 +200,36 @@
     }
   else
     {
-      octave_user_function *dbg_fcn = get_user_function (fname);
+      octave_user_code *dbg_fcn = get_user_code (fname);
+
       if (dbg_fcn)
 	{
 	  tree_statement_list *cmds = dbg_fcn->body ();
-	  octave_value_list results = cmds->list_breakpoints ();
-	  if (results.length () > 0)
+
+	  if (cmds)
 	    {
-	      for (int i = 0; i < len; i++)
+	      octave_value_list results = cmds->list_breakpoints ();
+
+	      if (results.length () > 0)
 		{
-		  const_intmap_iterator p = line.find (i);
-		  
-		  if (p != line.end ())
-		    cmds->delete_breakpoint (p->second);
-		}
-	      results = cmds->list_breakpoints ();
+		  for (int i = 0; i < len; i++)
+		    {
+		      const_intmap_iterator p = line.find (i);
+
+		      if (p != line.end ())
+			cmds->delete_breakpoint (p->second);
+		    }
 
-	      breakpoint_map_iterator it = bp_map.find (fname);
-	      if (results.length () == 0 && it != bp_map.end ())
-		bp_map.erase (it);
+		  results = cmds->list_breakpoints ();
+
+		  breakpoint_map_iterator it = bp_map.find (fname);
+
+		  if (results.length () == 0 && it != bp_map.end ())
+		    bp_map.erase (it);
+		}
+
+	      retval = results.length ();
 	    }
-
-	  retval = results.length ();
 	}
       else
 	error ("remove_breakpoint: unable to find the function requested\n");
@@ -232,24 +243,28 @@
 {
   intmap retval;
 
-  octave_user_function *dbg_fcn = get_user_function (fname);
+  octave_user_code *dbg_fcn = get_user_code (fname);
   
   if (dbg_fcn)
     {
       tree_statement_list *cmds = dbg_fcn->body ();
 
-      octave_value_list bkpts = cmds->list_breakpoints ();
-
-      for (int i = 0; i < bkpts.length (); i++)
+      if (cmds)
 	{
-	  int lineno = static_cast<int> (bkpts(i).int_value ());
-	  cmds->delete_breakpoint (lineno);
-	  retval[i] = lineno;
+	  octave_value_list bkpts = cmds->list_breakpoints ();
+
+	  for (int i = 0; i < bkpts.length (); i++)
+	    {
+	      int lineno = static_cast<int> (bkpts(i).int_value ());
+	      cmds->delete_breakpoint (lineno);
+	      retval[i] = lineno;
+	    }
+
+	  breakpoint_map_iterator it = bp_map.find (fname);
+
+	  if (it != bp_map.end ())
+	    bp_map.erase (it);
 	}
-      
-      breakpoint_map_iterator it = bp_map.find (fname);
-      if (it != bp_map.end ())
-	bp_map.erase (it);
     }
   else
     error ("remove_all_breakpoint_in_file: "
@@ -297,16 +312,23 @@
       if (fname_list.length () == 0
 	  || do_find_bkpt_list (fname_list, it->first) != "")
 	{
-	  octave_value_list bkpts = it->second->body ()->list_breakpoints ();
+	  octave_user_code *f = it->second;
+
+	  tree_statement_list *cmds = f->body ();
 
-	  octave_idx_type len = bkpts.length (); 
+	  if (cmds)
+	    {
+	      octave_value_list bkpts = cmds->list_breakpoints ();
 
-	  bp_table::intmap bkpts_vec;
+	      octave_idx_type len = bkpts.length (); 
+
+	      bp_table::intmap bkpts_vec;
 
-	  for (int i = 0; i < len; i++)
-	    bkpts_vec[i] = bkpts (i).double_value ();
+	      for (int i = 0; i < len; i++)
+		bkpts_vec[i] = bkpts (i).double_value ();
 
-	  retval[it->first] = bkpts_vec;
+	      retval[it->first] = bkpts_vec;
+	    }
 	}
     }
 
@@ -432,7 +454,7 @@
     }
   else
     {
-       octave_user_function *dbg_fcn = get_user_function ();
+       octave_user_code *dbg_fcn = get_user_code ();
        if (dbg_fcn)
 	 {
 	   symbol_name = dbg_fcn->name ();
@@ -498,7 +520,7 @@
 {
   octave_value retval;
 
-  octave_user_function *dbg_fcn = get_user_function ();
+  octave_user_code *dbg_fcn = get_user_code ();
 
   if (dbg_fcn)
     {
@@ -573,7 +595,7 @@
 @end deftypefn")
 {
   octave_value retval;
-  octave_user_function *dbg_fcn;
+  octave_user_code *dbg_fcn;
 
   int nargin = args.length ();
   string_vector argv = args.make_argv ("dbtype");
@@ -583,7 +605,7 @@
       switch (nargin)
 	{
 	case 0: // dbtype
-	  dbg_fcn = get_user_function ();
+	  dbg_fcn = get_user_code ();
 
 	  if (dbg_fcn)
 	    do_dbtype (octave_stdout, dbg_fcn->name (), 0, INT_MAX);
@@ -592,13 +614,13 @@
 	  break;
 
 	case 1: // (dbtype func) || (dbtype start:end)
-	  dbg_fcn = get_user_function (argv[1]);
+	  dbg_fcn = get_user_code (argv[1]);
 
 	  if (dbg_fcn)
 	    do_dbtype (octave_stdout, dbg_fcn->name (), 0, INT_MAX);
 	  else
 	    {
-	      dbg_fcn = get_user_function ();
+	      dbg_fcn = get_user_code ();
 
 	      if (dbg_fcn)
 		{
@@ -629,7 +651,7 @@
 	  break;
 
 	case 2: // (dbtype func start:end) , (dbtype func start)
-	  dbg_fcn = get_user_function (argv[1]);
+	  dbg_fcn = get_user_code (argv[1]);
 
 	  if (dbg_fcn)
 	    {
--- a/src/debug.h	Wed Apr 16 21:50:59 2008 -0400
+++ b/src/debug.h	Wed Apr 16 22:08:15 2008 -0400
@@ -28,7 +28,7 @@
 #include "dRowVector.h"
 
 class octave_value_list;
-class octave_user_function;
+class octave_user_code;
 
 // Interface to breakpoints,.
 
@@ -111,7 +111,7 @@
 
   // Map from function names to function objects for functions
   // containing at least one breakpoint.
-  typedef std::map<std::string, octave_user_function *> breakpoint_map;
+  typedef std::map<std::string, octave_user_code *> breakpoint_map;
 
   typedef breakpoint_map::const_iterator const_breakpoint_map_iterator;
   typedef breakpoint_map::iterator breakpoint_map_iterator;
--- a/src/error.cc	Wed Apr 16 21:50:59 2008 -0400
+++ b/src/error.cc	Wed Apr 16 22:08:15 2008 -0400
@@ -234,8 +234,7 @@
 
       if (tree_statement_stack::current ())
 	{
-	  octave_function *fcn
-	    = octave_call_stack::caller_user_script_or_function ();
+	  octave_user_code *fcn = octave_call_stack::caller_user_code ();
 
 	  if (fcn)
 	    {
@@ -429,8 +428,7 @@
       int l = -1;
       int c = -1;
 
-      octave_function *fcn
-	= octave_call_stack::caller_user_script_or_function ();
+      octave_user_code *fcn = octave_call_stack::caller_user_code ();
 
       if (fcn)
 	{
@@ -494,7 +492,7 @@
 
   if ((interactive || forced_interactive)
       && Vdebug_on_error && init_state == 0
-      && octave_call_stack::caller_user_script_or_function ())
+      && octave_call_stack::caller_user_code ())
     {
       unwind_protect_bool (Vdebug_on_error);
       Vdebug_on_error = false;
@@ -655,7 +653,7 @@
 
       if ((interactive || forced_interactive)
 	  && Vdebug_on_warning
-	  && octave_call_stack::caller_user_script_or_function ())
+	  && octave_call_stack::caller_user_code ())
 	{
 	  unwind_protect_bool (Vdebug_on_warning);
 	  Vdebug_on_warning = false;
--- a/src/input.cc	Wed Apr 16 21:50:59 2008 -0400
+++ b/src/input.cc	Wed Apr 16 22:08:15 2008 -0400
@@ -598,8 +598,7 @@
 
   if (debug)
     {
-      octave_function *caller
-	= octave_call_stack::caller_user_script_or_function ();
+      octave_user_code *caller = octave_call_stack::caller_user_code ();
 
       if (caller)
 	{
--- a/src/ov-base.cc	Wed Apr 16 21:50:59 2008 -0400
+++ b/src/ov-base.cc	Wed Apr 16 22:08:15 2008 -0400
@@ -782,6 +782,28 @@
   return retval;
 }
 
+octave_user_script *
+octave_base_value::user_script_value (bool silent)
+{
+  octave_user_script *retval = 0;
+
+  if (! silent)
+    gripe_wrong_type_arg ("octave_base_value::user_script_value()",
+			  type_name ());
+  return retval;
+}
+
+octave_user_code *
+octave_base_value::user_code_value (bool silent)
+{
+  octave_user_code *retval = 0;
+
+  if (! silent)
+    gripe_wrong_type_arg ("octave_base_value::user_code_value()",
+			  type_name ());
+  return retval;
+}
+
 octave_fcn_handle *
 octave_base_value::fcn_handle_value (bool silent)
 {
--- a/src/ov-base.h	Wed Apr 16 21:50:59 2008 -0400
+++ b/src/ov-base.h	Wed Apr 16 22:08:15 2008 -0400
@@ -51,6 +51,8 @@
 class octave_streamoff;
 class octave_function;
 class octave_user_function;
+class octave_user_script;
+class octave_user_code;
 class octave_fcn_handle;
 class octave_fcn_inline;
 class octave_value_list;
@@ -296,6 +298,8 @@
 
   virtual bool is_user_function (void) const { return false; }
 
+  virtual bool is_user_code (void) const { return false; }
+
   virtual bool is_builtin_function (void) const { return false; }
 
   virtual bool is_dld_function (void) const { return false; }
@@ -399,6 +403,10 @@
 
   virtual octave_user_function *user_function_value (bool silent = false);
 
+  virtual octave_user_script *user_script_value (bool silent = false);
+
+  virtual octave_user_code *user_code_value (bool silent = false);
+
   virtual octave_fcn_handle *fcn_handle_value (bool silent = false);
 
   virtual octave_fcn_inline *fcn_inline_value (bool silent = false);
--- a/src/ov-usr-fcn.cc	Wed Apr 16 21:50:59 2008 -0400
+++ b/src/ov-usr-fcn.cc	Wed Apr 16 22:08:15 2008 -0400
@@ -168,7 +168,7 @@
 octave_user_function::octave_user_function
   (symbol_table::scope_id sid, tree_parameter_list *pl,
    tree_parameter_list *rl, tree_statement_list *cl)
-  : octave_function (std::string (), std::string ()),
+  : octave_user_code (std::string (), std::string ()),
     param_list (pl), ret_list (rl), cmd_list (cl),
     lead_comm (), trail_comm (), file_name (),
     parent_name (), t_parsed (static_cast<time_t> (0)),
--- a/src/ov-usr-fcn.h	Wed Apr 16 21:50:59 2008 -0400
+++ b/src/ov-usr-fcn.h	Wed Apr 16 22:08:15 2008 -0400
@@ -43,24 +43,52 @@
 class tree_va_return_list;
 class tree_walker;
 
+class 
+octave_user_code : public octave_function
+{
+public:
+  octave_user_code (void)
+    : octave_function () { }
+
+  ~octave_user_code (void) { }
+
+  bool is_user_code (void) const { return true; }
+
+  virtual tree_statement_list *body (void) = 0;
+
+protected:
+
+  octave_user_code (const std::string& nm,
+		    const std::string& ds = std::string ())
+    : octave_function (nm, ds) { }
+
+private:
+
+  // No copying!
+
+  octave_user_code (const octave_user_code& f);
+
+  octave_user_code& operator = (const octave_user_code& f);
+};
+
 // Scripts.
 
 class
-octave_user_script : public octave_function
+octave_user_script : public octave_user_code
 {
 public:
 
   octave_user_script (void)
-    : octave_function (), cmd_list (0), file_name () { }
+    : octave_user_code (), cmd_list (0), file_name () { }
 
   octave_user_script (const std::string& fnm, const std::string& nm,
 		      tree_statement_list *cmds,
 		      const std::string& ds = std::string ())
-    : octave_function (nm, ds), cmd_list (cmds), file_name (fnm) { }
+    : octave_user_code (nm, ds), cmd_list (cmds), file_name (fnm) { }
 
   octave_user_script (const std::string& fnm, const std::string& nm,
 		      const std::string& ds = std::string ())
-    : octave_function (nm, ds), cmd_list (0), file_name (fnm) { }
+    : octave_user_code (nm, ds), cmd_list (0), file_name (fnm) { }
 
   ~octave_user_script (void);
 
@@ -68,6 +96,8 @@
 
   octave_user_script *user_script_value (bool = false) { return this; }
 
+  octave_user_code *user_code_value (bool = false) { return this; }
+
   // Scripts and user functions are both considered "scripts" because
   // they are written in Octave's scripting language.
 
@@ -141,7 +171,7 @@
 // User-defined functions.
 
 class
-octave_user_function : public octave_function
+octave_user_function : public octave_user_code
 {
 public:
 
@@ -156,6 +186,8 @@
 
   octave_user_function *user_function_value (bool = false) { return this; }
 
+  octave_user_code *user_code_value (bool = false) { return this; }
+
   octave_user_function *define_param_list (tree_parameter_list *t);
 
   octave_user_function *define_ret_list (tree_parameter_list *t);
--- a/src/ov.cc	Wed Apr 16 21:50:59 2008 -0400
+++ b/src/ov.cc	Wed Apr 16 22:08:15 2008 -0400
@@ -1151,6 +1151,18 @@
   return rep->user_function_value (silent);
 }
 
+octave_user_script *
+octave_value::user_script_value (bool silent)
+{
+  return rep->user_script_value (silent);
+}
+
+octave_user_code *
+octave_value::user_code_value (bool silent)
+{
+  return rep->user_code_value (silent);
+}
+
 octave_fcn_handle *
 octave_value::fcn_handle_value (bool silent)
 {
--- a/src/ov.h	Wed Apr 16 21:50:59 2008 -0400
+++ b/src/ov.h	Wed Apr 16 22:08:15 2008 -0400
@@ -571,6 +571,9 @@
   bool is_user_function (void) const
     { return rep->is_user_function (); }
 
+  bool is_user_code (void) const
+    { return rep->is_user_code (); }
+
   bool is_builtin_function (void) const
     { return rep->is_builtin_function (); }
 
@@ -739,6 +742,10 @@
 
   octave_user_function *user_function_value (bool silent = false);
 
+  octave_user_script *user_script_value (bool silent = false);
+
+  octave_user_code *user_code_value (bool silent = false);
+
   octave_fcn_handle *fcn_handle_value (bool silent = false);
 
   octave_fcn_inline *fcn_inline_value (bool silent = false);
--- a/src/parse.y	Wed Apr 16 21:50:59 2008 -0400
+++ b/src/parse.y	Wed Apr 16 22:08:15 2008 -0400
@@ -3347,19 +3347,21 @@
 
 	  if (! octave_env::absolute_pathname (nm))
 	    {
-	      octave_function *fcn = 
-		octave_call_stack::caller_user_script_or_function ();
+	      octave_user_code *fcn = octave_call_stack::caller_user_code ();
+
 	      bool found = false;
+
 	      if (fcn)
 		{
 		  std::string fname = fcn->fcn_file_name ();
+
 		  if (! fname.empty ())
 		    {
-		      fname = octave_env::make_absolute (fname,
-			octave_env::getcwd ());
-		      fname = fname.substr (0, 
-			fname.find_last_of (file_ops::dir_sep_str) + 1);
+		      fname = octave_env::make_absolute (fname, octave_env::getcwd ());
+		      fname = fname.substr (0, fname.find_last_of (file_ops::dir_sep_str) + 1);
+
 		      file_stat fs (fname + nm);
+
 		      if (fs.exists ())
 			{
 			  nm = fname + nm;
@@ -3479,7 +3481,7 @@
 
   std::string fname;
 
-  octave_function *fcn = octave_call_stack::caller_user_script_or_function ();
+  octave_user_code *fcn = octave_call_stack::caller_user_code ();
 
   if (fcn)
     {
--- a/src/toplev.cc	Wed Apr 16 21:50:59 2008 -0400
+++ b/src/toplev.cc	Wed Apr 16 22:08:15 2008 -0400
@@ -133,18 +133,18 @@
   return retval;
 }
 
-octave_function *
-octave_call_stack::do_caller_user_script_or_function (void)
+octave_user_code *
+octave_call_stack::do_caller_user_code (void)
 {
-  octave_function *retval = 0;
+  octave_user_code *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 ()))
+      if (f && f->is_user_code ())
 	{
-	  retval = f;
+	  retval = dynamic_cast<octave_user_code *> (f);
 	  break;
 	}
     }
--- a/src/toplev.h	Wed Apr 16 21:50:59 2008 -0400
+++ b/src/toplev.h	Wed Apr 16 22:08:15 2008 -0400
@@ -122,9 +122,9 @@
   }
 
   // First user-defined function on the stack.
-  static octave_function *caller_user_script_or_function (void)
+  static octave_user_code *caller_user_code (void)
   {
-    return instance_ok () ? instance->do_caller_user_script_or_function () : 0;
+    return instance_ok () ? instance->do_caller_user_code () : 0;
   }
 
   static void push (octave_function *f)
@@ -171,7 +171,7 @@
 
   octave_user_function *do_caller_user_function (void);
 
-  octave_function *do_caller_user_script_or_function (void);
+  octave_user_code *do_caller_user_code (void);
 
   void do_push (octave_function *f) { cs.push_front (f); }