# HG changeset patch # User Jaroslav Hajek # Date 1253027833 -7200 # Node ID 080e11f1b0c1cc9291eb0f6c5743afa91cc77fea # Parent 85dd3a2c9355dc4cf05d36fa3be0fea6bdafa4e9 don't return undefined output values from user functions diff --git a/src/ChangeLog b/src/ChangeLog --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,12 @@ +2009-09-15 Jaroslav Hajek + + * pt-misc.cc (tree_parameter_list::convert_to_const_vector): Pass + in nargout. Don't return excess elements. Optimize varargout-only case + to possibly use a shallow copy. + * pt-misc.h: Update decl. + * ov-usr-fcn.cc (octave_user_function::do_multi_index_op): Update call + to tree_parameter_list::convert_to_const_vector. + 2009-09-15 Jaroslav Hajek * pr-output.cc (Fdisp, Ffdisp): Declare retval as octave_value_list. diff --git a/src/ov-usr-fcn.cc b/src/ov-usr-fcn.cc --- a/src/ov-usr-fcn.cc +++ b/src/ov-usr-fcn.cc @@ -473,7 +473,7 @@ } if (! error_state) - retval = ret_list->convert_to_const_vector (varargout); + retval = ret_list->convert_to_const_vector (nargout, varargout); } } @@ -706,6 +706,17 @@ return SET_INTERNAL_VARIABLE (optimize_subsasgn_calls); } +DEFUN (test_feval, args, , "") +{ + octave_value_list fargs(2); + fargs(0) = "load"; + fargs(1) = "nlwing2"; + octave_value_list retval = feval ("pkg", fargs, 0); + std::cerr << retval.length () << '\n'; + + return octave_value_list (); +} + /* ;;; Local Variables: *** ;;; mode: C++ *** diff --git a/src/pt-misc.cc b/src/pt-misc.cc --- a/src/pt-misc.cc +++ b/src/pt-misc.cc @@ -204,26 +204,37 @@ } octave_value_list -tree_parameter_list::convert_to_const_vector (const Cell& varargout) +tree_parameter_list::convert_to_const_vector (int nargout, + const Cell& varargout) { octave_idx_type vlen = varargout.numel (); - int nout = length () + vlen; + // Special case. Will do a shallow copy. + if (length () == 0 && vlen == nargout) + return varargout; - octave_value_list retval (nout, octave_value ()); + // We want always at least one return value. + int nout = std::max (nargout, 1); + octave_value_list retval (nout); int i = 0; - for (iterator p = begin (); p != end (); p++) + for (iterator p = begin (); p != end () && i < nout; p++) { tree_decl_elt *elt = *p; retval(i++) = elt->is_defined () ? elt->rvalue1 () : octave_value (); } + vlen = std::min (vlen, nout - i); + for (octave_idx_type j = 0; j < vlen; j++) retval(i++) = varargout(j); + // If there was zero outputs requested, and nothing is defined, don't return anything. + if (nargout == 0 && retval(0).is_undefined ()) + retval = octave_value_list (); + return retval; } diff --git a/src/pt-misc.h b/src/pt-misc.h --- a/src/pt-misc.h +++ b/src/pt-misc.h @@ -79,7 +79,7 @@ bool is_defined (void); - octave_value_list convert_to_const_vector (const Cell& varargout); + octave_value_list convert_to_const_vector (int nargout, const Cell& varargout); tree_parameter_list *dup (symbol_table::scope_id scope, symbol_table::context_id context) const;