changeset 9644:080e11f1b0c1

don't return undefined output values from user functions
author Jaroslav Hajek <highegg@gmail.com>
date Tue, 15 Sep 2009 17:17:13 +0200
parents 85dd3a2c9355
children 4531741e5236
files src/ChangeLog src/ov-usr-fcn.cc src/pt-misc.cc src/pt-misc.h
diffstat 4 files changed, 37 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Tue Sep 15 10:00:53 2009 +0200
+++ b/src/ChangeLog	Tue Sep 15 17:17:13 2009 +0200
@@ -1,3 +1,12 @@
+2009-09-15  Jaroslav Hajek  <highegg@gmail.com>
+
+	* 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  <highegg@gmail.com>
 
 	* pr-output.cc (Fdisp, Ffdisp): Declare retval as octave_value_list.
--- a/src/ov-usr-fcn.cc	Tue Sep 15 10:00:53 2009 +0200
+++ b/src/ov-usr-fcn.cc	Tue Sep 15 17:17:13 2009 +0200
@@ -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++ ***
--- a/src/pt-misc.cc	Tue Sep 15 10:00:53 2009 +0200
+++ b/src/pt-misc.cc	Tue Sep 15 17:17:13 2009 +0200
@@ -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;
 }
 
--- a/src/pt-misc.h	Tue Sep 15 10:00:53 2009 +0200
+++ b/src/pt-misc.h	Tue Sep 15 17:17:13 2009 +0200
@@ -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;