diff options
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 | { |