changeset 22974:ecc5eeada8dc

Don't mark nested functions in primary function as subfunctions. * help.cc (Flocalfunctions): Remove note from docstring about nested functions causing problems with localfunctions usage. Add @seealso to functions. Don't check that function is a nested one before adding it to list. If it is in the subfunction_names list, it is valid. * ov-fcn-handle.cc (octave_fcn_handle::octave_fcn_handle): In constructor, only error out if function is a true nested function, rather than a subfunction which happens to be the parent of a nested function. * oct-parse.in.yy (base_parser::finish_function): Determine whether function is a subfunction or nested function and only if it is a subfunction is it added to the list of subfunctions of the primary function and marked as being a subfunction.
author Rik <rik@octave.org>
date Wed, 28 Dec 2016 13:58:01 -0800
parents aa55d32100c9
children d152c5e7df5a
files libinterp/corefcn/help.cc libinterp/octave-value/ov-fcn-handle.cc libinterp/parse-tree/oct-parse.in.yy
diffstat 3 files changed, 14 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/help.cc	Wed Dec 28 17:14:00 2016 -0500
+++ b/libinterp/corefcn/help.cc	Wed Dec 28 13:58:01 2016 -0800
@@ -683,8 +683,7 @@
 If the call is from the command line, an anonymous function, or a script,
 the return value is an empty cell array.
 
-Compatibility Note: Subfunctions which contain nested functions are not
-included in the list.  This is a known issue.
+@seealso{functions}
 @end deftypefn */)
 {
   if (args.length () != 0)
@@ -699,9 +698,8 @@
     return ovl (retval);
 
   // Find the subfunctions of this function.
-  // FIXME: This includes all nested functions.
-  //        Once handles of nested functions are implemented,
-  //        we will need to exclude ones not in scope.
+  // 1) subfunction_names contains only valid subfunctions
+  // 2) subfunctions contains both nested functions and subfunctions
   const std::list<std::string> names = parent_fcn->subfunction_names ();
   const std::map<std::string, octave_value> h = parent_fcn->subfunctions ();
 
@@ -713,14 +711,10 @@
   for (const auto& nm : names)
     {
       std::map<std::string, octave_value>::const_iterator nm_fcn = h.find (nm);
-      if (nm_fcn != h.end () &&
-          ! nm_fcn->second.user_function_value ()->is_nested_function ())
+      if (nm_fcn != h.end ())
         retval(i++) = octave_value (new octave_fcn_handle (nm_fcn->second, nm));
     }
 
-  // remove pre-allocation for nested functions
-  retval.resize (dim_vector (i, 1));
-
   return ovl (retval);
 }
 
@@ -737,8 +731,8 @@
 %!   fclose (fid);
 %!   d = eval (fcn_name);
 %!   assert (size (d), [2, 1]);
-%!   assert (d{1}(3), 4);
-%!   assert (d{2}(3), 6);
+%!   assert (d{1} (3), 4);
+%!   assert (d{2} (3), 6);
 %! unwind_protect_cleanup
 %!   unlink (f);
 %! end_unwind_protect
--- a/libinterp/octave-value/ov-fcn-handle.cc	Wed Dec 28 17:14:00 2016 -0500
+++ b/libinterp/octave-value/ov-fcn-handle.cc	Wed Dec 28 13:58:01 2016 -0800
@@ -84,7 +84,7 @@
   if (uf && nm != anonymous)
     symbol_table::cache_name (uf->scope (), nm);
 
-  if (uf && uf->is_nested_function ())
+  if (uf && uf->is_nested_function () && ! uf->is_subfunction ())
     error ("handles to nested functions are not yet supported");
 }
 
--- a/libinterp/parse-tree/oct-parse.in.yy	Wed Dec 28 17:14:00 2016 -0500
+++ b/libinterp/parse-tree/oct-parse.in.yy	Wed Dec 28 13:58:01 2016 -0800
@@ -3269,11 +3269,8 @@
 
         if (curr_fcn_depth > 1 || parsing_subfunctions)
           {
-            fcn->mark_as_subfunction ();
             fcn->stash_fcn_location (l, c);
 
-            subfunction_names.push_back (nm);
-
             if (endfunction_found && function_scopes.size () > 1)
               {
                 symbol_table::scope_id pscope
@@ -3283,8 +3280,13 @@
                                                     pscope);
               }
             else
-              symbol_table::install_subfunction (nm, octave_value (fcn),
-                                                 primary_fcn_scope);
+              {
+                fcn->mark_as_subfunction ();
+                subfunction_names.push_back (nm);
+
+                symbol_table::install_subfunction (nm, octave_value (fcn),
+                                                   primary_fcn_scope);
+               }
           }
 
         if (curr_fcn_depth == 1 && fcn)