diff options
| author | Miles Bader | 2007-07-15 04:47:46 +0000 |
|---|---|---|
| committer | Miles Bader | 2007-07-15 04:47:46 +0000 |
| commit | 8c406a9bc42ee77fcbbb4201fe8bda855eafd832 (patch) | |
| tree | 14c8fa2e72341edd9db40b17079fd5208b1554c8 /src/search.c | |
| parent | 9bdeb5e9bedd773cc6845bc29a98e1e2a208f1ff (diff) | |
| parent | 6f8a87c027ebd6f9cfdac5c0df97d651227bec62 (diff) | |
| download | emacs-8c406a9bc42ee77fcbbb4201fe8bda855eafd832.tar.gz emacs-8c406a9bc42ee77fcbbb4201fe8bda855eafd832.zip | |
Merge from emacs--devo--0
Patches applied:
* emacs--devo--0 (patch 806-813)
- Merge from emacs--rel--22
- Update from CVS
* emacs--rel--22 (patch 51-58)
- Update from CVS
- Merge from gnus--rel--5.10
* gnus--rel--5.10 (patch 233-236)
- Merge from emacs--devo--0
- Update from CVS
Revision: emacs@sv.gnu.org/emacs--unicode--0--patch-230
Diffstat (limited to 'src/search.c')
| -rw-r--r-- | src/search.c | 179 |
1 files changed, 131 insertions, 48 deletions
diff --git a/src/search.c b/src/search.c index fd7b474e4ab..ae5ae608e4a 100644 --- a/src/search.c +++ b/src/search.c | |||
| @@ -93,6 +93,11 @@ Lisp_Object Qsearch_failed; | |||
| 93 | 93 | ||
| 94 | Lisp_Object Vsearch_spaces_regexp; | 94 | Lisp_Object Vsearch_spaces_regexp; |
| 95 | 95 | ||
| 96 | /* If non-nil, the match data will not be changed during call to | ||
| 97 | searching or matching functions. This variable is for internal use | ||
| 98 | only. */ | ||
| 99 | Lisp_Object Vinhibit_changing_match_data; | ||
| 100 | |||
| 96 | static void set_search_regs (); | 101 | static void set_search_regs (); |
| 97 | static void save_search_regs (); | 102 | static void save_search_regs (); |
| 98 | static int simple_search (); | 103 | static int simple_search (); |
| @@ -289,7 +294,9 @@ looking_at_1 (string, posix) | |||
| 289 | = current_buffer->case_eqv_table; | 294 | = current_buffer->case_eqv_table; |
| 290 | 295 | ||
| 291 | CHECK_STRING (string); | 296 | CHECK_STRING (string); |
| 292 | bufp = compile_pattern (string, &search_regs, | 297 | bufp = compile_pattern (string, |
| 298 | (NILP (Vinhibit_changing_match_data) | ||
| 299 | ? &search_regs : NULL), | ||
| 293 | (!NILP (current_buffer->case_fold_search) | 300 | (!NILP (current_buffer->case_fold_search) |
| 294 | ? current_buffer->case_canon_table : Qnil), | 301 | ? current_buffer->case_canon_table : Qnil), |
| 295 | posix, | 302 | posix, |
| @@ -320,7 +327,9 @@ looking_at_1 (string, posix) | |||
| 320 | re_match_object = Qnil; | 327 | re_match_object = Qnil; |
| 321 | 328 | ||
| 322 | i = re_match_2 (bufp, (char *) p1, s1, (char *) p2, s2, | 329 | i = re_match_2 (bufp, (char *) p1, s1, (char *) p2, s2, |
| 323 | PT_BYTE - BEGV_BYTE, &search_regs, | 330 | PT_BYTE - BEGV_BYTE, |
| 331 | (NILP (Vinhibit_changing_match_data) | ||
| 332 | ? &search_regs : NULL), | ||
| 324 | ZV_BYTE - BEGV_BYTE); | 333 | ZV_BYTE - BEGV_BYTE); |
| 325 | immediate_quit = 0; | 334 | immediate_quit = 0; |
| 326 | 335 | ||
| @@ -328,7 +337,7 @@ looking_at_1 (string, posix) | |||
| 328 | matcher_overflow (); | 337 | matcher_overflow (); |
| 329 | 338 | ||
| 330 | val = (0 <= i ? Qt : Qnil); | 339 | val = (0 <= i ? Qt : Qnil); |
| 331 | if (i >= 0) | 340 | if (NILP (Vinhibit_changing_match_data) && i >= 0) |
| 332 | for (i = 0; i < search_regs.num_regs; i++) | 341 | for (i = 0; i < search_regs.num_regs; i++) |
| 333 | if (search_regs.start[i] >= 0) | 342 | if (search_regs.start[i] >= 0) |
| 334 | { | 343 | { |
| @@ -337,7 +346,11 @@ looking_at_1 (string, posix) | |||
| 337 | search_regs.end[i] | 346 | search_regs.end[i] |
| 338 | = BYTE_TO_CHAR (search_regs.end[i] + BEGV_BYTE); | 347 | = BYTE_TO_CHAR (search_regs.end[i] + BEGV_BYTE); |
| 339 | } | 348 | } |
| 340 | XSETBUFFER (last_thing_searched, current_buffer); | 349 | |
| 350 | /* Set last_thing_searched only when match data is changed. */ | ||
| 351 | if (NILP (Vinhibit_changing_match_data)) | ||
| 352 | XSETBUFFER (last_thing_searched, current_buffer); | ||
| 353 | |||
| 341 | return val; | 354 | return val; |
| 342 | } | 355 | } |
| 343 | 356 | ||
| @@ -399,7 +412,9 @@ string_match_1 (regexp, string, start, posix) | |||
| 399 | XCHAR_TABLE (current_buffer->case_canon_table)->extras[2] | 412 | XCHAR_TABLE (current_buffer->case_canon_table)->extras[2] |
| 400 | = current_buffer->case_eqv_table; | 413 | = current_buffer->case_eqv_table; |
| 401 | 414 | ||
| 402 | bufp = compile_pattern (regexp, &search_regs, | 415 | bufp = compile_pattern (regexp, |
| 416 | (NILP (Vinhibit_changing_match_data) | ||
| 417 | ? &search_regs : NULL), | ||
| 403 | (!NILP (current_buffer->case_fold_search) | 418 | (!NILP (current_buffer->case_fold_search) |
| 404 | ? current_buffer->case_canon_table : Qnil), | 419 | ? current_buffer->case_canon_table : Qnil), |
| 405 | posix, | 420 | posix, |
| @@ -410,21 +425,27 @@ string_match_1 (regexp, string, start, posix) | |||
| 410 | val = re_search (bufp, (char *) SDATA (string), | 425 | val = re_search (bufp, (char *) SDATA (string), |
| 411 | SBYTES (string), pos_byte, | 426 | SBYTES (string), pos_byte, |
| 412 | SBYTES (string) - pos_byte, | 427 | SBYTES (string) - pos_byte, |
| 413 | &search_regs); | 428 | (NILP (Vinhibit_changing_match_data) |
| 429 | ? &search_regs : NULL)); | ||
| 414 | immediate_quit = 0; | 430 | immediate_quit = 0; |
| 415 | last_thing_searched = Qt; | 431 | |
| 432 | /* Set last_thing_searched only when match data is changed. */ | ||
| 433 | if (NILP (Vinhibit_changing_match_data)) | ||
| 434 | last_thing_searched = Qt; | ||
| 435 | |||
| 416 | if (val == -2) | 436 | if (val == -2) |
| 417 | matcher_overflow (); | 437 | matcher_overflow (); |
| 418 | if (val < 0) return Qnil; | 438 | if (val < 0) return Qnil; |
| 419 | 439 | ||
| 420 | for (i = 0; i < search_regs.num_regs; i++) | 440 | if (NILP (Vinhibit_changing_match_data)) |
| 421 | if (search_regs.start[i] >= 0) | 441 | for (i = 0; i < search_regs.num_regs; i++) |
| 422 | { | 442 | if (search_regs.start[i] >= 0) |
| 423 | search_regs.start[i] | 443 | { |
| 424 | = string_byte_to_char (string, search_regs.start[i]); | 444 | search_regs.start[i] |
| 425 | search_regs.end[i] | 445 | = string_byte_to_char (string, search_regs.start[i]); |
| 426 | = string_byte_to_char (string, search_regs.end[i]); | 446 | search_regs.end[i] |
| 427 | } | 447 | = string_byte_to_char (string, search_regs.end[i]); |
| 448 | } | ||
| 428 | 449 | ||
| 429 | return make_number (string_byte_to_char (string, val)); | 450 | return make_number (string_byte_to_char (string, val)); |
| 430 | } | 451 | } |
| @@ -1042,6 +1063,11 @@ do \ | |||
| 1042 | } \ | 1063 | } \ |
| 1043 | while (0) | 1064 | while (0) |
| 1044 | 1065 | ||
| 1066 | /* Only used in search_buffer, to record the end position of the match | ||
| 1067 | when searching regexps and SEARCH_REGS should not be changed | ||
| 1068 | (i.e. Vinhibit_changing_match_data is non-nil). */ | ||
| 1069 | static struct re_registers search_regs_1; | ||
| 1070 | |||
| 1045 | static int | 1071 | static int |
| 1046 | search_buffer (string, pos, pos_byte, lim, lim_byte, n, | 1072 | search_buffer (string, pos, pos_byte, lim, lim_byte, n, |
| 1047 | RE, trt, inverse_trt, posix) | 1073 | RE, trt, inverse_trt, posix) |
| @@ -1077,7 +1103,10 @@ search_buffer (string, pos, pos_byte, lim, lim_byte, n, | |||
| 1077 | int s1, s2; | 1103 | int s1, s2; |
| 1078 | struct re_pattern_buffer *bufp; | 1104 | struct re_pattern_buffer *bufp; |
| 1079 | 1105 | ||
| 1080 | bufp = compile_pattern (string, &search_regs, trt, posix, | 1106 | bufp = compile_pattern (string, |
| 1107 | (NILP (Vinhibit_changing_match_data) | ||
| 1108 | ? &search_regs : &search_regs_1), | ||
| 1109 | trt, posix, | ||
| 1081 | !NILP (current_buffer->enable_multibyte_characters)); | 1110 | !NILP (current_buffer->enable_multibyte_characters)); |
| 1082 | 1111 | ||
| 1083 | immediate_quit = 1; /* Quit immediately if user types ^G, | 1112 | immediate_quit = 1; /* Quit immediately if user types ^G, |
| @@ -1110,7 +1139,8 @@ search_buffer (string, pos, pos_byte, lim, lim_byte, n, | |||
| 1110 | int val; | 1139 | int val; |
| 1111 | val = re_search_2 (bufp, (char *) p1, s1, (char *) p2, s2, | 1140 | val = re_search_2 (bufp, (char *) p1, s1, (char *) p2, s2, |
| 1112 | pos_byte - BEGV_BYTE, lim_byte - pos_byte, | 1141 | pos_byte - BEGV_BYTE, lim_byte - pos_byte, |
| 1113 | &search_regs, | 1142 | (NILP (Vinhibit_changing_match_data) |
| 1143 | ? &search_regs : &search_regs_1), | ||
| 1114 | /* Don't allow match past current point */ | 1144 | /* Don't allow match past current point */ |
| 1115 | pos_byte - BEGV_BYTE); | 1145 | pos_byte - BEGV_BYTE); |
| 1116 | if (val == -2) | 1146 | if (val == -2) |
| @@ -1119,18 +1149,27 @@ search_buffer (string, pos, pos_byte, lim, lim_byte, n, | |||
| 1119 | } | 1149 | } |
| 1120 | if (val >= 0) | 1150 | if (val >= 0) |
| 1121 | { | 1151 | { |
| 1122 | pos_byte = search_regs.start[0] + BEGV_BYTE; | 1152 | if (NILP (Vinhibit_changing_match_data)) |
| 1123 | for (i = 0; i < search_regs.num_regs; i++) | 1153 | { |
| 1124 | if (search_regs.start[i] >= 0) | 1154 | pos_byte = search_regs.start[0] + BEGV_BYTE; |
| 1125 | { | 1155 | for (i = 0; i < search_regs.num_regs; i++) |
| 1126 | search_regs.start[i] | 1156 | if (search_regs.start[i] >= 0) |
| 1127 | = BYTE_TO_CHAR (search_regs.start[i] + BEGV_BYTE); | 1157 | { |
| 1128 | search_regs.end[i] | 1158 | search_regs.start[i] |
| 1129 | = BYTE_TO_CHAR (search_regs.end[i] + BEGV_BYTE); | 1159 | = BYTE_TO_CHAR (search_regs.start[i] + BEGV_BYTE); |
| 1130 | } | 1160 | search_regs.end[i] |
| 1131 | XSETBUFFER (last_thing_searched, current_buffer); | 1161 | = BYTE_TO_CHAR (search_regs.end[i] + BEGV_BYTE); |
| 1132 | /* Set pos to the new position. */ | 1162 | } |
| 1133 | pos = search_regs.start[0]; | 1163 | XSETBUFFER (last_thing_searched, current_buffer); |
| 1164 | /* Set pos to the new position. */ | ||
| 1165 | pos = search_regs.start[0]; | ||
| 1166 | } | ||
| 1167 | else | ||
| 1168 | { | ||
| 1169 | pos_byte = search_regs_1.start[0] + BEGV_BYTE; | ||
| 1170 | /* Set pos to the new position. */ | ||
| 1171 | pos = BYTE_TO_CHAR (search_regs_1.start[0] + BEGV_BYTE); | ||
| 1172 | } | ||
| 1134 | } | 1173 | } |
| 1135 | else | 1174 | else |
| 1136 | { | 1175 | { |
| @@ -1144,7 +1183,8 @@ search_buffer (string, pos, pos_byte, lim, lim_byte, n, | |||
| 1144 | int val; | 1183 | int val; |
| 1145 | val = re_search_2 (bufp, (char *) p1, s1, (char *) p2, s2, | 1184 | val = re_search_2 (bufp, (char *) p1, s1, (char *) p2, s2, |
| 1146 | pos_byte - BEGV_BYTE, lim_byte - pos_byte, | 1185 | pos_byte - BEGV_BYTE, lim_byte - pos_byte, |
| 1147 | &search_regs, | 1186 | (NILP (Vinhibit_changing_match_data) |
| 1187 | ? &search_regs : &search_regs_1), | ||
| 1148 | lim_byte - BEGV_BYTE); | 1188 | lim_byte - BEGV_BYTE); |
| 1149 | if (val == -2) | 1189 | if (val == -2) |
| 1150 | { | 1190 | { |
| @@ -1152,17 +1192,25 @@ search_buffer (string, pos, pos_byte, lim, lim_byte, n, | |||
| 1152 | } | 1192 | } |
| 1153 | if (val >= 0) | 1193 | if (val >= 0) |
| 1154 | { | 1194 | { |
| 1155 | pos_byte = search_regs.end[0] + BEGV_BYTE; | 1195 | if (NILP (Vinhibit_changing_match_data)) |
| 1156 | for (i = 0; i < search_regs.num_regs; i++) | 1196 | { |
| 1157 | if (search_regs.start[i] >= 0) | 1197 | pos_byte = search_regs.end[0] + BEGV_BYTE; |
| 1158 | { | 1198 | for (i = 0; i < search_regs.num_regs; i++) |
| 1159 | search_regs.start[i] | 1199 | if (search_regs.start[i] >= 0) |
| 1160 | = BYTE_TO_CHAR (search_regs.start[i] + BEGV_BYTE); | 1200 | { |
| 1161 | search_regs.end[i] | 1201 | search_regs.start[i] |
| 1162 | = BYTE_TO_CHAR (search_regs.end[i] + BEGV_BYTE); | 1202 | = BYTE_TO_CHAR (search_regs.start[i] + BEGV_BYTE); |
| 1163 | } | 1203 | search_regs.end[i] |
| 1164 | XSETBUFFER (last_thing_searched, current_buffer); | 1204 | = BYTE_TO_CHAR (search_regs.end[i] + BEGV_BYTE); |
| 1165 | pos = search_regs.end[0]; | 1205 | } |
| 1206 | XSETBUFFER (last_thing_searched, current_buffer); | ||
| 1207 | pos = search_regs.end[0]; | ||
| 1208 | } | ||
| 1209 | else | ||
| 1210 | { | ||
| 1211 | pos_byte = search_regs_1.end[0] + BEGV_BYTE; | ||
| 1212 | pos = BYTE_TO_CHAR (search_regs_1.end[0] + BEGV_BYTE); | ||
| 1213 | } | ||
| 1166 | } | 1214 | } |
| 1167 | else | 1215 | else |
| 1168 | { | 1216 | { |
| @@ -1907,7 +1955,7 @@ boyer_moore (n, base_pat, len, len_byte, trt, inverse_trt, | |||
| 1907 | cursor += dirlen - i - direction; /* fix cursor */ | 1955 | cursor += dirlen - i - direction; /* fix cursor */ |
| 1908 | if (i + direction == 0) | 1956 | if (i + direction == 0) |
| 1909 | { | 1957 | { |
| 1910 | int position; | 1958 | int position, start, end; |
| 1911 | 1959 | ||
| 1912 | cursor -= direction; | 1960 | cursor -= direction; |
| 1913 | 1961 | ||
| @@ -1915,11 +1963,24 @@ boyer_moore (n, base_pat, len, len_byte, trt, inverse_trt, | |||
| 1915 | ? 1 - len_byte : 0); | 1963 | ? 1 - len_byte : 0); |
| 1916 | set_search_regs (position, len_byte); | 1964 | set_search_regs (position, len_byte); |
| 1917 | 1965 | ||
| 1966 | if (NILP (Vinhibit_changing_match_data)) | ||
| 1967 | { | ||
| 1968 | start = search_regs.start[0]; | ||
| 1969 | end = search_regs.end[0]; | ||
| 1970 | } | ||
| 1971 | else | ||
| 1972 | /* If Vinhibit_changing_match_data is non-nil, | ||
| 1973 | search_regs will not be changed. So let's | ||
| 1974 | compute start and end here. */ | ||
| 1975 | { | ||
| 1976 | start = BYTE_TO_CHAR (position); | ||
| 1977 | end = BYTE_TO_CHAR (position + len_byte); | ||
| 1978 | } | ||
| 1979 | |||
| 1918 | if ((n -= direction) != 0) | 1980 | if ((n -= direction) != 0) |
| 1919 | cursor += dirlen; /* to resume search */ | 1981 | cursor += dirlen; /* to resume search */ |
| 1920 | else | 1982 | else |
| 1921 | return ((direction > 0) | 1983 | return direction > 0 ? end : start; |
| 1922 | ? search_regs.end[0] : search_regs.start[0]); | ||
| 1923 | } | 1984 | } |
| 1924 | else | 1985 | else |
| 1925 | cursor += stride_for_teases; /* <sigh> we lose - */ | 1986 | cursor += stride_for_teases; /* <sigh> we lose - */ |
| @@ -1984,18 +2045,30 @@ boyer_moore (n, base_pat, len, len_byte, trt, inverse_trt, | |||
| 1984 | pos_byte += dirlen - i- direction; | 2045 | pos_byte += dirlen - i- direction; |
| 1985 | if (i + direction == 0) | 2046 | if (i + direction == 0) |
| 1986 | { | 2047 | { |
| 1987 | int position; | 2048 | int position, start, end; |
| 1988 | pos_byte -= direction; | 2049 | pos_byte -= direction; |
| 1989 | 2050 | ||
| 1990 | position = pos_byte + ((direction > 0) ? 1 - len_byte : 0); | 2051 | position = pos_byte + ((direction > 0) ? 1 - len_byte : 0); |
| 1991 | |||
| 1992 | set_search_regs (position, len_byte); | 2052 | set_search_regs (position, len_byte); |
| 1993 | 2053 | ||
| 2054 | if (NILP (Vinhibit_changing_match_data)) | ||
| 2055 | { | ||
| 2056 | start = search_regs.start[0]; | ||
| 2057 | end = search_regs.end[0]; | ||
| 2058 | } | ||
| 2059 | else | ||
| 2060 | /* If Vinhibit_changing_match_data is non-nil, | ||
| 2061 | search_regs will not be changed. So let's | ||
| 2062 | compute start and end here. */ | ||
| 2063 | { | ||
| 2064 | start = BYTE_TO_CHAR (position); | ||
| 2065 | end = BYTE_TO_CHAR (position + len_byte); | ||
| 2066 | } | ||
| 2067 | |||
| 1994 | if ((n -= direction) != 0) | 2068 | if ((n -= direction) != 0) |
| 1995 | pos_byte += dirlen; /* to resume search */ | 2069 | pos_byte += dirlen; /* to resume search */ |
| 1996 | else | 2070 | else |
| 1997 | return ((direction > 0) | 2071 | return direction > 0 ? end : start; |
| 1998 | ? search_regs.end[0] : search_regs.start[0]); | ||
| 1999 | } | 2072 | } |
| 2000 | else | 2073 | else |
| 2001 | pos_byte += stride_for_teases; | 2074 | pos_byte += stride_for_teases; |
| @@ -2018,6 +2091,9 @@ set_search_regs (beg_byte, nbytes) | |||
| 2018 | { | 2091 | { |
| 2019 | int i; | 2092 | int i; |
| 2020 | 2093 | ||
| 2094 | if (!NILP (Vinhibit_changing_match_data)) | ||
| 2095 | return; | ||
| 2096 | |||
| 2021 | /* Make sure we have registers in which to store | 2097 | /* Make sure we have registers in which to store |
| 2022 | the match position. */ | 2098 | the match position. */ |
| 2023 | if (search_regs.num_regs == 0) | 2099 | if (search_regs.num_regs == 0) |
| @@ -3145,6 +3221,13 @@ or other such regexp constructs are not replaced with this. | |||
| 3145 | A value of nil (which is the normal value) means treat spaces literally. */); | 3221 | A value of nil (which is the normal value) means treat spaces literally. */); |
| 3146 | Vsearch_spaces_regexp = Qnil; | 3222 | Vsearch_spaces_regexp = Qnil; |
| 3147 | 3223 | ||
| 3224 | DEFVAR_LISP ("inhibit-changing-match-data", &Vinhibit_changing_match_data, | ||
| 3225 | doc: /* Internal use only. | ||
| 3226 | If non-nil, the match data will not be changed during call to searching or | ||
| 3227 | matching functions, such as `looking-at', `string-match', `re-search-forward' | ||
| 3228 | etc. */); | ||
| 3229 | Vinhibit_changing_match_data = Qnil; | ||
| 3230 | |||
| 3148 | defsubr (&Slooking_at); | 3231 | defsubr (&Slooking_at); |
| 3149 | defsubr (&Sposix_looking_at); | 3232 | defsubr (&Sposix_looking_at); |
| 3150 | defsubr (&Sstring_match); | 3233 | defsubr (&Sstring_match); |