Mercurial > octave-nkf
comparison libinterp/octave-value/ov-base-sparse.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 |
---|---|
42 #include "boolSparse.h" | 42 #include "boolSparse.h" |
43 #include "ov-base-sparse.h" | 43 #include "ov-base-sparse.h" |
44 #include "pager.h" | 44 #include "pager.h" |
45 #include "utils.h" | 45 #include "utils.h" |
46 | 46 |
47 #include "lo-array-gripes.h" | |
48 | |
47 template <class T> | 49 template <class T> |
48 octave_value | 50 octave_value |
49 octave_base_sparse<T>::do_index_op (const octave_value_list& idx, | 51 octave_base_sparse<T>::do_index_op (const octave_value_list& idx, |
50 bool resize_ok) | 52 bool resize_ok) |
51 { | 53 { |
52 octave_value retval; | 54 octave_value retval; |
53 | 55 |
54 octave_idx_type n_idx = idx.length (); | 56 octave_idx_type n_idx = idx.length (); |
55 | 57 |
56 switch (n_idx) | 58 // If we catch an indexing error in index_vector, we flag an error in |
57 { | 59 // index k. Ensure it is the right value befor each idx_vector call. |
58 case 0: | 60 // Same variable as used in the for loop in the default case. |
59 retval = matrix; | 61 |
60 break; | 62 octave_idx_type k = 0; |
61 | 63 |
62 case 1: | 64 try |
63 { | 65 { |
64 idx_vector i = idx (0).index_vector (); | 66 switch (n_idx) |
65 | 67 { |
66 if (! error_state) | 68 case 0: |
67 retval = octave_value (matrix.index (i, resize_ok)); | 69 retval = matrix; |
68 } | 70 break; |
69 break; | 71 |
70 | 72 case 1: |
71 case 2: | 73 { |
72 { | 74 idx_vector i = idx (0).index_vector (); |
73 idx_vector i = idx (0).index_vector (); | |
74 | |
75 if (! error_state) | |
76 { | |
77 idx_vector j = idx (1).index_vector (); | |
78 | 75 |
79 if (! error_state) | 76 if (! error_state) |
80 retval = octave_value (matrix.index (i, j, resize_ok)); | 77 retval = octave_value (matrix.index (i, resize_ok)); |
81 } | 78 } |
82 } | 79 break; |
83 break; | 80 |
84 default: | 81 case 2: |
85 error ("sparse indexing needs 1 or 2 indices"); | 82 { |
83 idx_vector i = idx (0).index_vector (); | |
84 | |
85 if (! error_state) | |
86 { | |
87 k = 1; | |
88 idx_vector j = idx (1).index_vector (); | |
89 | |
90 if (! error_state) | |
91 retval = octave_value (matrix.index (i, j, resize_ok)); | |
92 } | |
93 } | |
94 break; | |
95 default: | |
96 error ("sparse indexing needs 1 or 2 indices"); | |
97 } | |
98 } | |
99 catch (index_exception& e) | |
100 { | |
101 // Rethrow to allow more info to be reported later. | |
102 e.set_pos_if_unset (n_idx, k+1); | |
103 throw; | |
86 } | 104 } |
87 | 105 |
88 return retval; | 106 return retval; |
89 } | 107 } |
90 | 108 |
168 octave_base_sparse<T>::assign (const octave_value_list& idx, const T& rhs) | 186 octave_base_sparse<T>::assign (const octave_value_list& idx, const T& rhs) |
169 { | 187 { |
170 | 188 |
171 octave_idx_type len = idx.length (); | 189 octave_idx_type len = idx.length (); |
172 | 190 |
173 switch (len) | 191 // If we catch an indexing error in index_vector, we flag an error in |
174 { | 192 // index k. Ensure it is the right value befor each idx_vector call. |
175 case 1: | 193 // Same variable as used in the for loop in the default case. |
176 { | 194 |
177 idx_vector i = idx (0).index_vector (); | 195 octave_idx_type k = 0; |
178 | 196 |
179 if (! error_state) | 197 try |
180 matrix.assign (i, rhs); | 198 { |
181 | 199 switch (len) |
182 break; | 200 { |
183 } | 201 case 1: |
184 | 202 { |
185 case 2: | 203 idx_vector i = idx (0).index_vector (); |
186 { | |
187 idx_vector i = idx (0).index_vector (); | |
188 | |
189 if (! error_state) | |
190 { | |
191 idx_vector j = idx (1).index_vector (); | |
192 | 204 |
193 if (! error_state) | 205 if (! error_state) |
194 matrix.assign (i, j, rhs); | 206 matrix.assign (i, rhs); |
195 } | 207 |
196 | 208 break; |
197 break; | 209 } |
198 } | 210 |
199 | 211 case 2: |
200 default: | 212 { |
201 error ("sparse indexing needs 1 or 2 indices"); | 213 idx_vector i = idx (0).index_vector (); |
214 | |
215 if (! error_state) | |
216 { | |
217 k = 1; | |
218 idx_vector j = idx (1).index_vector (); | |
219 | |
220 if (! error_state) | |
221 matrix.assign (i, j, rhs); | |
222 } | |
223 break; | |
224 } | |
225 | |
226 default: | |
227 error ("sparse indexing needs 1 or 2 indices"); | |
228 } | |
229 } | |
230 catch (index_exception& e) | |
231 { | |
232 // Rethrow to allow more info to be reported later. | |
233 e.set_pos_if_unset (len, k+1); | |
234 throw; | |
202 } | 235 } |
203 | 236 |
204 | 237 |
205 // Invalidate matrix type. | 238 // Invalidate matrix type. |
206 typ.invalidate_type (); | 239 typ.invalidate_type (); |
210 void | 243 void |
211 octave_base_sparse<MT>::delete_elements (const octave_value_list& idx) | 244 octave_base_sparse<MT>::delete_elements (const octave_value_list& idx) |
212 { | 245 { |
213 octave_idx_type len = idx.length (); | 246 octave_idx_type len = idx.length (); |
214 | 247 |
215 switch (len) | 248 // If we catch an indexing error in index_vector, we flag an error in |
216 { | 249 // index k. Ensure it is the right value befor each idx_vector call. |
217 case 1: | 250 // Same variable as used in the for loop in the default case. |
218 { | 251 |
219 idx_vector i = idx (0).index_vector (); | 252 octave_idx_type k = 0; |
220 | 253 |
221 if (! error_state) | 254 try |
222 matrix.delete_elements (i); | 255 { |
223 | 256 switch (len) |
224 break; | 257 { |
225 } | 258 case 1: |
226 | 259 { |
227 case 2: | 260 idx_vector i = idx (0).index_vector (); |
228 { | |
229 idx_vector i = idx (0).index_vector (); | |
230 | |
231 if (! error_state) | |
232 { | |
233 idx_vector j = idx (1).index_vector (); | |
234 | 261 |
235 if (! error_state) | 262 if (! error_state) |
236 matrix.delete_elements (i, j); | 263 matrix.delete_elements (i); |
237 } | 264 |
238 | 265 break; |
239 break; | 266 } |
240 } | 267 |
241 | 268 case 2: |
242 default: | 269 { |
243 error ("sparse indexing needs 1 or 2 indices"); | 270 idx_vector i = idx (0).index_vector (); |
271 | |
272 if (! error_state) | |
273 { | |
274 k = 1; | |
275 idx_vector j = idx (1).index_vector (); | |
276 | |
277 if (! error_state) | |
278 matrix.delete_elements (i, j); | |
279 } | |
280 | |
281 break; | |
282 } | |
283 | |
284 default: | |
285 error ("sparse indexing needs 1 or 2 indices"); | |
286 } | |
287 } | |
288 catch (index_exception& e) | |
289 { | |
290 // Rethrow to allow more info to be reported later. | |
291 e.set_pos_if_unset (len, k+1); | |
292 throw; | |
244 } | 293 } |
245 | 294 |
246 // Invalidate the matrix type | 295 // Invalidate the matrix type |
247 typ.invalidate_type (); | 296 typ.invalidate_type (); |
248 } | 297 } |