changeset 4749:a4bc7156bd60

[project @ 2004-02-07 16:59:28 by jwe]
author jwe
date Sat, 07 Feb 2004 16:59:28 +0000
parents 7b145222fea3
children 95661d5713ce
files liboctave/Array.cc liboctave/ChangeLog src/ChangeLog src/ov-complex.h src/ov-scalar.h
diffstat 5 files changed, 132 insertions(+), 88 deletions(-) [+]
line wrap: on
line diff
--- 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<LT>::get_size (frozen_len);
-
-		  Array<int> result_idx (lhs_dims_len, 0);
-
-		  RT scalar = rhs.elem (0);
-
-		  for (int i = 0; i < n; i++)
-		    {
-		      Array<int> 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<int> result_idx (lhs_dims_len, 0);
 
+		      RT scalar = rhs.elem (0);
+
 		      for (int i = 0; i < n; i++)
 			{
 			  Array<int> 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<LT>::get_size (frozen_len);
+
+			  Array<int> result_idx (lhs_dims_len, 0);
+
+			  for (int i = 0; i < n; i++)
+			    {
+			      Array<int> elt_idx = get_elt_idx (idx, result_idx);
+
+			      lhs.elem (elt_idx) = rhs.elem (i);
+
+			      increment_index (result_idx, frozen_len);
+			    }
+			}
+		    }
+		}
 	    }
 	}
 
--- 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  <jwe@bevo.che.wisc.edu>
+
+	* Array.cc (Array<T>::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  <jwe@bevo.che.wisc.edu>
 
 	* Array.cc (Array<T>::resize_and_fill): Don't bother to assign any
--- 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  <jwe@bevo.che.wisc.edu>
+
+	* 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  <jwe@bevo.che.wisc.edu>
 
 	* ov-usr-fcn.h (octave_user_function::function_name): Delete.
--- 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);
 
--- 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);