From bug-octave-request at bevo dot che dot wisc dot edu Thu Jun 19 11:43:47 2003 Subject: 'end' as last index for structs From: "John W. Eaton" To: Mats Jansson cc: bug-octave at bevo dot che dot wisc dot edu Date: Thu, 19 Jun 2003 11:40:19 -0500 On 5-Mar-2003, I wrote: | On 5-Mar-2003, Mats Jansson wrote: | | | Bug report for Octave 2.1.46 configured for i686-pc-linux-gnu | | | octave:1> a.a = 1:5 | | a = | | { | | a = | | | | 1 2 3 4 5 | | | | } | | | | octave:2> a.a(3:end) | | ans = [](0x0) | | octave:3> (a.a)(3:end) | | ans = [](0x0) | | octave:4> b = a.a; b(3:end) | | ans = | | | | 3 4 5 | | I see the problem, but no easy fix. I think it may require major | surgery. It turns out that the surgery was not that major, but it was somewhat tricky to figure out how do it without a making a big mess... Please try the following patch (relative to the current CVS, but should apply without too much trouble to any recent 2.1.x version released after "end" indexing was added). With the patch, I get octave:1> a.a = 1:5 a = { a = 1 2 3 4 5 } octave:2> a.a(3:end) ans = 3 4 5 and (for slightly different examples) octave:4> x(2).f = [1,2,3,4] x = { f = ( [1] = [](0x0) [2] = 1 2 3 4 ) } octave:5> x(end).f(end) ans = 4 octave:6> x(end).f(end+2) = 6 x = { f = ( [1] = [](0x0) [2] = 1 2 3 4 0 6 ) } Thanks, jwe src/ChangeLog: 2003-06-19 John W. Eaton * pt-idx.cc (tree_index_expression::rvalue): Correctly handle index expressions like x(end).f(end). (tree_index_expression::lvalue): Likewise. * pt-arg-list.cc (F__end__): Add nr, nc info to error messages. Index: src/pt-arg-list.cc =================================================================== RCS file: /usr/local/cvsroot/octave/src/pt-arg-list.cc,v retrieving revision 1.17 diff -u -r1.17 pt-arg-list.cc --- src/pt-arg-list.cc 3 Jan 2003 15:27:05 -0000 1.17 +++ src/pt-arg-list.cc 19 Jun 2003 16:31:30 -0000 at @ -132,7 +132,7 @@ int nc = indexed_object->columns (); if (nr < 0 || nc < 0) - ::error ("invalid use of end"); + ::error ("invalid use of end: (nr=%d, nc=%d)", nr, nc); else retval = nr * nc; } at @ -143,7 +143,7 @@ int nr = indexed_object->rows (); if (nr < 0) - ::error ("invalid use of end"); + ::error ("invalid use of end: (nr=%d)", nr); else retval = nr; } at @ -154,7 +154,7 @@ int nc = indexed_object->columns (); if (nc < 0) - ::error ("invalid use of end"); + ::error ("invalid use of end: (nc=%d)", nc); else retval = nc; } Index: src/pt-idx.cc =================================================================== RCS file: /usr/local/cvsroot/octave/src/pt-idx.cc,v retrieving revision 1.22 diff -u -r1.22 pt-idx.cc --- src/pt-idx.cc 21 Dec 2002 17:15:25 -0000 1.22 +++ src/pt-idx.cc 19 Jun 2003 16:31:30 -0000 at @ -258,7 +258,8 @@ if (error_state) return retval; - octave_value tmp = expr->rvalue (); + octave_value first_expr_val = expr->rvalue (); + octave_value tmp = first_expr_val; if (! error_state) { at @ -272,6 +273,32 @@ for (int i = 0; i < n; i++) { + if (i > 0) + { + tree_argument_list *al = *p_args; + + if (al && al->has_magic_end ()) + { + // We have an expression like + // + // x{end}.a(end) + // + // and we are looking at the argument list that + // contains the second (or third, etc.) "end" token, + // so we must evaluate everything up to the point of + // that argument list so we pass the appropiate + // value to the built-in __end__ function. + + octave_value_list tmp_list + = first_expr_val.subsref (type, idx, nargout); + + tmp = tmp_list(0); + + if (error_state) + break; + } + } + switch (type[i]) { case '(': at @ -304,7 +331,7 @@ } if (! error_state) - retval = tmp.subsref (type, idx, nargout); + retval = first_expr_val.subsref (type, idx, nargout); } return retval; at @ -340,18 +367,53 @@ if (! error_state) { - const octave_value *tmp = retval.object (); + // I think it is OK to have a copy here. + + const octave_value *tro = retval.object (); + + octave_value first_retval_object; + + if (tro) + first_retval_object = *tro; + + octave_value tmp = first_retval_object; for (int i = 0; i < n; i++) { + if (i > 0) + { + tree_argument_list *al = *p_args; + + if (al && al->has_magic_end ()) + { + // We have an expression like + // + // x{end}.a(end) + // + // and we are looking at the argument list that + // contains the second (or third, etc.) "end" token, + // so we must evaluate everything up to the point of + // that argument list so we pass the appropiate + // value to the built-in __end__ function. + + octave_value_list tmp_list + = first_retval_object.subsref (type, idx, 1); + + tmp = tmp_list(0); + + if (error_state) + break; + } + } + switch (type[i]) { case '(': - idx.push_back (make_value_list (*p_args, *p_arg_nm, tmp)); + idx.push_back (make_value_list (*p_args, *p_arg_nm, &tmp)); break; case '{': - idx.push_back (make_value_list (*p_args, *p_arg_nm, tmp)); + idx.push_back (make_value_list (*p_args, *p_arg_nm, &tmp)); break; case '.': ------------------------------------------------------------- Octave is freely available under the terms of the GNU GPL. Octave's home on the web: http://www.octave.org How to fund new projects: http://www.octave.org/funding.html Subscription information: http://www.octave.org/archive.html -------------------------------------------------------------