# HG changeset patch # User Rik # Date 1482962281 28800 # Node ID ecc5eeada8dcaab1041741757b04e3e7cbe7a3b6 # Parent aa55d32100c9935cfccb511e42c59b6125ca6a19 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. diff -r aa55d32100c9 -r ecc5eeada8dc libinterp/corefcn/help.cc --- 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 names = parent_fcn->subfunction_names (); const std::map h = parent_fcn->subfunctions (); @@ -713,14 +711,10 @@ for (const auto& nm : names) { std::map::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 diff -r aa55d32100c9 -r ecc5eeada8dc libinterp/octave-value/ov-fcn-handle.cc --- 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"); } diff -r aa55d32100c9 -r ecc5eeada8dc libinterp/parse-tree/oct-parse.in.yy --- 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)