changeset 20283:011a364b4d78

improve compatibility of indexed assignment (bug #43813) * oct-lvalue.h, oct-lvalue.cc (octave_lvalue::index_type, octave_lvalue::index_is_empty): New functions. * pt-assign.cc (tree_multi_assignment::rvalue): For expressions like [lhs{:}] = fcn (args) with LHS undefined, and in which FCN produces an output given nargout equal to zero, convert LHS to a one-element cell array indexed by 1.
author John W. Eaton <jwe@octave.org>
date Fri, 05 Jun 2015 15:51:04 -0400
parents 78293a28f2a5
children b93a155dc200
files libinterp/corefcn/oct-lvalue.cc libinterp/corefcn/oct-lvalue.h libinterp/parse-tree/pt-assign.cc
diffstat 3 files changed, 46 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/oct-lvalue.cc	Wed Jun 03 14:16:43 2015 -0700
+++ b/libinterp/corefcn/oct-lvalue.cc	Fri Jun 05 15:51:04 2015 -0400
@@ -54,6 +54,21 @@
     error ("invalid index expression in assignment");
 }
 
+bool
+octave_lvalue::index_is_empty (void) const
+{
+  bool retval = false;
+
+  if (idx.size () == 1)
+    {
+      octave_value_list tmp = idx.front ();
+
+      retval = (tmp.length () == 1 && tmp(0).is_empty ());
+    }
+
+  return retval;
+}
+
 void
 octave_lvalue::do_unary_op (octave_value::unary_op op)
 {
--- a/libinterp/corefcn/oct-lvalue.h	Wed Jun 03 14:16:43 2015 -0700
+++ b/libinterp/corefcn/oct-lvalue.h	Fri Jun 05 15:51:04 2015 -0400
@@ -90,6 +90,10 @@
 
   void clear_index (void) { type = std::string (); idx.clear (); }
 
+  std::string index_type (void) const { return type; }
+
+  bool index_is_empty (void) const;
+
   void do_unary_op (octave_value::unary_op op);
 
   octave_value value (void) const;
--- a/libinterp/parse-tree/pt-assign.cc	Wed Jun 03 14:16:43 2015 -0700
+++ b/libinterp/parse-tree/pt-assign.cc	Fri Jun 05 15:51:04 2015 -0400
@@ -260,6 +260,33 @@
 
           if (nel != 1)
             {
+              // Huge kluge so that wrapper scripts with lines like
+              //
+              //   [varargout{1:nargout}] = fcn (args);
+              //
+              // Will work the same as calling fcn directly when nargout
+              // is 0 and fcn produces more than one output even when
+              // nargout is 0.  This only works if varargout has not yet
+              // been defined.  See also bug #43813.
+
+              if (lvalue_list.size () == 1 && nel == 0 && n > 0
+                  && ! ult.is_black_hole () && ult.is_undefined ()
+                  && ult.index_type () == "{" && ult.index_is_empty ())
+                {
+                  // Convert undefined lvalue with empty index to a cell
+                  // array with a single value and indexed by 1 to
+                  // handle a single output.
+
+                  nel = 1;
+
+                  ult.define (Cell (1, 1));
+
+                  ult.clear_index ();
+                  std::list<octave_value_list> idx;
+                  idx.push_back (octave_value_list (octave_value (1)));
+                  ult.set_index ("{", idx);
+                }
+
               if (k + nel <= n)
                 {
                   // This won't do a copy.