# HG changeset patch # User John W. Eaton # Date 1433533864 14400 # Node ID 011a364b4d78a00d8ce279bdbb086745d678dfbb # Parent 78293a28f2a5cc959b5f4e4908dd5fcfa80f1f0b 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. diff -r 78293a28f2a5 -r 011a364b4d78 libinterp/corefcn/oct-lvalue.cc --- 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) { diff -r 78293a28f2a5 -r 011a364b4d78 libinterp/corefcn/oct-lvalue.h --- 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; diff -r 78293a28f2a5 -r 011a364b4d78 libinterp/parse-tree/pt-assign.cc --- 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 idx; + idx.push_back (octave_value_list (octave_value (1))); + ult.set_index ("{", idx); + } + if (k + nel <= n) { // This won't do a copy.