changeset 9463:d34baf412786

support non-local function lookups in str2func
author Jaroslav Hajek <highegg@gmail.com>
date Mon, 27 Jul 2009 10:39:09 +0200
parents 44e2e568f973
children e598248a060d
files src/ChangeLog src/ov-fcn-handle.cc src/ov-fcn-handle.h src/symtab.cc src/symtab.h
diffstat 5 files changed, 126 insertions(+), 101 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Mon Jul 27 08:34:54 2009 +0200
+++ b/src/ChangeLog	Mon Jul 27 10:39:09 2009 +0200
@@ -1,3 +1,17 @@
+2009-07-27  Jaroslav Hajek  <highegg@gmail.com>
+
+	* symtab.cc (symbol_table::fcn_info::fcn_info_rep::xfind,
+	symbol_table::fcn_info::fcn_info_rep::find,
+	symbol_table::fcn_info::fcn_info_rep::find_function,
+	symbol_table::fcn_info::find,
+	symbol_table::fcn_info::find_function,
+	symbol_table::find, symbol_table::do_find,
+	symbol_table::find_function):
+	Add local_funcs parameter.
+	* symtab.h: Update decls.
+	* ov-fcn-handle.cc (make_fcn_handle): Add local_funcs parameter.
+	* ov-fcn-handle.h: Update decls.
+
 2009-07-24  John W. Eaton  <jwe@octave.org>
 
 	* pt-mat.cc (DO_SINGLE_TYPE_CONCAT_NO_MUTATE): New macro.
--- a/src/ov-fcn-handle.cc	Mon Jul 27 08:34:54 2009 +0200
+++ b/src/ov-fcn-handle.cc	Mon Jul 27 10:39:09 2009 +0200
@@ -1305,7 +1305,7 @@
 }
 
 octave_value
-make_fcn_handle (const std::string& nm)
+make_fcn_handle (const std::string& nm, bool local_funcs)
 {
   octave_value retval;
 
@@ -1438,7 +1438,8 @@
     }
 
   bool handle_ok = false;
-  octave_value f = symbol_table::find_function (tnm);
+  octave_value f = symbol_table::find_function (tnm, octave_value_list (),
+                                                local_funcs);
 
   if (f.is_undefined ())
     {
@@ -1656,17 +1657,21 @@
 DEFUN (str2func, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} str2func (@var{fcn_name})\n\
+@deftypefnx {Built-in Function} {} str2func (@var{fcn_name}, \"global\")\n\
 Return a function handle constructed from the string @var{fcn_name}.\n\
+If the optional \"global\" argument is passed, locally visible functions\n\
+are ignored in the lookup.\n\
 @end deftypefn")
 {
   octave_value retval;
+  int nargin = args.length ();
 
-  if (args.length () == 1)
+  if (nargin == 1 || nargin == 2)
     {
       std::string nm = args(0).string_value ();
 
       if (! error_state)
-	retval = make_fcn_handle (nm);
+	retval = make_fcn_handle (nm, nargin != 2);
       else
 	error ("str2func: expecting string as first argument");
     }
--- a/src/ov-fcn-handle.h	Mon Jul 27 08:34:54 2009 +0200
+++ b/src/ov-fcn-handle.h	Mon Jul 27 10:39:09 2009 +0200
@@ -145,10 +145,11 @@
   // to dispatch at all.
   std::auto_ptr<str_ov_map> disp;
 
-  friend octave_value make_fcn_handle (const std::string &);
+  friend octave_value make_fcn_handle (const std::string &, bool);
 };
 
-extern octave_value make_fcn_handle (const std::string& nm);
+extern octave_value make_fcn_handle (const std::string& nm,
+                                     bool local_funcs = true);
 
 #endif
 
--- a/src/symtab.cc	Mon Jul 27 08:34:54 2009 +0200
+++ b/src/symtab.cc	Mon Jul 27 10:39:09 2009 +0200
@@ -484,9 +484,10 @@
 //   built-in function
 
 octave_value
-symbol_table::fcn_info::fcn_info_rep::find (const octave_value_list& args)
+symbol_table::fcn_info::fcn_info_rep::find (const octave_value_list& args,
+                                            bool local_funcs)
 {
-  octave_value retval = xfind (args);
+  octave_value retval = xfind (args, local_funcs);
 
   if (! retval.is_defined ())
     {
@@ -496,89 +497,93 @@
 
       load_path::update ();
 
-      retval = xfind (args);
+      retval = xfind (args, local_funcs);
     }
 
   return retval;
 }
 
 octave_value
-symbol_table::fcn_info::fcn_info_rep::xfind (const octave_value_list& args)
+symbol_table::fcn_info::fcn_info_rep::xfind (const octave_value_list& args,
+                                             bool local_funcs)
 {
-  // Subfunction.  I think it only makes sense to check for
-  // subfunctions if we are currently executing a function defined
-  // from a .m file.
+  if (local_funcs)
+    {
+      // Subfunction.  I think it only makes sense to check for
+      // subfunctions if we are currently executing a function defined
+      // from a .m file.
+
+      scope_val_iterator r = subfunctions.find (xcurrent_scope);
+
+      octave_function *curr_fcn = 0;
 
-  scope_val_iterator r = subfunctions.find (xcurrent_scope);
+      if (r != subfunctions.end ())
+        {
+          // FIXME -- out-of-date check here.
 
-  octave_function *curr_fcn = 0;
+          return r->second;
+        }
+      else
+        {
+          curr_fcn = octave_call_stack::current ();
 
-  if (r != subfunctions.end ())
-    {
-      // FIXME -- out-of-date check here.
+          if (curr_fcn)
+            {
+              scope_id pscope = curr_fcn->parent_fcn_scope ();
+
+              if (pscope > 0)
+                {
+                  r = subfunctions.find (pscope);
 
-      return r->second;
-    }
-  else
-    {
-      curr_fcn = octave_call_stack::current ();
+                  if (r != subfunctions.end ())
+                    {
+                      // FIXME -- out-of-date check here.
+
+                      return r->second;
+                    }
+                }
+            }
+        }
+
+      // Private function.
+
+      if (! curr_fcn)
+        curr_fcn = octave_call_stack::current ();
 
       if (curr_fcn)
-	{
-	  scope_id pscope = curr_fcn->parent_fcn_scope ();
-
-	  if (pscope > 0)
-	    {
-	      r = subfunctions.find (pscope);
-
-	      if (r != subfunctions.end ())
-		{
-		  // FIXME -- out-of-date check here.
+        {
+          std::string dir_name = curr_fcn->dir_name ();
 
-		  return r->second;
-		}
-	    }
-	}
-    }
+          if (! dir_name.empty ())
+            {
+              str_val_iterator q = private_functions.find (dir_name);
 
-  // Private function.
-
-  if (! curr_fcn)
-    curr_fcn = octave_call_stack::current ();
-
-  if (curr_fcn)
-    {
-      std::string dir_name = curr_fcn->dir_name ();
+              if (q == private_functions.end ())
+                {
+                  octave_value val = load_private_function (dir_name);
 
-      if (! dir_name.empty ())
-	{
-	  str_val_iterator q = private_functions.find (dir_name);
+                  if (val.is_defined ())
+                    return val;
+                }
+              else
+                {
+                  octave_value& fval = q->second;
 
-	  if (q == private_functions.end ())
-	    {
-	      octave_value val = load_private_function (dir_name);
-
-	      if (val.is_defined ())
-		return val;
-	    }
-	  else
-	    {
-	      octave_value& fval = q->second;
+                  if (fval.is_defined ())
+                    out_of_date_check_internal (fval);
 
-	      if (fval.is_defined ())
-		out_of_date_check_internal (fval);
+                  if (fval.is_defined ())
+                    return fval;
+                  else
+                    {
+                      octave_value val = load_private_function (dir_name);
 
-	      if (fval.is_defined ())
-		return fval;
-	      else
-		{
-		  octave_value val = load_private_function (dir_name);
-
-		  if (val.is_defined ())
-		    return val;
-		}
-	    }
-	}
+                      if (val.is_defined ())
+                        return val;
+                    }
+                }
+            }
+        }
     }
 
   // Class constructors.  The class name and function name are the same.
@@ -1030,20 +1035,15 @@
 }
 
 octave_value
-symbol_table::fcn_info::find (const octave_value_list& args)
-{
-  return rep->find (args);
-}
-
-octave_value
 symbol_table::find (const std::string& name, 
                     const octave_value_list& args, 
-                    bool skip_variables)
+                    bool skip_variables,
+                    bool local_funcs)
 {
   symbol_table *inst = get_instance (xcurrent_scope);
 
   return inst
-    ? inst->do_find (name, args, skip_variables)
+    ? inst->do_find (name, args, skip_variables, local_funcs)
     : octave_value ();
 }
 
@@ -1057,7 +1057,8 @@
 
 octave_value
 symbol_table::find_function (const std::string& name,
-                             const octave_value_list& args)
+                             const octave_value_list& args,
+                             bool local_funcs)
 {
   octave_value retval;
 
@@ -1078,13 +1079,14 @@
       size_t pos = name.find_first_of (Vfilemarker);
 
       if (pos == std::string::npos)
-	retval = find (name, args, true);
+	retval = find (name, args, true, local_funcs);
       else
 	{
 	  std::string fcn_scope = name.substr (0, pos);
 	  scope_id stored_scope = xcurrent_scope;
 	  xcurrent_scope = xtop_scope;
-	  octave_value parent = find_function (name.substr(0, pos));
+	  octave_value parent = find_function (name.substr(0, pos),
+                                               octave_value_list (), false);
 
 	  if (parent.is_defined ())
 	    {
@@ -1206,7 +1208,8 @@
 octave_value
 symbol_table::do_find (const std::string& name, 
                        const octave_value_list& args,
-		       bool skip_variables)
+		       bool skip_variables,
+                       bool local_funcs)
 {
   octave_value retval;
 
@@ -1237,12 +1240,12 @@
   fcn_table_iterator p = fcn_table.find (name);
 
   if (p != fcn_table.end ())
-    return p->second.find (args);
+    return p->second.find (args, local_funcs);
   else
     {
       fcn_info finfo (name);
 
-      octave_value fcn = finfo.find (args);
+      octave_value fcn = finfo.find (args, local_funcs);
 
       if (fcn.is_defined ())
 	fcn_table[name] = finfo;
--- a/src/symtab.h	Mon Jul 27 08:34:54 2009 +0200
+++ b/src/symtab.h	Mon Jul 27 10:39:09 2009 +0200
@@ -538,7 +538,7 @@
 
       octave_value load_class_method (const std::string& dispatch_type);
 
-      octave_value find (const octave_value_list& args = octave_value_list ());
+      octave_value find (const octave_value_list& args, bool local_funcs);
 
       octave_value builtin_find (void);
 
@@ -553,9 +553,9 @@
 	return function_on_path.is_defined ();
       }
 
-      octave_value find_function (const octave_value_list& args = octave_value_list ())
+      octave_value find_function (const octave_value_list& args, bool local_funcs)
       {
-	return find (args);
+	return find (args, local_funcs);
       }
 
       void lock_subfunction (scope_id scope)
@@ -718,7 +718,7 @@
 
     private:
 
-      octave_value xfind (const octave_value_list& args);
+      octave_value xfind (const octave_value_list& args, bool local_funcs);
 
       octave_value x_builtin_find (void);
 
@@ -759,7 +759,11 @@
 	delete rep;
     }
 
-    octave_value find (const octave_value_list& args);
+    octave_value find (const octave_value_list& args = octave_value_list (),
+                       bool local_funcs = true)
+    {
+      return rep->find (args, local_funcs);
+    }
 
     octave_value builtin_find (void)
     {
@@ -791,14 +795,10 @@
       return rep->is_user_function_defined ();
     }
 
-    octave_value find_function (void)
+    octave_value find_function (const octave_value_list& args = octave_value_list (),
+                                bool local_funcs = true)
     {
-      return rep->find_function ();
-    }
-
-    octave_value find_function (const octave_value_list& args)
-    {
-      return rep->find_function (args);
+      return rep->find_function (args, local_funcs);
     }
 
     void lock_subfunction (scope_id scope)
@@ -1033,7 +1033,8 @@
   static octave_value
   find (const std::string& name, 
         const octave_value_list& args = octave_value_list (),
-	bool skip_variables = false);
+	bool skip_variables = false,
+        bool local_funcs = true);
 
   static octave_value builtin_find (const std::string& name);
 
@@ -1172,7 +1173,8 @@
 
   static octave_value
   find_function (const std::string& name, 
-                 const octave_value_list& args = octave_value_list ());
+                 const octave_value_list& args = octave_value_list (),
+                 bool local_funcs = true);
 
   static octave_value find_user_function (const std::string& name)
   {
@@ -1973,7 +1975,7 @@
 
   octave_value
   do_find (const std::string& name, const octave_value_list& args,
-           bool skip_variables);
+           bool skip_variables, bool local_funcs);
 
   octave_value do_builtin_find (const std::string& name);