Mercurial > octave-nkf
comparison libinterp/corefcn/oct-map.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 | 1a0a433c8263 |
comparison
equal
deleted
inserted
replaced
20573:e3c0fee87493 | 20574:dd6345fd8a97 |
---|---|
898 octave_map::index (const octave_value_list& idx, bool resize_ok) const | 898 octave_map::index (const octave_value_list& idx, bool resize_ok) const |
899 { | 899 { |
900 octave_idx_type n_idx = idx.length (); | 900 octave_idx_type n_idx = idx.length (); |
901 octave_map retval; | 901 octave_map retval; |
902 | 902 |
903 switch (n_idx) | 903 // If we catch an indexing error in index_vector, we flag an error in |
904 { | 904 // index k. Ensure it is the right value befor each idx_vector call. |
905 case 1: | 905 // Same variable as used in the for loop in the default case. |
906 { | 906 |
907 idx_vector i = idx(0).index_vector (); | 907 octave_idx_type k = 0; |
908 | 908 |
909 if (! error_state) | 909 try |
910 retval = index (i, resize_ok); | 910 { |
911 } | 911 switch (n_idx) |
912 break; | 912 { |
913 | 913 case 1: |
914 case 2: | |
915 { | |
916 idx_vector i = idx(0).index_vector (); | |
917 | |
918 if (! error_state) | |
919 { | 914 { |
920 idx_vector j = idx(1).index_vector (); | 915 idx_vector i = idx(0).index_vector (); |
921 | 916 |
922 retval = index (i, j, resize_ok); | 917 if (! error_state) |
918 retval = index (i, resize_ok); | |
923 } | 919 } |
924 } | 920 break; |
925 break; | 921 |
926 | 922 case 2: |
927 default: | |
928 { | |
929 Array<idx_vector> ia (dim_vector (n_idx, 1)); | |
930 | |
931 for (octave_idx_type i = 0; i < n_idx; i++) | |
932 { | 923 { |
933 ia(i) = idx(i).index_vector (); | 924 idx_vector i = idx(0).index_vector (); |
934 | 925 |
935 if (error_state) | 926 if (! error_state) |
936 break; | 927 { |
928 k = 1; | |
929 idx_vector j = idx(1).index_vector (); | |
930 | |
931 retval = index (i, j, resize_ok); | |
932 } | |
937 } | 933 } |
938 | 934 break; |
939 if (! error_state) | 935 |
940 retval = index (ia, resize_ok); | 936 default: |
941 } | 937 { |
942 break; | 938 Array<idx_vector> ia (dim_vector (n_idx, 1)); |
939 | |
940 for (k = 0; k < n_idx; k++) | |
941 { | |
942 ia(k) = idx(k).index_vector (); | |
943 | |
944 if (error_state) | |
945 break; | |
946 } | |
947 | |
948 if (! error_state) | |
949 retval = index (ia, resize_ok); | |
950 } | |
951 break; | |
952 } | |
953 } | |
954 catch (index_exception& e) | |
955 { | |
956 // Rethrow to allow more info to be reported later. | |
957 e.set_pos_if_unset (n_idx, k+1); | |
958 throw; | |
943 } | 959 } |
944 | 960 |
945 return retval; | 961 return retval; |
946 } | 962 } |
947 | 963 |
1092 void | 1108 void |
1093 octave_map::assign (const octave_value_list& idx, const octave_map& rhs) | 1109 octave_map::assign (const octave_value_list& idx, const octave_map& rhs) |
1094 { | 1110 { |
1095 octave_idx_type n_idx = idx.length (); | 1111 octave_idx_type n_idx = idx.length (); |
1096 | 1112 |
1097 switch (n_idx) | 1113 // If we catch an indexing error in index_vector, we flag an error in |
1098 { | 1114 // index k. Ensure it is the right value befor each idx_vector call. |
1099 case 1: | 1115 // Same variable as used in the for loop in the default case. |
1100 { | 1116 |
1101 idx_vector i = idx(0).index_vector (); | 1117 octave_idx_type k = 0; |
1102 | 1118 |
1103 if (! error_state) | 1119 try |
1104 assign (i, rhs); | 1120 { |
1105 } | 1121 switch (n_idx) |
1106 break; | 1122 { |
1107 | 1123 case 1: |
1108 case 2: | |
1109 { | |
1110 idx_vector i = idx(0).index_vector (); | |
1111 | |
1112 if (! error_state) | |
1113 { | 1124 { |
1114 idx_vector j = idx(1).index_vector (); | 1125 idx_vector i = idx(0).index_vector (); |
1115 | 1126 |
1116 assign (i, j, rhs); | 1127 if (! error_state) |
1128 assign (i, rhs); | |
1117 } | 1129 } |
1118 } | 1130 break; |
1119 break; | 1131 |
1120 | 1132 case 2: |
1121 default: | |
1122 { | |
1123 Array<idx_vector> ia (dim_vector (n_idx, 1)); | |
1124 | |
1125 for (octave_idx_type i = 0; i < n_idx; i++) | |
1126 { | 1133 { |
1127 ia(i) = idx(i).index_vector (); | 1134 idx_vector i = idx(0).index_vector (); |
1128 | 1135 |
1129 if (error_state) | 1136 if (! error_state) |
1130 break; | 1137 { |
1138 k = 1; | |
1139 idx_vector j = idx(1).index_vector (); | |
1140 | |
1141 assign (i, j, rhs); | |
1142 } | |
1131 } | 1143 } |
1132 | 1144 break; |
1133 if (! error_state) | 1145 |
1134 assign (ia, rhs); | 1146 default: |
1135 } | 1147 { |
1136 break; | 1148 Array<idx_vector> ia (dim_vector (n_idx, 1)); |
1149 | |
1150 for (k = 0; k < n_idx; k++) | |
1151 { | |
1152 ia(k) = idx(k).index_vector (); | |
1153 | |
1154 if (error_state) | |
1155 break; | |
1156 } | |
1157 | |
1158 if (! error_state) | |
1159 assign (ia, rhs); | |
1160 } | |
1161 break; | |
1162 } | |
1163 } | |
1164 catch (index_exception& e) | |
1165 { | |
1166 // Rethrow to allow more info to be reported later. | |
1167 e.set_pos_if_unset (n_idx, k+1); | |
1168 throw; | |
1137 } | 1169 } |
1138 } | 1170 } |
1139 | 1171 |
1140 void | 1172 void |
1141 octave_map::assign (const octave_value_list& idx, const std::string& k, | 1173 octave_map::assign (const octave_value_list& idx, const std::string& k, |
1242 | 1274 |
1243 Array<idx_vector> ia (dim_vector (n_idx, 1)); | 1275 Array<idx_vector> ia (dim_vector (n_idx, 1)); |
1244 | 1276 |
1245 for (octave_idx_type i = 0; i < n_idx; i++) | 1277 for (octave_idx_type i = 0; i < n_idx; i++) |
1246 { | 1278 { |
1247 ia(i) = idx(i).index_vector (); | 1279 try |
1280 { | |
1281 ia(i) = idx(i).index_vector (); | |
1282 } | |
1283 catch (index_exception& e) | |
1284 { | |
1285 // Rethrow to allow more info to be reported later. | |
1286 e.set_pos_if_unset (n_idx, i+1); | |
1287 throw; | |
1288 } | |
1248 | 1289 |
1249 if (error_state) | 1290 if (error_state) |
1250 break; | 1291 break; |
1251 } | 1292 } |
1252 | 1293 |