diff liboctave/array/Array-util.cc @ 20574:dd6345fd8a97

use exceptions for better invalid index error reporting (bug #45957) * lo-array-gripes.h, lo-array-gripes.cc (index_exception): New base class for indexing errors. (invalid_index, out_of_range): New classes. (gripe_index_out_of_range): New overloaded function. (gripe_invalid_index): New overloaded functions. Delete version with no arguments. (gripe_invalid_assignment_size, gripe_assignment_dimension_mismatch): Delete. Change uses of gripe functions as needed. * Cell.cc (Cell::index, Cell::assign, Cell::delete_elements): Use exceptions to collect error info about and handle indexing errors. * data.cc (Fnth_element, do_accumarray_sum, F__accumarray_sum__, do_accumarray_minmax, do_accumarray_minmax_fun, F__accumdim_sum__): Likewise. * oct-map.cc (octave_map::index, octave_map::assign, octave_map::delete_elements): Likewise. * sparse.cc (Fsparse): Likewise. * sub2ind.cc (Fsub2ind, Find2sub): Likewise. New tests. * utils.cc (dims_to_numel): Likewise. * ov-base-diag.cc (octave_base_diag<DMT, MT>::do_index_op, octave_base_diag<DMT, MT>::subsasgn): Likewise. * ov-base-mat.cc (octave_base_matrix<MT>::subsref, octave_base_matrix<MT>::assign): Likewise. * ov-base-sparse.cc (octave_base_sparse<T>::do_index_op, octave_base_sparse<T>::assign, octave_base_sparse<MT>::delete_elements): Likewise. * ov-classdef.cc (cdef_object_array::subsref, cdef_object_array::subsasgn): Likewise. * ov-java.cc (make_java_index): Likewise. * ov-perm.cc (octave_perm_matrix::do_index_op): Likewise. * ov-range.cc (octave_range::do_index_op): Likewise. * ov-re-diag.cc (octave_diag_matrix::do_index_op): Likewise. * ov-str-mat.cc (octave_char_matrix_str::do_index_op_internal): Likewise. * pt-assign.cc (tree_simple_assignment::rvalue1): Likewise. * pt-idx.cc (tree_index_expression::rvalue, tree_index_expression::lvalue): Likewise. * Array-util.cc (sub2ind): Likewise. * toplev.cc (main_loop): Also catch unhandled index_exception exceptions. * ov-base.cc (octave_base_value::index_vector): Improve error message. * ov-re-sparse.cc (octave_sparse_matrix::index_vector): Likewise. * ov-complex.cc (complex_index): New class. (gripe_complex_index): New function. (octave_complex::index_vector): Use it. * pt-id.h, pt-id.cc (tree_identifier::is_variable, tree_black_hole::is_variable): Now const. * pt-idx.cc (final_index_error): New static function. (tree_index_expression::rvalue, tree_index_expression::lvalue): Use it. * index.tst: New tests.
author Lachlan Andrew <lachlanbis@gmail.com>
date Fri, 02 Oct 2015 15:07:37 -0400
parents a9574e3c6e9e
children
line wrap: on
line diff
--- a/liboctave/array/Array-util.cc	Fri Oct 02 12:25:39 2015 -0400
+++ b/liboctave/array/Array-util.cc	Fri Oct 02 15:07:37 2015 -0400
@@ -178,9 +178,9 @@
 compute_index (octave_idx_type n, const dim_vector& dims)
 {
   if (n < 0)
-    gripe_invalid_index ();
+    gripe_invalid_index (n, 1, 1);
   if (n >= dims.numel ())
-    gripe_index_out_of_range (1, 1, n+1, dims.numel ());
+    gripe_index_out_of_range (1, 1, n+1, dims.numel (), dims);
 
   return n;
 }
@@ -188,12 +188,14 @@
 octave_idx_type
 compute_index (octave_idx_type i, octave_idx_type j, const dim_vector& dims)
 {
-  if (i < 0 || j < 0)
-    gripe_invalid_index ();
+  if (i < 0)
+    gripe_invalid_index (i, 2, 1);
+  else if (j < 0)
+    gripe_invalid_index (j, 2, 2);
   if (i >= dims(0))
-    gripe_index_out_of_range (2, 1, i+1, dims(0));
+    gripe_index_out_of_range (2, 1, i+1, dims(0), dims);
   if (j >= dims.numel (1))
-    gripe_index_out_of_range (2, 2, j+1, dims.numel (1));
+    gripe_index_out_of_range (2, 2, j+1, dims.numel (1), dims);
 
   return j*dims(0) + i;
 }
@@ -202,14 +204,18 @@
 compute_index (octave_idx_type i, octave_idx_type j, octave_idx_type k,
                const dim_vector& dims)
 {
-  if (i < 0 || j < 0 || k < 0)
-    gripe_invalid_index ();
+  if (i < 0)
+    gripe_invalid_index (i, 3, 1);
+  else if (j < 0)
+    gripe_invalid_index (j, 3, 2);
+  else if (k < 0)
+    gripe_invalid_index (k, 3, 3);
   if (i >= dims(0))
-    gripe_index_out_of_range (3, 1, i+1, dims(0));
+    gripe_index_out_of_range (3, 1, i+1, dims(0), dims);
   if (j >= dims(1))
-    gripe_index_out_of_range (3, 2, j+1, dims(1));
+    gripe_index_out_of_range (3, 2, j+1, dims(1), dims);
   if (k >= dims.numel (2))
-    gripe_index_out_of_range (3, 3, k+1, dims.numel (2));
+    gripe_index_out_of_range (3, 3, k+1, dims.numel (2), dims);
 
   return (k*dims(1) + j)*dims(0) + i;
 }
@@ -222,9 +228,9 @@
   for (int d = 0; d < nd; d++)
     {
       if (ra_idx(d) < 0)
-        gripe_invalid_index ();
+        gripe_invalid_index (ra_idx(d), nd, d+1);
       if (ra_idx(d) >= dv(d))
-        gripe_index_out_of_range (nd, d+1, ra_idx(d)+1, dv(d));
+        gripe_index_out_of_range (nd, d+1, ra_idx(d)+1, dv(d), dims);
     }
 
   return dv.compute_index (ra_idx.data ());
@@ -540,18 +546,29 @@
 
       for (octave_idx_type i = 0; i < len; i++)
         {
-          idx_vector idx = idxa(i);
-          octave_idx_type n = dvx(i);
+          try
+            {
+              idx_vector idx = idxa(i);
+              octave_idx_type n = dvx(i);
+
+              all_ranges = all_ranges && idx.is_range ();
+              if (clen < 0)
+                clen = idx.length (n);
+              else if (clen != idx.length (n))
+                current_liboctave_error_handler ("sub2ind: lengths of indices must match");
 
-          all_ranges = all_ranges && idx.is_range ();
-          if (clen < 0)
-            clen = idx.length (n);
-          else if (clen != idx.length (n))
-            current_liboctave_error_handler ("sub2ind: lengths of indices must match");
+              if (idx.extent (n) > n)
+                  gripe_index_out_of_range (len, i+1, idx.extent (n), n);
+            }
+          catch (index_exception& e)
+            {
+              e.set_pos_if_unset (len, i+1);
+              e.set_var ("");           // no particular variable
+              (*current_liboctave_error_with_id_handler) (e.id(), e.err());
+            }
+        }
+      // idxa known to be valid. Shouldn't need to catch index_exception below here.
 
-          if (idx.extent (n) > n)
-            current_liboctave_error_handler ("sub2ind: index out of range");
-        }
 
       if (len == 1)
         retval = idxa(0);