comparison libinterp/octave-value/ov-base-diag.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 c6224b4e7774
children f90c8372b7ba
comparison
equal deleted inserted replaced
20573:e3c0fee87493 20574:dd6345fd8a97
27 #include <iostream> 27 #include <iostream>
28 28
29 #include "mach-info.h" 29 #include "mach-info.h"
30 #include "lo-ieee.h" 30 #include "lo-ieee.h"
31 31
32 #include "ov-base-diag.h"
32 #include "mxarray.h" 33 #include "mxarray.h"
33 #include "ov-base.h" 34 #include "ov-base.h"
34 #include "ov-base-mat.h" 35 #include "ov-base-mat.h"
35 #include "pr-output.h" 36 #include "pr-output.h"
36 #include "error.h" 37 #include "error.h"
101 { 102 {
102 octave_value retval; 103 octave_value retval;
103 104
104 if (idx.length () == 2 && ! resize_ok) 105 if (idx.length () == 2 && ! resize_ok)
105 { 106 {
106 idx_vector idx0 = idx(0).index_vector (); 107 int k = 0; // index we're accesing when index_vector throws
107 idx_vector idx1 = idx(1).index_vector (); 108 try
108
109 if (idx0.is_scalar () && idx1.is_scalar ())
110 { 109 {
111 retval = matrix.checkelem (idx0(0), idx1(0)); 110 idx_vector idx0 = idx(0).index_vector ();
112 } 111 k = 1;
113 else 112 idx_vector idx1 = idx(1).index_vector ();
114 { 113
115 octave_idx_type m = idx0.length (matrix.rows ()); 114 if (idx0.is_scalar () && idx1.is_scalar ())
116 octave_idx_type n = idx1.length (matrix.columns ());
117 if (idx0.is_colon_equiv (m) && idx1.is_colon_equiv (n)
118 && m <= matrix.rows () && n <= matrix.rows ())
119 { 115 {
120 DMT rm (matrix); 116 retval = matrix.checkelem (idx0(0), idx1(0));
121 rm.resize (m, n);
122 retval = rm;
123 } 117 }
124 else 118 else
125 retval = to_dense ().do_index_op (idx, resize_ok); 119 {
120 octave_idx_type m = idx0.length (matrix.rows ());
121 octave_idx_type n = idx1.length (matrix.columns ());
122 if (idx0.is_colon_equiv (m) && idx1.is_colon_equiv (n)
123 && m <= matrix.rows () && n <= matrix.rows ())
124 {
125 DMT rm (matrix);
126 rm.resize (m, n);
127 retval = rm;
128 }
129 else
130 retval = to_dense ().do_index_op (idx, resize_ok);
131 }
132 }
133 catch (index_exception& e)
134 {
135 // Rethrow to allow more info to be reported later.
136 e.set_pos_if_unset (2, k+1);
137 throw;
126 } 138 }
127 } 139 }
128 else 140 else
129 retval = to_dense ().do_index_op (idx, resize_ok); 141 retval = to_dense ().do_index_op (idx, resize_ok);
130 142
151 // (provided i is a valid index). 163 // (provided i is a valid index).
152 if (jdx.length () == 2 164 if (jdx.length () == 2
153 && jdx(0).is_scalar_type () && jdx(1).is_scalar_type ()) 165 && jdx(0).is_scalar_type () && jdx(1).is_scalar_type ())
154 { 166 {
155 typename DMT::element_type val; 167 typename DMT::element_type val;
156 idx_vector i0 = jdx(0).index_vector (); 168 int k = 0;
157 idx_vector i1 = jdx(1).index_vector (); 169 try
158 if (! error_state && i0(0) == i1(0)
159 && i0(0) < matrix.rows () && i1(0) < matrix.cols ()
160 && chk_valid_scalar (rhs, val))
161 { 170 {
162 matrix.dgelem (i0(0)) = val; 171 idx_vector i0 = jdx(0).index_vector ();
163 retval = this; 172 k = 1;
164 this->count++; 173 idx_vector i1 = jdx(1).index_vector ();
165 // invalidate cache 174 if (! error_state && i0(0) == i1(0)
166 dense_cache = octave_value (); 175 && i0(0) < matrix.rows () && i1(0) < matrix.cols ()
176 && chk_valid_scalar (rhs, val))
177 {
178 matrix.dgelem (i0(0)) = val;
179 retval = this;
180 this->count++;
181 // invalidate cache
182 dense_cache = octave_value ();
183 }
184 }
185 catch (index_exception& e)
186 {
187 // Rethrow to allow more info to be reported later.
188 e.set_pos_if_unset (2, k+1);
189 throw;
167 } 190 }
168 } 191 }
169 192
170 if (! error_state && ! retval.is_defined ()) 193 if (! error_state && ! retval.is_defined ())
171 retval = numeric_assign (type, idx, rhs); 194 retval = numeric_assign (type, idx, rhs);