Mercurial > octave
changeset 20248: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.