diff options
| author | Richard M. Stallman | 2007-07-10 03:49:44 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 2007-07-10 03:49:44 +0000 |
| commit | ef8878109c47998abea49be9965c757af12cdd64 (patch) | |
| tree | c6a26a63a9eda4b9c74665c2d1291387a236a4bc /src | |
| parent | 5d27646d21eab1e70b58df3f5e27d87e34b43a89 (diff) | |
| download | emacs-ef8878109c47998abea49be9965c757af12cdd64.tar.gz emacs-ef8878109c47998abea49be9965c757af12cdd64.zip | |
(Vinhibit_changing_match_data, search_regs_1): New vars.
(looking_at_1): Don't change search_regs and last_thing_searched
if `inhibit-changing-match-data' is non-nil.
(string_match_1, search_buffer, set_search_regs): Likewise.
(syms_of_search): Add Lisp level definition for
`inhibit-changing-match-data' and set it to nil.
(boyer_moore): If `inhibit-changing-match-data' is non-nil,
compute start and end of the match, instead of using values in search_regs.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 12 | ||||
| -rw-r--r-- | src/search.c | 179 |
2 files changed, 143 insertions, 48 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index b87b05f8e27..489e68b37be 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,15 @@ | |||
| 1 | 2007-07-10 Guanpeng Xu <herberteuler@hotmail.com> | ||
| 2 | |||
| 3 | * search.c (Vinhibit_changing_match_data, search_regs_1): New vars. | ||
| 4 | (looking_at_1): Don't change search_regs and last_thing_searched | ||
| 5 | if `inhibit-changing-match-data' is non-nil. | ||
| 6 | (string_match_1, search_buffer, set_search_regs): Likewise. | ||
| 7 | (syms_of_search): Add Lisp level definition for | ||
| 8 | `inhibit-changing-match-data' and set it to nil. | ||
| 9 | (boyer_moore): If `inhibit-changing-match-data' is non-nil, | ||
| 10 | compute start and end of the match, instead of using values in | ||
| 11 | search_regs. | ||
| 12 | |||
| 1 | 2007-07-01 Stefan Monnier <monnier@iro.umontreal.ca> | 13 | 2007-07-01 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 14 | ||
| 3 | * minibuf.c (Fcompleting_read): New value `confirm-only' | 15 | * minibuf.c (Fcompleting_read): New value `confirm-only' |
diff --git a/src/search.c b/src/search.c index c9c6dfdd242..154f6c80e2d 100644 --- a/src/search.c +++ b/src/search.c | |||
| @@ -92,6 +92,11 @@ Lisp_Object Qsearch_failed; | |||
| 92 | 92 | ||
| 93 | Lisp_Object Vsearch_spaces_regexp; | 93 | Lisp_Object Vsearch_spaces_regexp; |
| 94 | 94 | ||
| 95 | /* If non-nil, the match data will not be changed during call to | ||
| 96 | searching or matching functions. This variable is for internal use | ||
| 97 | only. */ | ||
| 98 | Lisp_Object Vinhibit_changing_match_data; | ||
| 99 | |||
| 95 | static void set_search_regs (); | 100 | static void set_search_regs (); |
| 96 | static void save_search_regs (); | 101 | static void save_search_regs (); |
| 97 | static int simple_search (); | 102 | static int simple_search (); |
| @@ -321,7 +326,9 @@ looking_at_1 (string, posix) | |||
| 321 | = current_buffer->case_eqv_table; | 326 | = current_buffer->case_eqv_table; |
| 322 | 327 | ||
| 323 | CHECK_STRING (string); | 328 | CHECK_STRING (string); |
| 324 | bufp = compile_pattern (string, &search_regs, | 329 | bufp = compile_pattern (string, |
| 330 | (NILP (Vinhibit_changing_match_data) | ||
| 331 | ? &search_regs : NULL), | ||
| 325 | (!NILP (current_buffer->case_fold_search) | 332 | (!NILP (current_buffer->case_fold_search) |
| 326 | ? current_buffer->case_canon_table : Qnil), | 333 | ? current_buffer->case_canon_table : Qnil), |
| 327 | posix, | 334 | posix, |
| @@ -352,7 +359,9 @@ looking_at_1 (string, posix) | |||
| 352 | re_match_object = Qnil; | 359 | re_match_object = Qnil; |
| 353 | 360 | ||
| 354 | i = re_match_2 (bufp, (char *) p1, s1, (char *) p2, s2, | 361 | i = re_match_2 (bufp, (char *) p1, s1, (char *) p2, s2, |
| 355 | PT_BYTE - BEGV_BYTE, &search_regs, | 362 | PT_BYTE - BEGV_BYTE, |
| 363 | (NILP (Vinhibit_changing_match_data) | ||
| 364 | ? &search_regs : NULL), | ||
| 356 | ZV_BYTE - BEGV_BYTE); | 365 | ZV_BYTE - BEGV_BYTE); |
| 357 | immediate_quit = 0; | 366 | immediate_quit = 0; |
| 358 | 367 | ||
| @@ -360,7 +369,7 @@ looking_at_1 (string, posix) | |||
| 360 | matcher_overflow (); | 369 | matcher_overflow (); |
| 361 | 370 | ||
| 362 | val = (0 <= i ? Qt : Qnil); | 371 | val = (0 <= i ? Qt : Qnil); |
| 363 | if (i >= 0) | 372 | if (NILP (Vinhibit_changing_match_data) && i >= 0) |
| 364 | for (i = 0; i < search_regs.num_regs; i++) | 373 | for (i = 0; i < search_regs.num_regs; i++) |
| 365 | if (search_regs.start[i] >= 0) | 374 | if (search_regs.start[i] >= 0) |
| 366 | { | 375 | { |
| @@ -369,7 +378,11 @@ looking_at_1 (string, posix) | |||
| 369 | search_regs.end[i] | 378 | search_regs.end[i] |
| 370 | = BYTE_TO_CHAR (search_regs.end[i] + BEGV_BYTE); | 379 | = BYTE_TO_CHAR (search_regs.end[i] + BEGV_BYTE); |
| 371 | } | 380 | } |
| 372 | XSETBUFFER (last_thing_searched, current_buffer); | 381 | |
| 382 | /* Set last_thing_searched only when match data is changed. */ | ||
| 383 | if (NILP (Vinhibit_changing_match_data)) | ||
| 384 | XSETBUFFER (last_thing_searched, current_buffer); | ||
| 385 | |||
| 373 | return val; | 386 | return val; |
| 374 | } | 387 | } |
| 375 | 388 | ||
| @@ -431,7 +444,9 @@ string_match_1 (regexp, string, start, posix) | |||
| 431 | XCHAR_TABLE (current_buffer->case_canon_table)->extras[2] | 444 | XCHAR_TABLE (current_buffer->case_canon_table)->extras[2] |
| 432 | = current_buffer->case_eqv_table; | 445 | = current_buffer->case_eqv_table; |
| 433 | 446 | ||
| 434 | bufp = compile_pattern (regexp, &search_regs, | 447 | bufp = compile_pattern (regexp, |
| 448 | (NILP (Vinhibit_changing_match_data) | ||
| 449 | ? &search_regs : NULL), | ||
| 435 | (!NILP (current_buffer->case_fold_search) | 450 | (!NILP (current_buffer->case_fold_search) |
| 436 | ? current_buffer->case_canon_table : Qnil), | 451 | ? current_buffer->case_canon_table : Qnil), |
| 437 | posix, | 452 | posix, |
| @@ -442,21 +457,27 @@ string_match_1 (regexp, string, start, posix) | |||
| 442 | val = re_search (bufp, (char *) SDATA (string), | 457 | val = re_search (bufp, (char *) SDATA (string), |
| 443 | SBYTES (string), pos_byte, | 458 | SBYTES (string), pos_byte, |
| 444 | SBYTES (string) - pos_byte, | 459 | SBYTES (string) - pos_byte, |
| 445 | &search_regs); | 460 | (NILP (Vinhibit_changing_match_data) |
| 461 | ? &search_regs : NULL)); | ||
| 446 | immediate_quit = 0; | 462 | immediate_quit = 0; |
| 447 | last_thing_searched = Qt; | 463 | |
| 464 | /* Set last_thing_searched only when match data is changed. */ | ||
| 465 | if (NILP (Vinhibit_changing_match_data)) | ||
| 466 | last_thing_searched = Qt; | ||
| 467 | |||
| 448 | if (val == -2) | 468 | if (val == -2) |
| 449 | matcher_overflow (); | 469 | matcher_overflow (); |
| 450 | if (val < 0) return Qnil; | 470 | if (val < 0) return Qnil; |
| 451 | 471 | ||
| 452 | for (i = 0; i < search_regs.num_regs; i++) | 472 | if (NILP (Vinhibit_changing_match_data)) |
| 453 | if (search_regs.start[i] >= 0) | 473 | for (i = 0; i < search_regs.num_regs; i++) |
| 454 | { | 474 | if (search_regs.start[i] >= 0) |
| 455 | search_regs.start[i] | 475 | { |
| 456 | = string_byte_to_char (string, search_regs.start[i]); | 476 | search_regs.start[i] |
| 457 | search_regs.end[i] | 477 | = string_byte_to_char (string, search_regs.start[i]); |
| 458 | = string_byte_to_char (string, search_regs.end[i]); | 478 | search_regs.end[i] |
| 459 | } | 479 | = string_byte_to_char (string, search_regs.end[i]); |
| 480 | } | ||
| 460 | 481 | ||
| 461 | return make_number (string_byte_to_char (string, val)); | 482 | return make_number (string_byte_to_char (string, val)); |
| 462 | } | 483 | } |
| @@ -1074,6 +1095,11 @@ do \ | |||
| 1074 | } \ | 1095 | } \ |
| 1075 | while (0) | 1096 | while (0) |
| 1076 | 1097 | ||
| 1098 | /* Only used in search_buffer, to record the end position of the match | ||
| 1099 | when searching regexps and SEARCH_REGS should not be changed | ||
| 1100 | (i.e. Vinhibit_changing_match_data is non-nil). */ | ||
| 1101 | static struct re_registers search_regs_1; | ||
| 1102 | |||
| 1077 | static int | 1103 | static int |
| 1078 | search_buffer (string, pos, pos_byte, lim, lim_byte, n, | 1104 | search_buffer (string, pos, pos_byte, lim, lim_byte, n, |
| 1079 | RE, trt, inverse_trt, posix) | 1105 | RE, trt, inverse_trt, posix) |
| @@ -1109,7 +1135,10 @@ search_buffer (string, pos, pos_byte, lim, lim_byte, n, | |||
| 1109 | int s1, s2; | 1135 | int s1, s2; |
| 1110 | struct re_pattern_buffer *bufp; | 1136 | struct re_pattern_buffer *bufp; |
| 1111 | 1137 | ||
| 1112 | bufp = compile_pattern (string, &search_regs, trt, posix, | 1138 | bufp = compile_pattern (string, |
| 1139 | (NILP (Vinhibit_changing_match_data) | ||
| 1140 | ? &search_regs : &search_regs_1), | ||
| 1141 | trt, posix, | ||
| 1113 | !NILP (current_buffer->enable_multibyte_characters)); | 1142 | !NILP (current_buffer->enable_multibyte_characters)); |
| 1114 | 1143 | ||
| 1115 | immediate_quit = 1; /* Quit immediately if user types ^G, | 1144 | immediate_quit = 1; /* Quit immediately if user types ^G, |
| @@ -1142,7 +1171,8 @@ search_buffer (string, pos, pos_byte, lim, lim_byte, n, | |||
| 1142 | int val; | 1171 | int val; |
| 1143 | val = re_search_2 (bufp, (char *) p1, s1, (char *) p2, s2, | 1172 | val = re_search_2 (bufp, (char *) p1, s1, (char *) p2, s2, |
| 1144 | pos_byte - BEGV_BYTE, lim_byte - pos_byte, | 1173 | pos_byte - BEGV_BYTE, lim_byte - pos_byte, |
| 1145 | &search_regs, | 1174 | (NILP (Vinhibit_changing_match_data) |
| 1175 | ? &search_regs : &search_regs_1), | ||
| 1146 | /* Don't allow match past current point */ | 1176 | /* Don't allow match past current point */ |
| 1147 | pos_byte - BEGV_BYTE); | 1177 | pos_byte - BEGV_BYTE); |
| 1148 | if (val == -2) | 1178 | if (val == -2) |
| @@ -1151,18 +1181,27 @@ search_buffer (string, pos, pos_byte, lim, lim_byte, n, | |||
| 1151 | } | 1181 | } |
| 1152 | if (val >= 0) | 1182 | if (val >= 0) |
| 1153 | { | 1183 | { |
| 1154 | pos_byte = search_regs.start[0] + BEGV_BYTE; | 1184 | if (NILP (Vinhibit_changing_match_data)) |
| 1155 | for (i = 0; i < search_regs.num_regs; i++) | 1185 | { |
| 1156 | if (search_regs.start[i] >= 0) | 1186 | pos_byte = search_regs.start[0] + BEGV_BYTE; |
| 1157 | { | 1187 | for (i = 0; i < search_regs.num_regs; i++) |
| 1158 | search_regs.start[i] | 1188 | if (search_regs.start[i] >= 0) |
| 1159 | = BYTE_TO_CHAR (search_regs.start[i] + BEGV_BYTE); | 1189 | { |
| 1160 | search_regs.end[i] | 1190 | search_regs.start[i] |
| 1161 | = BYTE_TO_CHAR (search_regs.end[i] + BEGV_BYTE); | 1191 | = BYTE_TO_CHAR (search_regs.start[i] + BEGV_BYTE); |
| 1162 | } | 1192 | search_regs.end[i] |
| 1163 | XSETBUFFER (last_thing_searched, current_buffer); | 1193 | = BYTE_TO_CHAR (search_regs.end[i] + BEGV_BYTE); |
| 1164 | /* Set pos to the new position. */ | 1194 | } |
| 1165 | pos = search_regs.start[0]; | 1195 | XSETBUFFER (last_thing_searched, current_buffer); |
| 1196 | /* Set pos to the new position. */ | ||
| 1197 | pos = search_regs.start[0]; | ||
| 1198 | } | ||
| 1199 | else | ||
| 1200 | { | ||
| 1201 | pos_byte = search_regs_1.start[0] + BEGV_BYTE; | ||
| 1202 | /* Set pos to the new position. */ | ||
| 1203 | pos = BYTE_TO_CHAR (search_regs_1.start[0] + BEGV_BYTE); | ||
| 1204 | } | ||
| 1166 | } | 1205 | } |
| 1167 | else | 1206 | else |
| 1168 | { | 1207 | { |
| @@ -1176,7 +1215,8 @@ search_buffer (string, pos, pos_byte, lim, lim_byte, n, | |||
| 1176 | int val; | 1215 | int val; |
| 1177 | val = re_search_2 (bufp, (char *) p1, s1, (char *) p2, s2, | 1216 | val = re_search_2 (bufp, (char *) p1, s1, (char *) p2, s2, |
| 1178 | pos_byte - BEGV_BYTE, lim_byte - pos_byte, | 1217 | pos_byte - BEGV_BYTE, lim_byte - pos_byte, |
| 1179 | &search_regs, | 1218 | (NILP (Vinhibit_changing_match_data) |
| 1219 | ? &search_regs : &search_regs_1), | ||
| 1180 | lim_byte - BEGV_BYTE); | 1220 | lim_byte - BEGV_BYTE); |
| 1181 | if (val == -2) | 1221 | if (val == -2) |
| 1182 | { | 1222 | { |
| @@ -1184,17 +1224,25 @@ search_buffer (string, pos, pos_byte, lim, lim_byte, n, | |||
| 1184 | } | 1224 | } |
| 1185 | if (val >= 0) | 1225 | if (val >= 0) |
| 1186 | { | 1226 | { |
| 1187 | pos_byte = search_regs.end[0] + BEGV_BYTE; | 1227 | if (NILP (Vinhibit_changing_match_data)) |
| 1188 | for (i = 0; i < search_regs.num_regs; i++) | 1228 | { |
| 1189 | if (search_regs.start[i] >= 0) | 1229 | pos_byte = search_regs.end[0] + BEGV_BYTE; |
| 1190 | { | 1230 | for (i = 0; i < search_regs.num_regs; i++) |
| 1191 | search_regs.start[i] | 1231 | if (search_regs.start[i] >= 0) |
| 1192 | = BYTE_TO_CHAR (search_regs.start[i] + BEGV_BYTE); | 1232 | { |
| 1193 | search_regs.end[i] | 1233 | search_regs.start[i] |
| 1194 | = BYTE_TO_CHAR (search_regs.end[i] + BEGV_BYTE); | 1234 | = BYTE_TO_CHAR (search_regs.start[i] + BEGV_BYTE); |
| 1195 | } | 1235 | search_regs.end[i] |
| 1196 | XSETBUFFER (last_thing_searched, current_buffer); | 1236 | = BYTE_TO_CHAR (search_regs.end[i] + BEGV_BYTE); |
| 1197 | pos = search_regs.end[0]; | 1237 | } |
| 1238 | XSETBUFFER (last_thing_searched, current_buffer); | ||
| 1239 | pos = search_regs.end[0]; | ||
| 1240 | } | ||
| 1241 | else | ||
| 1242 | { | ||
| 1243 | pos_byte = search_regs_1.end[0] + BEGV_BYTE; | ||
| 1244 | pos = BYTE_TO_CHAR (search_regs_1.end[0] + BEGV_BYTE); | ||
| 1245 | } | ||
| 1198 | } | 1246 | } |
| 1199 | else | 1247 | else |
| 1200 | { | 1248 | { |
| @@ -1926,7 +1974,7 @@ boyer_moore (n, base_pat, len, len_byte, trt, inverse_trt, | |||
| 1926 | cursor += dirlen - i - direction; /* fix cursor */ | 1974 | cursor += dirlen - i - direction; /* fix cursor */ |
| 1927 | if (i + direction == 0) | 1975 | if (i + direction == 0) |
| 1928 | { | 1976 | { |
| 1929 | int position; | 1977 | int position, start, end; |
| 1930 | 1978 | ||
| 1931 | cursor -= direction; | 1979 | cursor -= direction; |
| 1932 | 1980 | ||
| @@ -1934,11 +1982,24 @@ boyer_moore (n, base_pat, len, len_byte, trt, inverse_trt, | |||
| 1934 | ? 1 - len_byte : 0); | 1982 | ? 1 - len_byte : 0); |
| 1935 | set_search_regs (position, len_byte); | 1983 | set_search_regs (position, len_byte); |
| 1936 | 1984 | ||
| 1985 | if (NILP (Vinhibit_changing_match_data)) | ||
| 1986 | { | ||
| 1987 | start = search_regs.start[0]; | ||
| 1988 | end = search_regs.end[0]; | ||
| 1989 | } | ||
| 1990 | else | ||
| 1991 | /* If Vinhibit_changing_match_data is non-nil, | ||
| 1992 | search_regs will not be changed. So let's | ||
| 1993 | compute start and end here. */ | ||
| 1994 | { | ||
| 1995 | start = BYTE_TO_CHAR (position); | ||
| 1996 | end = BYTE_TO_CHAR (position + len_byte); | ||
| 1997 | } | ||
| 1998 | |||
| 1937 | if ((n -= direction) != 0) | 1999 | if ((n -= direction) != 0) |
| 1938 | cursor += dirlen; /* to resume search */ | 2000 | cursor += dirlen; /* to resume search */ |
| 1939 | else | 2001 | else |
| 1940 | return ((direction > 0) | 2002 | return direction > 0 ? end : start; |
| 1941 | ? search_regs.end[0] : search_regs.start[0]); | ||
| 1942 | } | 2003 | } |
| 1943 | else | 2004 | else |
| 1944 | cursor += stride_for_teases; /* <sigh> we lose - */ | 2005 | cursor += stride_for_teases; /* <sigh> we lose - */ |
| @@ -2003,18 +2064,30 @@ boyer_moore (n, base_pat, len, len_byte, trt, inverse_trt, | |||
| 2003 | pos_byte += dirlen - i- direction; | 2064 | pos_byte += dirlen - i- direction; |
| 2004 | if (i + direction == 0) | 2065 | if (i + direction == 0) |
| 2005 | { | 2066 | { |
| 2006 | int position; | 2067 | int position, start, end; |
| 2007 | pos_byte -= direction; | 2068 | pos_byte -= direction; |
| 2008 | 2069 | ||
| 2009 | position = pos_byte + ((direction > 0) ? 1 - len_byte : 0); | 2070 | position = pos_byte + ((direction > 0) ? 1 - len_byte : 0); |
| 2010 | |||
| 2011 | set_search_regs (position, len_byte); | 2071 | set_search_regs (position, len_byte); |
| 2012 | 2072 | ||
| 2073 | if (NILP (Vinhibit_changing_match_data)) | ||
| 2074 | { | ||
| 2075 | start = search_regs.start[0]; | ||
| 2076 | end = search_regs.end[0]; | ||
| 2077 | } | ||
| 2078 | else | ||
| 2079 | /* If Vinhibit_changing_match_data is non-nil, | ||
| 2080 | search_regs will not be changed. So let's | ||
| 2081 | compute start and end here. */ | ||
| 2082 | { | ||
| 2083 | start = BYTE_TO_CHAR (position); | ||
| 2084 | end = BYTE_TO_CHAR (position + len_byte); | ||
| 2085 | } | ||
| 2086 | |||
| 2013 | if ((n -= direction) != 0) | 2087 | if ((n -= direction) != 0) |
| 2014 | pos_byte += dirlen; /* to resume search */ | 2088 | pos_byte += dirlen; /* to resume search */ |
| 2015 | else | 2089 | else |
| 2016 | return ((direction > 0) | 2090 | return direction > 0 ? end : start; |
| 2017 | ? search_regs.end[0] : search_regs.start[0]); | ||
| 2018 | } | 2091 | } |
| 2019 | else | 2092 | else |
| 2020 | pos_byte += stride_for_teases; | 2093 | pos_byte += stride_for_teases; |
| @@ -2037,6 +2110,9 @@ set_search_regs (beg_byte, nbytes) | |||
| 2037 | { | 2110 | { |
| 2038 | int i; | 2111 | int i; |
| 2039 | 2112 | ||
| 2113 | if (!NILP (Vinhibit_changing_match_data)) | ||
| 2114 | return; | ||
| 2115 | |||
| 2040 | /* Make sure we have registers in which to store | 2116 | /* Make sure we have registers in which to store |
| 2041 | the match position. */ | 2117 | the match position. */ |
| 2042 | if (search_regs.num_regs == 0) | 2118 | if (search_regs.num_regs == 0) |
| @@ -3167,6 +3243,13 @@ or other such regexp constructs are not replaced with this. | |||
| 3167 | A value of nil (which is the normal value) means treat spaces literally. */); | 3243 | A value of nil (which is the normal value) means treat spaces literally. */); |
| 3168 | Vsearch_spaces_regexp = Qnil; | 3244 | Vsearch_spaces_regexp = Qnil; |
| 3169 | 3245 | ||
| 3246 | DEFVAR_LISP ("inhibit-changing-match-data", &Vinhibit_changing_match_data, | ||
| 3247 | doc: /* Internal use only. | ||
| 3248 | If non-nil, the match data will not be changed during call to searching or | ||
| 3249 | matching functions, such as `looking-at', `string-match', `re-search-forward' | ||
| 3250 | etc. */); | ||
| 3251 | Vinhibit_changing_match_data = Qnil; | ||
| 3252 | |||
| 3170 | defsubr (&Slooking_at); | 3253 | defsubr (&Slooking_at); |
| 3171 | defsubr (&Sposix_looking_at); | 3254 | defsubr (&Sposix_looking_at); |
| 3172 | defsubr (&Sstring_match); | 3255 | defsubr (&Sstring_match); |