Mercurial > hg > xemacs-beta
comparison src/search.c @ 771:943eaba38521
[xemacs-hg @ 2002-03-13 08:51:24 by ben]
The big ben-mule-21-5 check-in!
Various files were added and deleted. See CHANGES-ben-mule.
There are still some test suite failures. No crashes, though.
Many of the failures have to do with problems in the test suite itself
rather than in the actual code. I'll be addressing these in the next
day or so -- none of the test suite failures are at all critical.
Meanwhile I'll be trying to address the biggest issues -- i.e. build
or run failures, which will almost certainly happen on various platforms.
All comments should be sent to ben@xemacs.org -- use a Cc: if necessary
when sending to mailing lists. There will be pre- and post- tags,
something like
pre-ben-mule-21-5-merge-in, and
post-ben-mule-21-5-merge-in.
author | ben |
---|---|
date | Wed, 13 Mar 2002 08:54:06 +0000 |
parents | a307f9a2021d |
children | e38acbeb1cae |
comparison
equal
deleted
inserted
replaced
770:336a418893b5 | 771:943eaba38521 |
---|---|
1 /* String search routines for XEmacs. | 1 /* String search routines for XEmacs. |
2 Copyright (C) 1985, 1986, 1987, 1992-1995 Free Software Foundation, Inc. | 2 Copyright (C) 1985, 1986, 1987, 1992-1995 Free Software Foundation, Inc. |
3 Copyright (C) 1995 Sun Microsystems, Inc. | 3 Copyright (C) 1995 Sun Microsystems, Inc. |
4 Copyright (C) 2001 Ben Wing. | |
4 | 5 |
5 This file is part of XEmacs. | 6 This file is part of XEmacs. |
6 | 7 |
7 XEmacs is free software; you can redistribute it and/or modify it | 8 XEmacs is free software; you can redistribute it and/or modify it |
8 under the terms of the GNU General Public License as published by the | 9 under the terms of the GNU General Public License as published by the |
121 static Charbpos search_buffer (struct buffer *buf, Lisp_Object str, | 122 static Charbpos search_buffer (struct buffer *buf, Lisp_Object str, |
122 Charbpos charbpos, Charbpos buflim, EMACS_INT n, int RE, | 123 Charbpos charbpos, Charbpos buflim, EMACS_INT n, int RE, |
123 Lisp_Object trt, Lisp_Object inverse_trt, | 124 Lisp_Object trt, Lisp_Object inverse_trt, |
124 int posix); | 125 int posix); |
125 | 126 |
127 struct regex_reentrancy | |
128 { | |
129 struct syntax_cache cache; | |
130 struct buffer *regex_emacs_buffer; | |
131 Lisp_Object regex_match_object; | |
132 }; | |
133 | |
134 typedef struct | |
135 { | |
136 Dynarr_declare (struct regex_reentrancy); | |
137 } regex_reentrancy_dynarr; | |
138 | |
139 static regex_reentrancy_dynarr *the_regex_reentrancy_dynarr; | |
140 | |
141 static Lisp_Object | |
142 restore_regex_reentrancy (Lisp_Object dummy) | |
143 { | |
144 struct regex_reentrancy rr = Dynarr_pop (the_regex_reentrancy_dynarr); | |
145 syntax_cache = rr.cache; | |
146 regex_emacs_buffer = rr.regex_emacs_buffer; | |
147 regex_match_object = rr.regex_match_object; | |
148 return Qnil; | |
149 } | |
150 | |
151 static int | |
152 begin_regex_reentrancy (void) | |
153 { | |
154 /* #### there is still a potential problem with the regex cache -- | |
155 the compiled regex could be overwritten. we'd need 20-fold | |
156 reentrancy, though. */ | |
157 struct regex_reentrancy rr; | |
158 rr.cache = syntax_cache; | |
159 rr.regex_emacs_buffer = regex_emacs_buffer; | |
160 rr.regex_match_object = regex_match_object; | |
161 if (!the_regex_reentrancy_dynarr) | |
162 the_regex_reentrancy_dynarr = Dynarr_new2 (regex_reentrancy_dynarr, | |
163 struct regex_reentrancy); | |
164 Dynarr_add (the_regex_reentrancy_dynarr, rr); | |
165 return record_unwind_protect (restore_regex_reentrancy, Qnil); | |
166 } | |
167 | |
126 static void | 168 static void |
127 matcher_overflow (void) | 169 matcher_overflow (void) |
128 { | 170 { |
129 stack_overflow ("Stack overflow in regexp matcher", Qunbound); | 171 stack_overflow ("Stack overflow in regexp matcher", Qunbound); |
130 } | 172 } |
270 for (i = 0; i < num_regs; i++) | 312 for (i = 0; i < num_regs; i++) |
271 { | 313 { |
272 if (search_regs.start[i] > 0) | 314 if (search_regs.start[i] > 0) |
273 { | 315 { |
274 search_regs.start[i] = | 316 search_regs.start[i] = |
275 bytecount_to_charcount (XSTRING_DATA (string), | 317 XSTRING_INDEX_BYTE_TO_CHAR (string, search_regs.start[i]); |
276 search_regs.start[i]); | |
277 } | 318 } |
278 if (search_regs.end[i] > 0) | 319 if (search_regs.end[i] > 0) |
279 { | 320 { |
280 search_regs.end[i] = | 321 search_regs.end[i] = |
281 bytecount_to_charcount (XSTRING_DATA (string), | 322 XSTRING_INDEX_BYTE_TO_CHAR (string, search_regs.end[i]); |
282 search_regs.end[i]); | |
283 } | 323 } |
284 } | 324 } |
285 } | 325 } |
286 | 326 |
287 | 327 |
292 Lisp_Object val; | 332 Lisp_Object val; |
293 Bytebpos p1, p2; | 333 Bytebpos p1, p2; |
294 Bytecount s1, s2; | 334 Bytecount s1, s2; |
295 REGISTER int i; | 335 REGISTER int i; |
296 struct re_pattern_buffer *bufp; | 336 struct re_pattern_buffer *bufp; |
337 int count = begin_regex_reentrancy (); | |
297 | 338 |
298 if (running_asynch_code) | 339 if (running_asynch_code) |
299 save_search_regs (); | 340 save_search_regs (); |
300 | 341 |
301 CHECK_STRING (string); | 342 CHECK_STRING (string); |
324 if (i == -2) | 365 if (i == -2) |
325 matcher_overflow (); | 366 matcher_overflow (); |
326 | 367 |
327 val = (0 <= i ? Qt : Qnil); | 368 val = (0 <= i ? Qt : Qnil); |
328 if (NILP (val)) | 369 if (NILP (val)) |
329 return Qnil; | 370 return unbind_to (count); |
330 { | 371 { |
331 int num_regs = search_regs.num_regs; | 372 int num_regs = search_regs.num_regs; |
332 for (i = 0; i < num_regs; i++) | 373 for (i = 0; i < num_regs; i++) |
333 if (search_regs.start[i] >= 0) | 374 if (search_regs.start[i] >= 0) |
334 { | 375 { |
336 search_regs.end[i] += BI_BUF_BEGV (buf); | 377 search_regs.end[i] += BI_BUF_BEGV (buf); |
337 } | 378 } |
338 } | 379 } |
339 XSETBUFFER (last_thing_searched, buf); | 380 XSETBUFFER (last_thing_searched, buf); |
340 fixup_search_regs_for_buffer (buf); | 381 fixup_search_regs_for_buffer (buf); |
341 return val; | 382 return unbind_to_1 (count, val); |
342 } | 383 } |
343 | 384 |
344 DEFUN ("looking-at", Flooking_at, 1, 2, 0, /* | 385 DEFUN ("looking-at", Flooking_at, 1, 2, 0, /* |
345 Return t if text after point matches regular expression REGEXP. | 386 Return t if text after point matches regular expression REGEXP. |
346 This function modifies the match data that `match-beginning', | 387 This function modifies the match data that `match-beginning', |
374 { | 415 { |
375 /* This function has been Mule-ized, except for the trt table handling. */ | 416 /* This function has been Mule-ized, except for the trt table handling. */ |
376 Bytecount val; | 417 Bytecount val; |
377 Charcount s; | 418 Charcount s; |
378 struct re_pattern_buffer *bufp; | 419 struct re_pattern_buffer *bufp; |
420 int count = begin_regex_reentrancy (); | |
379 | 421 |
380 if (running_asynch_code) | 422 if (running_asynch_code) |
381 save_search_regs (); | 423 save_search_regs (); |
382 | 424 |
383 CHECK_STRING (regexp); | 425 CHECK_STRING (regexp); |
402 (!NILP (buf->case_fold_search) | 444 (!NILP (buf->case_fold_search) |
403 ? XCASE_TABLE_DOWNCASE (buf->case_table) : Qnil), | 445 ? XCASE_TABLE_DOWNCASE (buf->case_table) : Qnil), |
404 0, ERROR_ME); | 446 0, ERROR_ME); |
405 QUIT; | 447 QUIT; |
406 { | 448 { |
407 Bytecount bis = charcount_to_bytecount (XSTRING_DATA (string), s); | 449 Bytecount bis = XSTRING_INDEX_CHAR_TO_BYTE (string, s); |
408 regex_match_object = string; | 450 regex_match_object = string; |
409 regex_emacs_buffer = buf; | 451 regex_emacs_buffer = buf; |
410 val = re_search (bufp, (char *) XSTRING_DATA (string), | 452 val = re_search (bufp, (char *) XSTRING_DATA (string), |
411 XSTRING_LENGTH (string), bis, | 453 XSTRING_LENGTH (string), bis, |
412 XSTRING_LENGTH (string) - bis, | 454 XSTRING_LENGTH (string) - bis, |
413 &search_regs); | 455 &search_regs); |
414 } | 456 } |
415 if (val == -2) | 457 if (val == -2) |
416 matcher_overflow (); | 458 matcher_overflow (); |
417 if (val < 0) return Qnil; | 459 if (val < 0) return unbind_to (count); |
418 last_thing_searched = Qt; | 460 last_thing_searched = Qt; |
419 fixup_search_regs_for_string (string); | 461 fixup_search_regs_for_string (string); |
420 return make_int (bytecount_to_charcount (XSTRING_DATA (string), val)); | 462 return |
463 unbind_to_1 (count, | |
464 make_int (XSTRING_INDEX_BYTE_TO_CHAR (string, val))); | |
421 } | 465 } |
422 | 466 |
423 DEFUN ("string-match", Fstring_match, 2, 4, 0, /* | 467 DEFUN ("string-match", Fstring_match, 2, 4, 0, /* |
424 Return index of start of first match for REGEXP in STRING, or nil. | 468 Return index of start of first match for REGEXP in STRING, or nil. |
425 If third arg START is non-nil, start search at that index in STRING. | 469 If third arg START is non-nil, start search at that index in STRING. |
465 { | 509 { |
466 /* This function has been Mule-ized, except for the trt table handling. */ | 510 /* This function has been Mule-ized, except for the trt table handling. */ |
467 Bytecount val; | 511 Bytecount val; |
468 Intbyte *newnonreloc = (Intbyte *) nonreloc; | 512 Intbyte *newnonreloc = (Intbyte *) nonreloc; |
469 struct re_pattern_buffer *bufp; | 513 struct re_pattern_buffer *bufp; |
514 int count; | |
470 | 515 |
471 bufp = compile_pattern (regexp, 0, | 516 bufp = compile_pattern (regexp, 0, |
472 (case_fold_search | 517 (case_fold_search |
473 ? XCASE_TABLE_DOWNCASE (current_buffer->case_table) | 518 ? XCASE_TABLE_DOWNCASE (Vstandard_case_table) |
474 : Qnil), | 519 : Qnil), |
475 0, errb); | 520 0, errb); |
476 if (!bufp) | 521 if (!bufp) |
477 return -1; /* will only do this when errb != ERROR_ME */ | 522 return -1; /* will only do this when errb != ERROR_ME */ |
478 if (!no_quit) | 523 if (!no_quit) |
480 else | 525 else |
481 no_quit_in_re_search = 1; | 526 no_quit_in_re_search = 1; |
482 | 527 |
483 fixup_internal_substring (nonreloc, reloc, offset, &length); | 528 fixup_internal_substring (nonreloc, reloc, offset, &length); |
484 | 529 |
530 /* Don't need to protect against GC inside of re_search() due to QUIT; | |
531 QUIT is GC-inhibited. */ | |
485 if (!NILP (reloc)) | 532 if (!NILP (reloc)) |
486 { | 533 newnonreloc = XSTRING_DATA (reloc); |
487 if (no_quit) | 534 |
488 newnonreloc = XSTRING_DATA (reloc); | 535 count = begin_regex_reentrancy (); |
489 else | |
490 { | |
491 /* QUIT could relocate RELOC. Therefore we must alloca() | |
492 and copy. No way around this except some serious | |
493 rewriting of re_search(). */ | |
494 newnonreloc = (Intbyte *) alloca (length); | |
495 memcpy (newnonreloc, XSTRING_DATA (reloc), length); | |
496 } | |
497 } | |
498 | |
499 /* #### evil current-buffer dependency */ | 536 /* #### evil current-buffer dependency */ |
500 regex_match_object = reloc; | 537 regex_match_object = reloc; |
501 regex_emacs_buffer = current_buffer; | 538 regex_emacs_buffer = current_buffer; |
502 val = re_search (bufp, (char *) newnonreloc + offset, length, 0, | 539 val = re_search (bufp, (char *) newnonreloc + offset, length, 0, |
503 length, 0); | 540 length, 0); |
504 | 541 |
505 no_quit_in_re_search = 0; | 542 no_quit_in_re_search = 0; |
543 unbind_to (count); | |
506 return val; | 544 return val; |
507 } | 545 } |
508 | 546 |
509 Bytecount | 547 Bytecount |
510 fast_lisp_string_match (Lisp_Object regex, Lisp_Object string) | 548 fast_lisp_string_match (Lisp_Object regex, Lisp_Object string) |
1139 Intbyte *base_pat = XSTRING_DATA (string); | 1177 Intbyte *base_pat = XSTRING_DATA (string); |
1140 REGISTER EMACS_INT i, j; | 1178 REGISTER EMACS_INT i, j; |
1141 Bytebpos p1, p2; | 1179 Bytebpos p1, p2; |
1142 Bytecount s1, s2; | 1180 Bytecount s1, s2; |
1143 Bytebpos pos, lim; | 1181 Bytebpos pos, lim; |
1182 int count; | |
1144 | 1183 |
1145 if (running_asynch_code) | 1184 if (running_asynch_code) |
1146 save_search_regs (); | 1185 save_search_regs (); |
1147 | 1186 |
1148 /* Null string is found at starting position. */ | 1187 /* Null string is found at starting position. */ |
1159 pos = charbpos_to_bytebpos (buf, charbpos); | 1198 pos = charbpos_to_bytebpos (buf, charbpos); |
1160 lim = charbpos_to_bytebpos (buf, buflim); | 1199 lim = charbpos_to_bytebpos (buf, buflim); |
1161 if (RE && !trivial_regexp_p (string)) | 1200 if (RE && !trivial_regexp_p (string)) |
1162 { | 1201 { |
1163 struct re_pattern_buffer *bufp; | 1202 struct re_pattern_buffer *bufp; |
1203 count = begin_regex_reentrancy (); | |
1164 | 1204 |
1165 bufp = compile_pattern (string, &search_regs, trt, posix, | 1205 bufp = compile_pattern (string, &search_regs, trt, posix, |
1166 ERROR_ME); | 1206 ERROR_ME); |
1167 | 1207 |
1168 /* Get pointers and sizes of the two strings | 1208 /* Get pointers and sizes of the two strings |
1206 /* And charbpos too. */ | 1246 /* And charbpos too. */ |
1207 charbpos = search_regs.start[0]; | 1247 charbpos = search_regs.start[0]; |
1208 } | 1248 } |
1209 else | 1249 else |
1210 { | 1250 { |
1251 unbind_to (count); | |
1211 return n; | 1252 return n; |
1212 } | 1253 } |
1213 n++; | 1254 n++; |
1214 } | 1255 } |
1215 while (n > 0) | 1256 while (n > 0) |
1243 /* And charbpos too. */ | 1284 /* And charbpos too. */ |
1244 charbpos = search_regs.end[0]; | 1285 charbpos = search_regs.end[0]; |
1245 } | 1286 } |
1246 else | 1287 else |
1247 { | 1288 { |
1289 unbind_to (count); | |
1248 return 0 - n; | 1290 return 0 - n; |
1249 } | 1291 } |
1250 n--; | 1292 n--; |
1251 } | 1293 } |
1294 unbind_to (count); | |
1252 return charbpos; | 1295 return charbpos; |
1253 } | 1296 } |
1254 else /* non-RE case */ | 1297 else /* non-RE case */ |
1255 { | 1298 { |
1256 int charset_base = -1; | 1299 int charset_base = -1; |
1631 j = (unsigned char) ch; | 1674 j = (unsigned char) ch; |
1632 | 1675 |
1633 /* For all the characters that map into CH, | 1676 /* For all the characters that map into CH, |
1634 set up simple_translate to map the last byte | 1677 set up simple_translate to map the last byte |
1635 into STARTING_J. */ | 1678 into STARTING_J. */ |
1636 simple_translate[j] = starting_j; | 1679 simple_translate[j] = (Intbyte) starting_j; |
1637 if (ch == starting_ch) | 1680 if (ch == starting_ch) |
1638 break; | 1681 break; |
1639 BM_tab[j] = dirlen - i; | 1682 BM_tab[j] = dirlen - i; |
1640 } | 1683 } |
1641 } | 1684 } |
2556 set_string_char (XSTRING (replacement), strpos, newchar); | 2599 set_string_char (XSTRING (replacement), strpos, newchar); |
2557 } | 2600 } |
2558 } | 2601 } |
2559 | 2602 |
2560 /* frees the Dynarrs if necessary. */ | 2603 /* frees the Dynarrs if necessary. */ |
2561 unbind_to (speccount, Qnil); | 2604 unbind_to (speccount); |
2562 return concat3 (before, replacement, after); | 2605 return concat3 (before, replacement, after); |
2563 } | 2606 } |
2564 | 2607 |
2565 mc_count = begin_multiple_change (buf, search_regs.start[sub], | 2608 mc_count = begin_multiple_change (buf, search_regs.start[sub], |
2566 search_regs.end[sub]); | 2609 search_regs.end[sub]); |
2689 buffer_replace_char (buf, pos, newchar, 0, 0); | 2732 buffer_replace_char (buf, pos, newchar, 0, 0); |
2690 } | 2733 } |
2691 } | 2734 } |
2692 | 2735 |
2693 /* frees the Dynarrs if necessary. */ | 2736 /* frees the Dynarrs if necessary. */ |
2694 unbind_to (speccount, Qnil); | 2737 unbind_to (speccount); |
2695 end_multiple_change (buf, mc_count); | 2738 end_multiple_change (buf, mc_count); |
2696 | 2739 |
2697 return Qnil; | 2740 return Qnil; |
2698 } | 2741 } |
2699 | 2742 |