changeset 28004:403df0b32204

update out_of_range error messages * sub2ind.cc (Fsub2ind): Don't redimension dim_vector object so that the sub2ind function may report original dimensions in error messages. * Range.h (Range::dims): New function. * lo-array-errwarn.h, lo-array-errwarn.cc (out_of_range::set_size, out_of_range::set_extent): Delete. (out_of_range::out_of_range): Accept size and extent arguments. (out_of_range::details): Simplify. Always report extent and dimensions. (err_index_out_of_range): Deprecate overload that does not accept dim_vector argument. Change all uses to call the one that does. Simplify by passing extent and dims to out_of_range_object constructor. * test/index.tst: Update error messages in tests.
author John W. Eaton <jwe@octave.org>
date Sat, 25 Jan 2020 16:56:27 -0500
parents 60d8d6e5594d
children 4ee66fda87fb
files libinterp/corefcn/sub2ind.cc liboctave/array/Array-util.cc liboctave/array/Range.cc liboctave/array/Range.h liboctave/util/lo-array-errwarn.cc liboctave/util/lo-array-errwarn.h test/index.tst
diffstat 7 files changed, 43 insertions(+), 56 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/sub2ind.cc	Sat Jan 25 12:43:31 2020 -0500
+++ b/libinterp/corefcn/sub2ind.cc	Sat Jan 25 16:56:27 2020 -0500
@@ -114,7 +114,8 @@
   if (nargin < 2)
     print_usage ();
 
-  dim_vector dv = get_dim_vector (args(0), "sub2ind").redim (nargin - 1);
+  dim_vector dv = get_dim_vector (args(0), "sub2ind");
+
   Array<idx_vector> idxa (dim_vector (nargin-1, 1));
 
   for (int j = 0; j < nargin - 1; j++)
--- a/liboctave/array/Array-util.cc	Sat Jan 25 12:43:31 2020 -0500
+++ b/liboctave/array/Array-util.cc	Sat Jan 25 16:56:27 2020 -0500
@@ -559,7 +559,7 @@
               ("sub2ind: lengths of indices must match");
 
           if (idx.extent (n) > n)
-            octave::err_index_out_of_range (len, i+1, idx.extent (n), n);
+            octave::err_index_out_of_range (len, i+1, idx.extent (n), n, dv);
         }
       catch (octave::index_exception& e)
         {
--- a/liboctave/array/Range.cc	Sat Jan 25 12:43:31 2020 -0500
+++ b/liboctave/array/Range.cc	Sat Jan 25 16:56:27 2020 -0500
@@ -113,7 +113,7 @@
 Range::checkelem (octave_idx_type i) const
 {
   if (i < 0 || i >= rng_numel)
-    octave::err_index_out_of_range (2, 2, i+1, rng_numel);
+    octave::err_index_out_of_range (2, 2, i+1, rng_numel, dims ());
 
   if (i == 0)
     return rng_base;
@@ -128,7 +128,7 @@
 {
   // Ranges are *always* row vectors.
   if (i != 0)
-    octave::err_index_out_of_range (1, 1, i+1, rng_numel);
+    octave::err_index_out_of_range (1, 1, i+1, rng_numel, dims ());
 
   return checkelem (j);
 }
@@ -182,7 +182,7 @@
   else
     {
       if (i.extent (n) != n)
-        octave::err_index_out_of_range (1, 1, i.extent (n), n); // throws
+        octave::err_index_out_of_range (1, 1, i.extent (n), n, dims ()); // throws
 
       dim_vector rd = i.orig_dimensions ();
       octave_idx_type il = i.length (n);
--- a/liboctave/array/Range.h	Sat Jan 25 12:43:31 2020 -0500
+++ b/liboctave/array/Range.h	Sat Jan 25 16:56:27 2020 -0500
@@ -31,6 +31,7 @@
 #include <iosfwd>
 
 #include "dMatrix.h"
+#include "dim-vector.h"
 #include "oct-sort.h"
 
 class
@@ -85,6 +86,8 @@
 
   octave_idx_type numel (void) const { return rng_numel; }
 
+  dim_vector dims (void) const { return dim_vector (1, rng_numel); }
+
   octave_idx_type rows (void) const { return 1; }
 
   octave_idx_type cols (void) const { return numel (); }
--- a/liboctave/util/lo-array-errwarn.cc	Sat Jan 25 12:43:31 2020 -0500
+++ b/liboctave/util/lo-array-errwarn.cc	Sat Jan 25 16:56:27 2020 -0500
@@ -250,28 +250,18 @@
   {
   public:
 
-    out_of_range (const std::string& value, octave_idx_type nd_in,
-                  octave_idx_type dim_in)
-      : index_exception (value, nd_in, dim_in), m_size (), m_extent (0)
+    out_of_range (const std::string& value, octave_idx_type nd,
+                  octave_idx_type dim, octave_idx_type ext,
+                  const dim_vector& size)
+      : index_exception (value, nd, dim), m_size (size), m_extent (ext)
     { }
 
     std::string details (void) const
     {
       std::string expl;
 
-      if (m_nd >= m_size.ndims ())   // if not an index slice
-        {
-          if (m_var != "")
-            expl = "but " + m_var + " has size ";
-          else
-            expl = "but object has size ";
-
-          expl = expl + m_size.str ('x');
-        }
-      else
-        expl = "out of bound " + std::to_string (m_extent);
-
-      return expl;
+      return "out of bound " + std::to_string (m_extent)
+        + " (dimensions are " + m_size.str ('x') + ")";
     }
 
     // ID of error to throw.
@@ -280,10 +270,6 @@
       return error_id_index_out_of_bounds;
     }
 
-    void set_size (const dim_vector& size_in) { m_size = size_in; }
-
-    void set_extent (octave_idx_type ext) { m_extent = ext; }
-
   private:
 
     // Dimension of object being accessed.
@@ -293,31 +279,12 @@
     octave_idx_type m_extent;
   };
 
-  // Complain of an index that is out of range, but we don't know matrix size
-  void
-  err_index_out_of_range (int nd, int dim, octave_idx_type idx,
-                          octave_idx_type ext)
-  {
-    out_of_range e (std::to_string (idx), nd, dim);
-
-    e.set_extent (ext);
-    // ??? Make details method give extent not size.
-    e.set_size (dim_vector (1, 1, 1, 1, 1, 1,1));
-
-    throw e;
-  }
-
   // Complain of an index that is out of range
   void
   err_index_out_of_range (int nd, int dim, octave_idx_type idx,
-                          octave_idx_type ext, const dim_vector& d)
+                          octave_idx_type ext, const dim_vector& dv)
   {
-    out_of_range e (std::to_string (idx), nd, dim);
-
-    e.set_extent (ext);
-    e.set_size (d);
-
-    throw e;
+    throw out_of_range (std::to_string (idx), nd, dim, ext, dv);
   }
 
   void
@@ -344,6 +311,21 @@
            "matrix singular to machine precision, rcond = %g", rcond);
       }
   }
+
+  // DEPRECATED in Octave 6.
+
+  // Complain of an index that is out of range, but we don't know matrix size
+  void
+  err_index_out_of_range (int nd, int dim, octave_idx_type idx,
+                          octave_idx_type ext)
+  {
+    // The dim_vector setting here doesn't really make sense.  However,
+    // this function has been deprecated and will be removed in version
+    // 8, so there's no need to attempt to fix it.
+
+    throw out_of_range (std::to_string (idx), nd, dim, ext,
+                        dim_vector (1, 1, 1, 1, 1, 1, 1));
+  }
 }
 
 /* Tests in test/index.tst */
--- a/liboctave/util/lo-array-errwarn.h	Sat Jan 25 12:43:31 2020 -0500
+++ b/liboctave/util/lo-array-errwarn.h	Sat Jan 25 16:56:27 2020 -0500
@@ -130,11 +130,12 @@
                      const dim_vector& op1_dims, const dim_vector& op2_dims);
 
   OCTAVE_NORETURN OCTAVE_API extern void
-  err_index_out_of_range (int nd, int dim, octave_idx_type iext,
-                          octave_idx_type ext, const dim_vector& d);
+  err_index_out_of_range (int ndims, int dim, octave_idx_type idx,
+                          octave_idx_type ext, const dim_vector& dv);
 
+  OCTAVE_DEPRECATED (6, "use err_index_out_of_range (int, int, octave_idx_type, octave_idx_type, const dim_vector&) instead")
   OCTAVE_NORETURN OCTAVE_API extern void
-  err_index_out_of_range (int nd, int dim, octave_idx_type iext,
+  err_index_out_of_range (int ndims, int dim, octave_idx_type idx,
                           octave_idx_type ext);
 
   OCTAVE_NORETURN OCTAVE_API extern void
--- a/test/index.tst	Sat Jan 25 12:43:31 2020 -0500
+++ b/test/index.tst	Sat Jan 25 16:56:27 2020 -0500
@@ -512,9 +512,9 @@
 %!error <index \(...\[x9\]...-1,_\): subscript>      1(1,1,1,1,1,1,1,1,1,-1,1)
 %!error <index \(2\): out of bound 1>                1(2)
 %!error <index \(1\): out of bound 0>                [](1)
-%!error <index \(_,1\): but object has size 5x0>     zeros(5,0)(3,1)
-%!error <index \(3,_\): but object has size 0x5>     zeros(0,5)(3,1)
 %!error <index \(-1\): subscripts>                   1(1)(-1)(1)
+%!error <index \(_,1\): out of bound 0 \(dimensions are 5x0\)> zeros(5,0)(3,1)
+%!error <index \(3,_\): out of bound 0 \(dimensions are 0x5\)> zeros(0,5)(3,1)
 %!
 %!shared abc
 %! abc = [1, 2];
@@ -526,20 +526,20 @@
 %!shared abc
 %! abc = [1 2; 3 4];
 %!error <abc\(5\): out of bound 4>         abc(5)
-%!error <abc\(_,3\): but abc has size 2x2> abc(2,3)
+%!error <abc\(_,3\): out of bound 2 \(dimensions are 2x2\)> abc(2,3)
 %!error <abc\(_,_,0.5\): subscripts>       exp (abc(2,3,0.5))
 
 %!shared abc
 %! abc = [1 2; 3 4]; abc(1,1,2) = 1;
 %!error <abc\(_,5\): out of bound 4>                            abc(2,5)
-%!error <abc\(_,3,_\): but abc has size 2x2x2>                  abc(2,3,2)
+%!error <abc\(_,3,_\): out of bound 2 \(dimensions are 2x2x2\)> abc(2,3,2)
 %!error <A\(..,I,..\) = \[\]: .* value 3 out of bound 2>        abc(3,:) = []
 %!error <A\(I\) = \[\]: .* value 50 out of bound 8>             abc(3:50) = []
 %!error <a null assignment can only have one non-colon index>   abc(3,5) = []
 %!error <=: nonconformant arguments \(op1 is 1x1, op2 is 1x5\)> abc(3,5) = 1:5
 
 ##  Test diagonal matrices, and access of function results
-%!error <index \(_,_,5\): but object has size 3x3> eye(3)(2,3,5)
+%!error <index \(_,_,5\): out of bound 1 \(dimensions are 3x3\)> eye(3)(2,3,5)
 %!error <index \(-2,_\): subscripts>               eye(4)(-2,3)
 
 ##  Test cells
@@ -564,14 +564,14 @@
 %!error <abc\(-1,_\): subscripts>              abc(-1,1)
 %!error <abc\(-1,_\): subscripts>              abc(-1,1) = 1
 %!error <sparse indexing needs 1 or 2 indices> abc(0,0,0,0)
-%!error <abc\(4,_\): but abc has size 3x3>     abc(4,1)
+%!error <abc\(4,_\): out of bound 3 \(dimensions are 3x3\)> abc(4,1)
 
 ##  Test ranges
 %!shared abc
 %! abc = 1:10;
 %!error <abc\(-1\): subscripts>             abc(-1)
 %!error <abc\(-1,_\): subscripts>           abc(-1,1)
-%!error <abc\(4,_\): but abc has size 1x10> abc(4,1)
+%!error <abc\(4,_\): out of bound 1 \(dimensions are 1x10\)> abc(4,1)
 
 ##  Test complex
 %!shared abc, z