aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
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 {