changeset 16091:1785493171ac

pass lvalue_list to more subsref calls (bug #38374) * pt-id.h, pt-id.cc (tree_identifier::rvalue): Handle lvalue_list. * ov-cell.h, ov-cell.cc (octave_cell::subsref): Likewise. * ov.h, ov.cc (octave_value::next_subsref): Likewise. * ov-usr-fcn.cc (octave_usr_function::do_multi_index_op): Forward lvalue_list to rvalue call for special expression. (Fisargout): New tests.
author John W. Eaton <jwe@octave.org>
date Fri, 22 Feb 2013 19:01:10 -0500
parents 63163e8eaef3
children def3b111cff8
files libinterp/octave-value/ov-cell.cc libinterp/octave-value/ov-cell.h libinterp/octave-value/ov-usr-fcn.cc libinterp/octave-value/ov.cc libinterp/octave-value/ov.h libinterp/parse-tree/pt-id.cc libinterp/parse-tree/pt-id.h
diffstat 7 files changed, 73 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/octave-value/ov-cell.cc	Fri Feb 22 11:22:21 2013 -0500
+++ b/libinterp/octave-value/ov-cell.cc	Fri Feb 22 19:01:10 2013 -0500
@@ -136,7 +136,8 @@
 octave_value_list
 octave_cell::subsref (const std::string& type,
                       const std::list<octave_value_list>& idx,
-                      int nargout)
+                      int nargout,
+                      const std::list<octave_lvalue> *lvalue_list)
 {
   octave_value_list retval;
 
@@ -178,7 +179,9 @@
   // octave_user_function::subsref.
 
   if (idx.size () > 1)
-    retval = retval(0).next_subsref (nargout, type, idx);
+    retval = (lvalue_list
+              ? retval(0).next_subsref (nargout, type, idx, lvalue_list)
+              : retval(0).next_subsref (nargout, type, idx));
 
   return retval;
 }
--- a/libinterp/octave-value/ov-cell.h	Fri Feb 22 11:22:21 2013 -0500
+++ b/libinterp/octave-value/ov-cell.h	Fri Feb 22 19:01:10 2013 -0500
@@ -79,7 +79,16 @@
     }
 
   octave_value_list subsref (const std::string& type,
-                             const std::list<octave_value_list>& idx, int);
+                             const std::list<octave_value_list>& idx,
+                             int nargout)
+  {
+    return subsref (type, idx, nargout, 0);
+  }
+
+  octave_value_list subsref (const std::string& type,
+                             const std::list<octave_value_list>& idx,
+                             int nargout,
+                             const std::list<octave_lvalue> *lvalue_list);
 
   octave_value subsref (const std::string& type,
                         const std::list<octave_value_list>& idx,
--- a/libinterp/octave-value/ov-usr-fcn.cc	Fri Feb 22 11:22:21 2013 -0500
+++ b/libinterp/octave-value/ov-usr-fcn.cc	Fri Feb 22 19:01:10 2013 -0500
@@ -481,7 +481,9 @@
       tree_expression *expr = special_expr ();
 
       if (expr)
-        retval = expr->rvalue (nargout);
+        retval = (lvalue_list
+                  ? expr->rvalue (nargout, lvalue_list)
+                  : expr->rvalue (nargout));
     }
   else
     cmd_list->accept (*current_evaluator);
@@ -1006,4 +1008,24 @@
 %!test
 %! [x, y] = try_isargout ();
 %! assert ([x, y], [1, 2]);
+%!
+%% It should work without ():
+%!test
+%! [~, y] = try_isargout;
+%! assert (y, -2);
+%!
+%% It should work in function handles, anonymous functions, and cell
+%% arrays of handles or anonymous functions.
+%!test
+%! fh = @try_isargout;
+%! af = @() try_isargout;
+%! c = {fh, af};
+%! [~, y] = fh ();
+%! assert (y, -2);
+%! [~, y] = af ();
+%! assert (y, -2);
+%! [~, y] = c{1}();
+%! assert (y, -2);
+%! [~, y] = c{2}();
+%! assert (y, -2);
 */
--- a/libinterp/octave-value/ov.cc	Fri Feb 22 11:22:21 2013 -0500
+++ b/libinterp/octave-value/ov.cc	Fri Feb 22 19:01:10 2013 -0500
@@ -1312,6 +1312,23 @@
     return *this;
 }
 
+octave_value_list
+octave_value::next_subsref (int nargout, const std::string& type,
+                            const std::list<octave_value_list>& idx,
+                            const std::list<octave_lvalue> *lvalue_list,
+                            size_t skip)
+{
+  if (! error_state && idx.size () > skip)
+    {
+      std::list<octave_value_list> new_idx (idx);
+      for (size_t i = 0; i < skip; i++)
+        new_idx.erase (new_idx.begin ());
+      return subsref (type.substr (skip), new_idx, nargout, lvalue_list);
+    }
+  else
+    return *this;
+}
+
 octave_value
 octave_value::next_subsref (bool auto_add, const std::string& type,
                             const std::list<octave_value_list>& idx,
--- a/libinterp/octave-value/ov.h	Fri Feb 22 11:22:21 2013 -0500
+++ b/libinterp/octave-value/ov.h	Fri Feb 22 19:01:10 2013 -0500
@@ -419,6 +419,12 @@
                                   std::list<octave_value_list>& idx,
                                   size_t skip = 1);
 
+  octave_value_list next_subsref (int nargout,
+                                  const std::string& type, const
+                                  std::list<octave_value_list>& idx,
+                                  const std::list<octave_lvalue> *lvalue_list,
+                                  size_t skip = 1);
+
   octave_value next_subsref (bool auto_add, const std::string& type, const
                              std::list<octave_value_list>& idx,
                              size_t skip = 1);
--- a/libinterp/parse-tree/pt-id.cc	Fri Feb 22 11:22:21 2013 -0500
+++ b/libinterp/parse-tree/pt-id.cc	Fri Feb 22 19:01:10 2013 -0500
@@ -59,7 +59,8 @@
 }
 
 octave_value_list
-tree_identifier::rvalue (int nargout)
+tree_identifier::rvalue (int nargout,
+                         const std::list<octave_lvalue> *lvalue_list)
 {
   octave_value_list retval;
 
@@ -85,7 +86,9 @@
         {
           octave_value_list tmp_args;
 
-          retval = val.do_multi_index_op (nargout, tmp_args);
+          retval = (lvalue_list
+                    ? val.do_multi_index_op (nargout, tmp_args, lvalue_list)
+                    : val.do_multi_index_op (nargout, tmp_args));
         }
       else
         {
--- a/libinterp/parse-tree/pt-id.h	Fri Feb 22 11:22:21 2013 -0500
+++ b/libinterp/parse-tree/pt-id.h	Fri Feb 22 19:01:10 2013 -0500
@@ -103,7 +103,13 @@
 
   octave_value rvalue1 (int nargout = 1);
 
-  octave_value_list rvalue (int nargout);
+  octave_value_list rvalue (int nargout)
+  {
+    return rvalue (nargout, 0);
+  }
+
+  octave_value_list rvalue (int nargout,
+                            const std::list<octave_lvalue> *lvalue_list);
 
   octave_lvalue lvalue (void);