# HG changeset patch # User Jaroslav Hajek # Date 1254730818 -7200 # Node ID 318e0cdd31bd04ca77ef6792b26fbad5926db8f0 # Parent f42f0d707e8ed2961bbde799a8da4e7446b8e02c improve OOP subsref handling diff --git a/src/ChangeLog b/src/ChangeLog --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,11 @@ +2009-10-05 Jaroslav Hajek + + * pt-misc.cc (tree_argument_list::convert_to_const_vector): + Return more than nargout arguments only unless undefined elements + occur. + * ov-class.cc (octave_class::subsref): Pack return list from + overloaded method into first value. + 2009-10-05 Jaroslav Hajek * ov-ch-mat.h (octave_char_matrix): Don't declare allocator and diff --git a/src/ov-class.cc b/src/ov-class.cc --- a/src/ov-class.cc +++ b/src/ov-class.cc @@ -464,27 +464,32 @@ count++; args(0) = octave_value (this); + // FIXME: for Matlab compatibility, let us attempt to set up a proper + // value for nargout at least in the simple case where the + // cs-list-type expression - i.e., {} or ().x, is the leading one. + // Note that Octave does not actually need this, since it will + // be able to properly react to varargout a posteriori. bool maybe_cs_list_query = (type[0] == '.' || type[0] == '{' || (type.length () > 1 && type[0] == '(' && type[1] == '.')); - if (nargout == 1 && maybe_cs_list_query) + int true_nargout = nargout; + + if (maybe_cs_list_query) { // Set up a proper nargout for the subsref call by calling numel. octave_value_list tmp; if (type[0] != '.') tmp = idx.front (); - octave_idx_type true_nargout = numel (tmp); - if (! error_state) - { - tmp = feval (meth.function_value (), args, true_nargout); - if (true_nargout != 1) - retval(0) = octave_value (tmp, true); - else - retval = tmp; - } + true_nargout = numel (tmp); } - else - retval = feval (meth.function_value (), args, nargout); + + retval = feval (meth.function_value (), args, true_nargout); + + // Since we're handling subsref, return the list in the first value + // if it has more than one element, to be able to pass through + // rvalue1 calls. + if (retval.length () > 1) + retval = octave_value (retval, true); } else { diff --git a/src/pt-misc.cc b/src/pt-misc.cc --- a/src/pt-misc.cc +++ b/src/pt-misc.cc @@ -208,34 +208,45 @@ const Cell& varargout) { octave_idx_type vlen = varargout.numel (); + int len = length (); // Special case. Will do a shallow copy. - if (length () == 0 && vlen == nargout) + if (len == 0) return varargout; + else if (nargout <= len) + { + octave_value_list retval (nargout); + + int i = 0; - // 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 () && i < nout; p++) - { - tree_decl_elt *elt = *p; + for (iterator p = begin (); p != end (); p++) + { + tree_decl_elt *elt = *p; + if (elt->is_defined ()) + retval(i++) = elt->rvalue1 (); + else + break; + } - retval(i++) = elt->is_defined () ? elt->rvalue1 () : octave_value (); + return retval; } + else + { + octave_value_list retval (len + vlen); - vlen = std::min (vlen, nout - i); + int i = 0; - for (octave_idx_type j = 0; j < vlen; j++) - retval(i++) = varargout(j); + for (iterator p = begin (); p != end (); p++) + { + tree_decl_elt *elt = *p; + retval(i++) = elt->rvalue1 (); + } - // 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 (); + for (octave_idx_type j = 0; j < vlen; j++) + retval(i++) = varargout(j); - return retval; + return retval; + } } bool