aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2014-04-01 13:18:12 -0700
committerPaul Eggert2014-04-01 13:18:12 -0700
commit8ec49c53c67cfaee550f275c1a8b68d65b9b606f (patch)
tree570a656b003ee5de09623df3a8d89f3fd1112e11 /src
parent21c625fdd0fffffb8420ec25fbcba1aed7e05248 (diff)
downloademacs-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/ChangeLog10
-rw-r--r--src/fns.c95
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 @@
12014-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
12014-03-31 Dmitry Antipov <dmantipov@yandex.ru> 112014-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.
diff --git a/src/fns.c b/src/fns.c
index b0aafc40dd0..53819ed23aa 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -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
1135static bool 1136static void
1136validate_substring (Lisp_Object from, Lisp_Object to, ptrdiff_t size, 1137validate_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
1162DEFUN ("substring", Fsubstring, Ssubstring, 1, 3, 0, 1171DEFUN ("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 {