diff options
| author | Paul Eggert | 2014-04-01 13:18:12 -0700 |
|---|---|---|
| committer | Paul Eggert | 2014-04-01 13:18:12 -0700 |
| commit | 8ec49c53c67cfaee550f275c1a8b68d65b9b606f (patch) | |
| tree | 570a656b003ee5de09623df3a8d89f3fd1112e11 /src | |
| parent | 21c625fdd0fffffb8420ec25fbcba1aed7e05248 (diff) | |
| download | emacs-8ec49c53c67cfaee550f275c1a8b68d65b9b606f.tar.gz emacs-8ec49c53c67cfaee550f275c1a8b68d65b9b606f.zip | |
* fns.c (validate_subarray): Rename from validate_substring,
since it works for vectors too. New arg ARRAY. Optimize for the
non-nil case. Instead of returning bool, throw an error if out of
range, so that the caller needn't do that. All uses changed.
Report original values if out of range.
(Fsubstring, Fsubstring_no_properties, secure_hash):
Also optimize the case where FROM is 0 or TO is the size.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 10 | ||||
| -rw-r--r-- | src/fns.c | 95 |
2 files changed, 59 insertions, 46 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 773a09121fd..6889fa9b4e6 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,13 @@ | |||
| 1 | 2014-04-01 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | * fns.c (validate_subarray): Rename from validate_substring, | ||
| 4 | since it works for vectors too. New arg ARRAY. Optimize for the | ||
| 5 | non-nil case. Instead of returning bool, throw an error if out of | ||
| 6 | range, so that the caller needn't do that. All uses changed. | ||
| 7 | Report original values if out of range. | ||
| 8 | (Fsubstring, Fsubstring_no_properties, secure_hash): | ||
| 9 | Also optimize the case where FROM is 0 or TO is the size. | ||
| 10 | |||
| 1 | 2014-03-31 Dmitry Antipov <dmantipov@yandex.ru> | 11 | 2014-03-31 Dmitry Antipov <dmantipov@yandex.ru> |
| 2 | 12 | ||
| 3 | * search.c (Freplace_match): Use make_specified_string. | 13 | * search.c (Freplace_match): Use make_specified_string. |
| @@ -1127,36 +1127,45 @@ Elements of ALIST that are not conses are also shared. */) | |||
| 1127 | return alist; | 1127 | return alist; |
| 1128 | } | 1128 | } |
| 1129 | 1129 | ||
| 1130 | /* True if [FROM..TO) specifies a valid substring of SIZE-characters string. | 1130 | /* Check that ARRAY can have a valid subarray [FROM..TO), |
| 1131 | If FROM is nil, 0 assumed. If TO is nil, SIZE assumed. Negative | 1131 | given that its size is SIZE. |
| 1132 | values are counted from the end. *FROM_CHAR and *TO_CHAR are updated | 1132 | If FROM is nil, use 0; if TO is nil, use SIZE. |
| 1133 | with corresponding C values of TO and FROM. */ | 1133 | Count negative values backwards from the end. |
| 1134 | Set *IFROM and *ITO to the two indexes used. */ | ||
| 1134 | 1135 | ||
| 1135 | static bool | 1136 | static void |
| 1136 | validate_substring (Lisp_Object from, Lisp_Object to, ptrdiff_t size, | 1137 | validate_subarray (Lisp_Object array, Lisp_Object from, Lisp_Object to, |
| 1137 | EMACS_INT *from_char, EMACS_INT *to_char) | 1138 | ptrdiff_t size, EMACS_INT *ifrom, EMACS_INT *ito) |
| 1138 | { | 1139 | { |
| 1139 | if (NILP (from)) | 1140 | EMACS_INT f, t; |
| 1140 | *from_char = 0; | 1141 | |
| 1141 | else | 1142 | if (INTEGERP (from)) |
| 1142 | { | 1143 | { |
| 1143 | CHECK_NUMBER (from); | 1144 | f = XINT (from); |
| 1144 | *from_char = XINT (from); | 1145 | if (f < 0) |
| 1145 | if (*from_char < 0) | 1146 | f += size; |
| 1146 | *from_char += size; | ||
| 1147 | } | 1147 | } |
| 1148 | 1148 | else if (NILP (from)) | |
| 1149 | if (NILP (to)) | 1149 | f = 0; |
| 1150 | *to_char = size; | ||
| 1151 | else | 1150 | else |
| 1151 | wrong_type_argument (Qintegerp, from); | ||
| 1152 | |||
| 1153 | if (INTEGERP (to)) | ||
| 1152 | { | 1154 | { |
| 1153 | CHECK_NUMBER (to); | 1155 | t = XINT (to); |
| 1154 | *to_char = XINT (to); | 1156 | if (t < 0) |
| 1155 | if (*to_char < 0) | 1157 | t += size; |
| 1156 | *to_char += size; | ||
| 1157 | } | 1158 | } |
| 1159 | else if (NILP (to)) | ||
| 1160 | t = size; | ||
| 1161 | else | ||
| 1162 | wrong_type_argument (Qintegerp, to); | ||
| 1163 | |||
| 1164 | if (! (0 <= f && f <= t && t <= size)) | ||
| 1165 | args_out_of_range_3 (array, from, to); | ||
| 1158 | 1166 | ||
| 1159 | return (0 <= *from_char && *from_char <= *to_char && *to_char <= size); | 1167 | *ifrom = f; |
| 1168 | *ito = t; | ||
| 1160 | } | 1169 | } |
| 1161 | 1170 | ||
| 1162 | DEFUN ("substring", Fsubstring, Ssubstring, 1, 3, 0, | 1171 | DEFUN ("substring", Fsubstring, Ssubstring, 1, 3, 0, |
| @@ -1176,7 +1185,7 @@ With one argument, just copy STRING (with properties, if any). */) | |||
| 1176 | { | 1185 | { |
| 1177 | Lisp_Object res; | 1186 | Lisp_Object res; |
| 1178 | ptrdiff_t size; | 1187 | ptrdiff_t size; |
| 1179 | EMACS_INT from_char, to_char; | 1188 | EMACS_INT ifrom, ito; |
| 1180 | 1189 | ||
| 1181 | if (STRINGP (string)) | 1190 | if (STRINGP (string)) |
| 1182 | size = SCHARS (string); | 1191 | size = SCHARS (string); |
| @@ -1184,24 +1193,23 @@ With one argument, just copy STRING (with properties, if any). */) | |||
| 1184 | size = ASIZE (string); | 1193 | size = ASIZE (string); |
| 1185 | else | 1194 | else |
| 1186 | wrong_type_argument (Qarrayp, string); | 1195 | wrong_type_argument (Qarrayp, string); |
| 1187 | 1196 | ||
| 1188 | if (!validate_substring (from, to, size, &from_char, &to_char)) | 1197 | validate_subarray (string, from, to, size, &ifrom, &ito); |
| 1189 | args_out_of_range_3 (string, make_number (from_char), | ||
| 1190 | make_number (to_char)); | ||
| 1191 | 1198 | ||
| 1192 | if (STRINGP (string)) | 1199 | if (STRINGP (string)) |
| 1193 | { | 1200 | { |
| 1194 | ptrdiff_t to_byte = | 1201 | ptrdiff_t from_byte |
| 1195 | (NILP (to) ? SBYTES (string) : string_char_to_byte (string, to_char)); | 1202 | = !ifrom ? 0 : string_char_to_byte (string, ifrom); |
| 1196 | ptrdiff_t from_byte = string_char_to_byte (string, from_char); | 1203 | ptrdiff_t to_byte |
| 1204 | = ito == size ? SBYTES (string) : string_char_to_byte (string, ito); | ||
| 1197 | res = make_specified_string (SSDATA (string) + from_byte, | 1205 | res = make_specified_string (SSDATA (string) + from_byte, |
| 1198 | to_char - from_char, to_byte - from_byte, | 1206 | ito - ifrom, to_byte - from_byte, |
| 1199 | STRING_MULTIBYTE (string)); | 1207 | STRING_MULTIBYTE (string)); |
| 1200 | copy_text_properties (make_number (from_char), make_number (to_char), | 1208 | copy_text_properties (make_number (ifrom), make_number (ito), |
| 1201 | string, make_number (0), res, Qnil); | 1209 | string, make_number (0), res, Qnil); |
| 1202 | } | 1210 | } |
| 1203 | else | 1211 | else |
| 1204 | res = Fvector (to_char - from_char, aref_addr (string, from_char)); | 1212 | res = Fvector (ito - ifrom, aref_addr (string, ifrom)); |
| 1205 | 1213 | ||
| 1206 | return res; | 1214 | return res; |
| 1207 | } | 1215 | } |
| @@ -1224,14 +1232,11 @@ With one argument, just copy STRING without its properties. */) | |||
| 1224 | CHECK_STRING (string); | 1232 | CHECK_STRING (string); |
| 1225 | 1233 | ||
| 1226 | size = SCHARS (string); | 1234 | size = SCHARS (string); |
| 1235 | validate_subarray (string, from, to, size, &from_char, &to_char); | ||
| 1227 | 1236 | ||
| 1228 | if (!validate_substring (from, to, size, &from_char, &to_char)) | 1237 | from_byte = !from_char ? 0 : string_char_to_byte (string, from_char); |
| 1229 | args_out_of_range_3 (string, make_number (from_char), | ||
| 1230 | make_number (to_char)); | ||
| 1231 | |||
| 1232 | from_byte = NILP (from) ? 0 : string_char_to_byte (string, from_char); | ||
| 1233 | to_byte = | 1238 | to_byte = |
| 1234 | NILP (to) ? SBYTES (string) : string_char_to_byte (string, to_char); | 1239 | to_char == size ? SBYTES (string) : string_char_to_byte (string, to_char); |
| 1235 | return make_specified_string (SSDATA (string) + from_byte, | 1240 | return make_specified_string (SSDATA (string) + from_byte, |
| 1236 | to_char - from_char, to_byte - from_byte, | 1241 | to_char - from_char, to_byte - from_byte, |
| 1237 | STRING_MULTIBYTE (string)); | 1242 | STRING_MULTIBYTE (string)); |
| @@ -4612,14 +4617,12 @@ secure_hash (Lisp_Object algorithm, Lisp_Object object, Lisp_Object start, Lisp_ | |||
| 4612 | object = code_convert_string (object, coding_system, Qnil, 1, 0, 1); | 4617 | object = code_convert_string (object, coding_system, Qnil, 1, 0, 1); |
| 4613 | 4618 | ||
| 4614 | size = SCHARS (object); | 4619 | size = SCHARS (object); |
| 4620 | validate_subarray (object, start, end, size, &start_char, &end_char); | ||
| 4615 | 4621 | ||
| 4616 | if (!validate_substring (start, end, size, &start_char, &end_char)) | 4622 | start_byte = !start_char ? 0 : string_char_to_byte (object, start_char); |
| 4617 | args_out_of_range_3 (object, make_number (start_char), | 4623 | end_byte = (end_char == size |
| 4618 | make_number (end_char)); | 4624 | ? SBYTES (object) |
| 4619 | 4625 | : string_char_to_byte (object, end_char)); | |
| 4620 | start_byte = NILP (start) ? 0 : string_char_to_byte (object, start_char); | ||
| 4621 | end_byte = | ||
| 4622 | NILP (end) ? SBYTES (object) : string_char_to_byte (object, end_char); | ||
| 4623 | } | 4626 | } |
| 4624 | else | 4627 | else |
| 4625 | { | 4628 | { |