# HG changeset patch # User jwe # Date 1194299485 0 # Node ID 70f30a92b725dfaf5f67d1c89f08588d4699fe36 # Parent dd3a3e65bc861fb5744fb74222ebd079cf61dc56 [project @ 2007-11-05 21:51:24 by jwe] diff -r dd3a3e65bc86 -r 70f30a92b725 src/ChangeLog --- a/src/ChangeLog Fri Nov 02 19:21:56 2007 +0000 +++ b/src/ChangeLog Mon Nov 05 21:51:25 2007 +0000 @@ -1,3 +1,9 @@ +2007-11-05 John W. Eaton + + * pt-idx.cc (tree_index_expression::lvalue): Try to do a better + job of computing the number of elements in lvalue expressions when + the last indexing element is ".". + 2007-11-02 John W. Eaton * file-io.cc (fopen_mode_to_ios_mode): Use std::ios::app instead diff -r dd3a3e65bc86 -r 70f30a92b725 src/pt-idx.cc --- a/src/pt-idx.cc Fri Nov 02 19:21:56 2007 +0000 +++ b/src/pt-idx.cc Mon Nov 05 21:51:25 2007 +0000 @@ -385,6 +385,10 @@ if (! error_state) { + bool have_new_struct_field = false; + + octave_idx_type new_struct_field_nel = 0; + // I think it is OK to have a copy here. const octave_value *tro = retval.object (); @@ -485,44 +489,88 @@ // Last indexing element. Will this result in a // comma-separated list? - if (first_retval_object.is_map ()) + if (have_new_struct_field) + retval.numel (new_struct_field_nel); + else if (i > 0) { - if (i > 0) + std::string ttype = type.substr (0, i); + + if (ttype[ttype.length()-1] == '(') { + octave_idx_type nel = 1; + octave_value_list xidx = idx.back (); - if (xidx.has_magic_colon ()) + octave_idx_type nidx = xidx.length (); + + for (octave_idx_type j = 0; j < nidx; j++) + { + octave_value val = xidx(j); + + nel *= val.numel (); + } + + retval.numel (nel); + } + else if (first_retval_object.is_defined ()) + { + octave_value_list tmp_list + = first_retval_object.subsref (ttype, idx, 1); + + if (! error_state) { - std::string ttype = type.substr (0, i); + octave_value val = tmp_list(0); + retval.numel (val.numel ()); + } + } + else + retval.numel (1); + } + else + { + if (first_retval_object.is_defined ()) + retval.numel (first_retval_object.numel ()); + else + retval.numel (1); + } + } + else + { + octave_value tobj = first_retval_object; + + if (! have_new_struct_field) + { + if (i > 0 && first_retval_object.is_defined ()) + { + std::string ttype = type.substr (0, i); + + if (ttype[ttype.length()-1] != '(') + { octave_value_list tmp_list = first_retval_object.subsref (ttype, idx, 1); if (! error_state) + tobj = tmp_list(0); + } + } + + if (! error_state && tobj.is_map ()) + { + if (tidx.is_string ()) + { + Octave_map m = tobj.map_value (); + + std::string s = tidx.string_value (); + + if (! m.contains (s)) { - octave_value val = tmp_list(0); + have_new_struct_field = true; - retval.numel (val.numel ()); + new_struct_field_nel = m.numel (); } } - else - { - octave_idx_type nel = 1; - - octave_idx_type nidx = xidx.length (); - - for (octave_idx_type j = 0; j < nidx; j++) - { - octave_value val = xidx(j); - - nel *= val.numel (); - } - - retval.numel (nel); - } } - else - retval.numel (first_retval_object.numel ()); } } @@ -552,6 +600,31 @@ return retval; } +/* +%!test +%! x = {1, 2, 3}; +%! [x{:}] = deal (4, 5, 6); +%! assert (x, {4, 5, 6}); + +%!test +%! [x.a, x.b.c] = deal (1, 2); +%! assert (x.a == 1 && x.b.c == 2); + +%!test +%! [x.a, x(2).b] = deal (1, 2); +%! assert (x(1).a == 1 && isempty (x(2).a) && isempty (x(1).b) && x(2).b == 2); + +%!test +%! x = struct (zeros (0, 1), {"a", "b"}); +%! x(2).b = 1; +%! assert (x(2).b == 1); + +%!test +%! x = struct (zeros (0, 1), {"a", "b"}); +%! x(2).b = 1; +%! assert (x(2).b == 1); +*/ + void tree_index_expression::eval_error (void) const {