diff libinterp/corefcn/data.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 4bb41929286b
children a05a0432dff4
line wrap: on
line diff
--- a/libinterp/corefcn/data.cc	Fri Oct 02 12:25:39 2015 -0400
+++ b/libinterp/corefcn/data.cc	Fri Oct 02 15:07:37 2015 -0400
@@ -7244,44 +7244,51 @@
       if (dim < 0)
         dim = argx.dims ().first_non_singleton ();
 
-      idx_vector n = args(1).index_vector ();
-
-      if (error_state)
-        return retval;
-
-      switch (argx.builtin_type ())
+      try
         {
-        case btyp_double:
-          retval = argx.array_value ().nth_element (n, dim);
-          break;
-        case btyp_float:
-          retval = argx.float_array_value ().nth_element (n, dim);
-          break;
-        case btyp_complex:
-          retval = argx.complex_array_value ().nth_element (n, dim);
-          break;
-        case btyp_float_complex:
-          retval = argx.float_complex_array_value ().nth_element (n, dim);
-          break;
+          idx_vector n = args(1).index_vector ();
+
+          if (error_state)
+            return retval;
+
+          switch (argx.builtin_type ())
+            {
+            case btyp_double:
+              retval = argx.array_value ().nth_element (n, dim);
+              break;
+            case btyp_float:
+              retval = argx.float_array_value ().nth_element (n, dim);
+              break;
+            case btyp_complex:
+              retval = argx.complex_array_value ().nth_element (n, dim);
+              break;
+            case btyp_float_complex:
+              retval = argx.float_complex_array_value ().nth_element (n, dim);
+              break;
 #define MAKE_INT_BRANCH(X) \
-        case btyp_ ## X: \
-          retval = argx.X ## _array_value ().nth_element (n, dim); \
-          break;
-
-        MAKE_INT_BRANCH (int8);
-        MAKE_INT_BRANCH (int16);
-        MAKE_INT_BRANCH (int32);
-        MAKE_INT_BRANCH (int64);
-        MAKE_INT_BRANCH (uint8);
-        MAKE_INT_BRANCH (uint16);
-        MAKE_INT_BRANCH (uint32);
-        MAKE_INT_BRANCH (uint64);
+            case btyp_ ## X: \
+              retval = argx.X ## _array_value ().nth_element (n, dim); \
+              break;
+
+            MAKE_INT_BRANCH (int8);
+            MAKE_INT_BRANCH (int16);
+            MAKE_INT_BRANCH (int32);
+            MAKE_INT_BRANCH (int64);
+            MAKE_INT_BRANCH (uint8);
+            MAKE_INT_BRANCH (uint16);
+            MAKE_INT_BRANCH (uint32);
+            MAKE_INT_BRANCH (uint64);
 #undef MAKE_INT_BRANCH
-        default:
-          if (argx.is_cellstr ())
-            retval = argx.cellstr_value ().nth_element (n, dim);
-          else
-            gripe_wrong_type_arg ("nth_element", argx);
+            default:
+              if (argx.is_cellstr ())
+                retval = argx.cellstr_value ().nth_element (n, dim);
+              else
+                gripe_wrong_type_arg ("nth_element", argx);
+            }
+        }
+      catch (index_exception& e)
+        {
+          error ("nth_element: invalid N value %s. %s", e.idx (), e.explain ());
         }
     }
   else
@@ -7323,42 +7330,50 @@
   int nargin = args.length ();
   if (nargin >= 2 && nargin <= 3 && args(0).is_numeric_type ())
     {
-      idx_vector idx = args(0).index_vector ();
-      octave_idx_type n = -1;
-      if (nargin == 3)
-        n = args(2).idx_type_value (true);
-
-      if (! error_state)
+      try
         {
-          octave_value vals = args(1);
-          if (vals.is_range ())
-            {
-              Range r = vals.range_value ();
-              if (r.inc () == 0)
-                vals = r.base ();
-            }
-
-          if (vals.is_single_type ())
+          idx_vector idx = args(0).index_vector ();
+          octave_idx_type n = -1;
+          if (nargin == 3)
+            n = args(2).idx_type_value (true);
+
+          if (! error_state)
             {
-              if (vals.is_complex_type ())
-                retval = do_accumarray_sum (idx,
-                                            vals.float_complex_array_value (),
-                                            n);
+              octave_value vals = args(1);
+              if (vals.is_range ())
+                {
+                  Range r = vals.range_value ();
+                  if (r.inc () == 0)
+                    vals = r.base ();
+                }
+
+              if (vals.is_single_type ())
+                {
+                  if (vals.is_complex_type ())
+                    retval = do_accumarray_sum (idx,
+                                                vals.float_complex_array_value (),
+                                                n);
+                  else
+                    retval = do_accumarray_sum (idx, vals.float_array_value (), n);
+                }
+              else if (vals.is_numeric_type () || vals.is_bool_type ())
+                {
+                  if (vals.is_complex_type ())
+                    retval = do_accumarray_sum (idx,
+                                                vals.complex_array_value (),
+                                                n);
+                  else
+                    retval = do_accumarray_sum (idx, vals.array_value (), n);
+                }
               else
-                retval = do_accumarray_sum (idx, vals.float_array_value (), n);
+                gripe_wrong_type_arg ("accumarray", vals);
             }
-          else if (vals.is_numeric_type () || vals.is_bool_type ())
-            {
-              if (vals.is_complex_type ())
-                retval = do_accumarray_sum (idx,
-                                            vals.complex_array_value (),
-                                            n);
-              else
-                retval = do_accumarray_sum (idx, vals.array_value (), n);
-            }
-          else
-            gripe_wrong_type_arg ("accumarray", vals);
-        }
+          }
+        catch (index_exception& e)
+          {
+            error ("__accumarray_sum__: invalid IDX %s. %s",
+                                        e.idx(), e.explain ());
+          }
     }
   else
     print_usage ();
@@ -7403,60 +7418,69 @@
   int nargin = args.length ();
   if (nargin >= 3 && nargin <= 4 && args(0).is_numeric_type ())
     {
-      idx_vector idx = args(0).index_vector ();
-      octave_idx_type n = -1;
-      if (nargin == 4)
-        n = args(3).idx_type_value (true);
-
-      if (! error_state)
+      try
         {
-          octave_value vals = args(1);
-          octave_value zero = args(2);
-
-          switch (vals.builtin_type ())
+          idx_vector idx = args(0).index_vector ();
+          octave_idx_type n = -1;
+          if (nargin == 4)
+            n = args(3).idx_type_value (true);
+
+          if (! error_state)
             {
-            case btyp_double:
-              retval = do_accumarray_minmax (idx, vals.array_value (), n, ismin,
-                                             zero.double_value ());
-              break;
-            case btyp_float:
-              retval = do_accumarray_minmax (idx, vals.float_array_value (), n,
-                                             ismin, zero.float_value ());
-              break;
-            case btyp_complex:
-              retval = do_accumarray_minmax (idx, vals.complex_array_value (),
-                                             n, ismin, zero.complex_value ());
-              break;
-            case btyp_float_complex:
-              retval = do_accumarray_minmax (idx,
-                                             vals.float_complex_array_value (),
-                                             n, ismin,
-                                             zero.float_complex_value ());
-              break;
+              octave_value vals = args(1);
+              octave_value zero = args(2);
+
+              switch (vals.builtin_type ())
+                {
+                case btyp_double:
+                  retval = do_accumarray_minmax (idx, vals.array_value (), n, ismin,
+                                                 zero.double_value ());
+                  break;
+                case btyp_float:
+                  retval = do_accumarray_minmax (idx, vals.float_array_value (), n,
+                                                 ismin, zero.float_value ());
+                  break;
+                case btyp_complex:
+                  retval = do_accumarray_minmax (idx, vals.complex_array_value (),
+                                                 n, ismin, zero.complex_value ());
+                  break;
+                case btyp_float_complex:
+                  retval = do_accumarray_minmax (idx,
+                                                 vals.float_complex_array_value (),
+                                                 n, ismin,
+                                                 zero.float_complex_value ());
+                  break;
 #define MAKE_INT_BRANCH(X) \
-            case btyp_ ## X: \
-              retval = do_accumarray_minmax (idx, vals.X ## _array_value (), \
-                                             n, ismin, \
-                                             zero.X ## _scalar_value ()); \
-              break;
-
-            MAKE_INT_BRANCH (int8);
-            MAKE_INT_BRANCH (int16);
-            MAKE_INT_BRANCH (int32);
-            MAKE_INT_BRANCH (int64);
-            MAKE_INT_BRANCH (uint8);
-            MAKE_INT_BRANCH (uint16);
-            MAKE_INT_BRANCH (uint32);
-            MAKE_INT_BRANCH (uint64);
+                case btyp_ ## X: \
+                  retval = do_accumarray_minmax (idx, vals.X ## _array_value (), \
+                                                 n, ismin, \
+                                                 zero.X ## _scalar_value ()); \
+                  break;
+
+                MAKE_INT_BRANCH (int8);
+                MAKE_INT_BRANCH (int16);
+                MAKE_INT_BRANCH (int32);
+                MAKE_INT_BRANCH (int64);
+                MAKE_INT_BRANCH (uint8);
+                MAKE_INT_BRANCH (uint16);
+                MAKE_INT_BRANCH (uint32);
+                MAKE_INT_BRANCH (uint64);
 #undef MAKE_INT_BRANCH
-            case btyp_bool:
-              retval = do_accumarray_minmax (idx, vals.array_value (), n, ismin,
-                                             zero.bool_value ());
-              break;
-            default:
-              gripe_wrong_type_arg ("accumarray", vals);
+                case btyp_bool:
+                  retval = do_accumarray_minmax (idx, vals.array_value (), n, ismin,
+                                                 zero.bool_value ());
+                  break;
+                default:
+                  gripe_wrong_type_arg ("accumarray", vals);
+                }
             }
         }
+      catch (index_exception& e)
+        {
+          error ("do_accumarray_minmax_fun: invalid index %s. %s",
+                                        e.idx (), e.explain ());
+        }
+
     }
   else
     print_usage ();
@@ -7523,39 +7547,46 @@
   int nargin = args.length ();
   if (nargin >= 2 && nargin <= 4 && args(0).is_numeric_type ())
     {
-      idx_vector idx = args(0).index_vector ();
-      int dim = -1;
-      if (nargin >= 3)
-        dim = args(2).int_value () - 1;
-
-      octave_idx_type n = -1;
-      if (nargin == 4)
-        n = args(3).idx_type_value (true);
-
-      if (! error_state)
+      try
         {
-          octave_value vals = args(1);
-
-          if (vals.is_single_type ())
+          idx_vector idx = args(0).index_vector ();
+          int dim = -1;
+          if (nargin >= 3)
+            dim = args(2).int_value () - 1;
+
+          octave_idx_type n = -1;
+          if (nargin == 4)
+            n = args(3).idx_type_value (true);
+
+          if (! error_state)
             {
-              if (vals.is_complex_type ())
-                retval = do_accumdim_sum (idx,
-                                          vals.float_complex_array_value (),
-                                          dim, n);
+              octave_value vals = args(1);
+
+              if (vals.is_single_type ())
+                {
+                  if (vals.is_complex_type ())
+                    retval = do_accumdim_sum (idx,
+                                              vals.float_complex_array_value (),
+                                              dim, n);
+                  else
+                    retval = do_accumdim_sum (idx, vals.float_array_value (),
+                                              dim, n);
+                }
+              else if (vals.is_numeric_type () || vals.is_bool_type ())
+                {
+                  if (vals.is_complex_type ())
+                    retval = do_accumdim_sum (idx, vals.complex_array_value (),
+                                              dim, n);
+                  else
+                    retval = do_accumdim_sum (idx, vals.array_value (), dim, n);
+                }
               else
-                retval = do_accumdim_sum (idx, vals.float_array_value (),
-                                          dim, n);
+                gripe_wrong_type_arg ("accumdim", vals);
             }
-          else if (vals.is_numeric_type () || vals.is_bool_type ())
-            {
-              if (vals.is_complex_type ())
-                retval = do_accumdim_sum (idx, vals.complex_array_value (),
-                                          dim, n);
-              else
-                retval = do_accumdim_sum (idx, vals.array_value (), dim, n);
-            }
-          else
-            gripe_wrong_type_arg ("accumdim", vals);
+        }
+      catch (index_exception& e)
+        {
+          error ("__accumdim_sum__: invalid IDX %s. %s", e.idx(), e.explain ());
         }
     }
   else