# HG changeset patch # User jwe # Date 1076173168 0 # Node ID a4bc7156bd608c118b9e5477328b8d5f5881bb55 # Parent 7b145222fea32654281ddc9f043b223ab85f7569 [project @ 2004-02-07 16:59:28 by jwe] diff -r 7b145222fea3 -r a4bc7156bd60 liboctave/Array.cc --- a/liboctave/Array.cc Sat Feb 07 06:27:28 2004 +0000 +++ b/liboctave/Array.cc Sat Feb 07 16:59:28 2004 +0000 @@ -2711,102 +2711,62 @@ // We didn't start out with all zero dimensions, so if // index is a colon, it refers to the current LHS // dimension. Otherwise, it is OK to enlarge to a - // dimension given by the largest index. - - new_dims(i) - = (idx(i).is_colon () || idx(i).max () < lhs_dims(i)) - ? lhs_dims(i) : idx(i).max () + 1; + // dimension given by the largest index (but that index + // needs to be a number, not a colon). + + if (i < lhs_dims_len + && (idx(i).is_colon () || idx(i).max () < lhs_dims(i))) + new_dims(i) = lhs_dims(i); + else if (! idx(i).is_colon ()) + new_dims(i) = idx(i).max () + 1; + else + { + // XXX FIXME XXX -- can we provide a more + // informative message here? + + (*current_liboctave_error_handler) + ("invalid array index for assignment"); + + retval = 0; + + break; + } } } - if (! orig_empty - && n_idx < orig_lhs_dims_len - && new_dims(n_idx-1) != lhs_dims(n_idx-1)) + if (retval != 0) { - // We reshaped and the last dimension changed. This has to - // be an error, because we don't know how to undo that - // later... - - (*current_liboctave_error_handler) - ("array index %d (= %d) for assignment requires invalid resizing operation", - n_idx, new_dims(n_idx-1)); - - retval = 0; - } - else - { - if (n_idx < orig_lhs_dims_len) + if (! orig_empty + && n_idx < orig_lhs_dims_len + && new_dims(n_idx-1) != lhs_dims(n_idx-1)) { - for (int i = 0; i < n_idx-1; i++) - final_lhs_dims(i) = new_dims(i); - } - else - final_lhs_dims = new_dims; - - lhs.resize_and_fill (new_dims, rfv); - lhs_dims = lhs.dims (); - lhs_dims_len = lhs_dims.length (); - - frozen_len = freeze (idx, lhs_dims, true); - - if (rhs_is_scalar) - { - if (! final_lhs_dims.any_zero ()) - { - int n = Array::get_size (frozen_len); - - Array result_idx (lhs_dims_len, 0); - - RT scalar = rhs.elem (0); - - for (int i = 0; i < n; i++) - { - Array elt_idx = get_elt_idx (idx, result_idx); - - lhs.elem (elt_idx) = scalar; - - increment_index (result_idx, frozen_len); - } - } + // We reshaped and the last dimension changed. This has to + // be an error, because we don't know how to undo that + // later... + + (*current_liboctave_error_handler) + ("array index %d (= %d) for assignment requires invalid resizing operation", + n_idx, new_dims(n_idx-1)); + + retval = 0; } else { - // RHS is matrix or higher dimension. - - // Check that non-singleton RHS dimensions conform to - // non-singleton LHS index dimensions. - - dim_vector t_rhs_dims = rhs_dims.squeeze (); - dim_vector t_frozen_len = frozen_len.squeeze (); - - // If after sqeezing out singleton dimensions, RHS is - // vector and LHS is vector, force them to have the same - // orientation so that operations like - // - // a = zeros (3, 3, 3); - // a(1:3,1,1) = [1,2,3]; - // - // will work. - - if (t_rhs_dims.length () == 2 && t_frozen_len.length () == 2 - && ((t_rhs_dims.elem(1) == 1 - && t_frozen_len.elem(0) == 1) - || (t_rhs_dims.elem(0) == 1 - && t_frozen_len.elem(1) == 1))) + if (n_idx < orig_lhs_dims_len) { - int t0 = t_rhs_dims.elem(0); - t_rhs_dims.elem(0) = t_rhs_dims.elem(1); - t_rhs_dims.elem(1) = t0; - } - - if (t_rhs_dims != t_frozen_len) - { - (*current_liboctave_error_handler) - ("A(IDX-LIST) = X: X must be a scalar or size of X must equal number of elements indexed by IDX-LIST"); - - retval = 0; + for (int i = 0; i < n_idx-1; i++) + final_lhs_dims(i) = new_dims(i); } else + final_lhs_dims = new_dims; + + lhs.resize_and_fill (new_dims, rfv); + lhs_dims = lhs.dims (); + lhs_dims_len = lhs_dims.length (); + + frozen_len = freeze (idx, lhs_dims, true); + + if (rhs_is_scalar) { if (! final_lhs_dims.any_zero ()) { @@ -2814,16 +2774,74 @@ Array result_idx (lhs_dims_len, 0); + RT scalar = rhs.elem (0); + for (int i = 0; i < n; i++) { Array elt_idx = get_elt_idx (idx, result_idx); - lhs.elem (elt_idx) = rhs.elem (i); + lhs.elem (elt_idx) = scalar; increment_index (result_idx, frozen_len); } } } + else + { + // RHS is matrix or higher dimension. + + // Check that non-singleton RHS dimensions conform to + // non-singleton LHS index dimensions. + + dim_vector t_rhs_dims = rhs_dims.squeeze (); + dim_vector t_frozen_len = frozen_len.squeeze (); + + // If after sqeezing out singleton dimensions, RHS is + // vector and LHS is vector, force them to have the same + // orientation so that operations like + // + // a = zeros (3, 3, 3); + // a(1:3,1,1) = [1,2,3]; + // + // will work. + + if (t_rhs_dims.length () == 2 && t_frozen_len.length () == 2 + && ((t_rhs_dims.elem(1) == 1 + && t_frozen_len.elem(0) == 1) + || (t_rhs_dims.elem(0) == 1 + && t_frozen_len.elem(1) == 1))) + { + int t0 = t_rhs_dims.elem(0); + t_rhs_dims.elem(0) = t_rhs_dims.elem(1); + t_rhs_dims.elem(1) = t0; + } + + if (t_rhs_dims != t_frozen_len) + { + (*current_liboctave_error_handler) + ("A(IDX-LIST) = X: X must be a scalar or size of X must equal number of elements indexed by IDX-LIST"); + + retval = 0; + } + else + { + if (! final_lhs_dims.any_zero ()) + { + int n = Array::get_size (frozen_len); + + Array result_idx (lhs_dims_len, 0); + + for (int i = 0; i < n; i++) + { + Array elt_idx = get_elt_idx (idx, result_idx); + + lhs.elem (elt_idx) = rhs.elem (i); + + increment_index (result_idx, frozen_len); + } + } + } + } } } diff -r 7b145222fea3 -r a4bc7156bd60 liboctave/ChangeLog --- a/liboctave/ChangeLog Sat Feb 07 06:27:28 2004 +0000 +++ b/liboctave/ChangeLog Sat Feb 07 16:59:28 2004 +0000 @@ -1,3 +1,10 @@ +2004-02-07 John W. Eaton + + * Array.cc (Array::assignN): Don't crash if trying to resize a + non-empty LHS when the number of lhs dimensions is less than the + number of indices. Detect error if attempting to resize non-empty + LHS with colon indices. + 2004-02-06 John W. Eaton * Array.cc (Array::resize_and_fill): Don't bother to assign any diff -r 7b145222fea3 -r a4bc7156bd60 src/ChangeLog --- a/src/ChangeLog Sat Feb 07 06:27:28 2004 +0000 +++ b/src/ChangeLog Sat Feb 07 16:59:28 2004 +0000 @@ -1,3 +1,10 @@ +2004-02-07 John W. Eaton + + * ov-scalar.h (octave_scalar::empty_clone): + Return empty octave_matrix, not an octave_scalar object. + * ov-complex.h (octave_complex::empty_clone): + Return empty octave_complex_matrix, not an octave_complex object. + 2004-02-06 John W. Eaton * ov-usr-fcn.h (octave_user_function::function_name): Delete. diff -r 7b145222fea3 -r a4bc7156bd60 src/ov-complex.h --- a/src/ov-complex.h Sat Feb 07 06:27:28 2004 +0000 +++ b/src/ov-complex.h Sat Feb 07 16:59:28 2004 +0000 @@ -38,6 +38,7 @@ #include "error.h" #include "ov-base.h" +#include "ov-cx-mat.h" #include "ov-base-scalar.h" #include "ov-typeinfo.h" @@ -65,7 +66,13 @@ ~octave_complex (void) { } octave_value *clone (void) const { return new octave_complex (*this); } - octave_value *empty_clone (void) const { return new octave_complex (); } + + // We return an octave_complex_matrix object here instead of an + // octave_complex object so that in expressions like A(2,2,2) = 2 + // (for A previously undefined), A will be empty instead of a 1x1 + // object. + octave_value *empty_clone (void) const + { return new octave_complex_matrix (); } octave_value *try_narrowing_conversion (void); diff -r 7b145222fea3 -r a4bc7156bd60 src/ov-scalar.h --- a/src/ov-scalar.h Sat Feb 07 06:27:28 2004 +0000 +++ b/src/ov-scalar.h Sat Feb 07 16:59:28 2004 +0000 @@ -39,6 +39,7 @@ #include "str-vec.h" #include "ov-base.h" +#include "ov-re-mat.h" #include "ov-base-scalar.h" #include "ov-typeinfo.h" @@ -66,7 +67,11 @@ ~octave_scalar (void) { } octave_value *clone (void) const { return new octave_scalar (*this); } - octave_value *empty_clone (void) const { return new octave_scalar (); } + + // We return an octave_matrix here instead of an octave_scalar so + // that in expressions like A(2,2,2) = 2 (for A previously + // undefined), A will be empty instead of a 1x1 object. + octave_value *empty_clone (void) const { return new octave_matrix (); } octave_value do_index_op (const octave_value_list& idx, int resize_ok);