1106 |
unsigned char *patbuf; |
unsigned char *patbuf; |
1107 |
int multibyte = !NILP (current_buffer->enable_multibyte_characters); |
int multibyte = !NILP (current_buffer->enable_multibyte_characters); |
1108 |
unsigned char *base_pat = XSTRING (string)->data; |
unsigned char *base_pat = XSTRING (string)->data; |
1109 |
int charset_base = -1; |
/* High bits of char, calculated by (CHAR & 0x3F). Characters |
1110 |
|
of the same high bits have the same sequence of bytes but |
1111 |
|
last. To do the BM search, all characters in STRING must |
1112 |
|
have the same high bits (including their case |
1113 |
|
translations). */ |
1114 |
|
int char_high_bits = -1; |
1115 |
int boyer_moore_ok = 1; |
int boyer_moore_ok = 1; |
1116 |
|
|
1117 |
/* MULTIBYTE says whether the text to be searched is multibyte. |
/* MULTIBYTE says whether the text to be searched is multibyte. |
1152 |
/* Copy and optionally translate the pattern. */ |
/* Copy and optionally translate the pattern. */ |
1153 |
len = raw_pattern_size; |
len = raw_pattern_size; |
1154 |
len_byte = raw_pattern_size_byte; |
len_byte = raw_pattern_size_byte; |
1155 |
patbuf = (unsigned char *) alloca (len_byte); |
patbuf = (unsigned char *) alloca (len * MAX_MULTIBYTE_LENGTH); |
1156 |
pat = patbuf; |
pat = patbuf; |
1157 |
base_pat = raw_pattern; |
base_pat = raw_pattern; |
1158 |
if (multibyte) |
if (multibyte) |
1159 |
{ |
{ |
1160 |
while (--len >= 0) |
while (--len >= 0) |
1161 |
{ |
{ |
|
unsigned char str[MAX_MULTIBYTE_LENGTH]; |
|
1162 |
int c, translated, inverse; |
int c, translated, inverse; |
1163 |
int in_charlen, charlen; |
int in_charlen; |
1164 |
|
|
1165 |
/* If we got here and the RE flag is set, it's because we're |
/* If we got here and the RE flag is set, it's because we're |
1166 |
dealing with a regexp known to be trivial, so the backslash |
dealing with a regexp known to be trivial, so the backslash |
1176 |
|
|
1177 |
/* Translate the character, if requested. */ |
/* Translate the character, if requested. */ |
1178 |
TRANSLATE (translated, trt, c); |
TRANSLATE (translated, trt, c); |
|
/* If translation changed the byte-length, go back |
|
|
to the original character. */ |
|
|
charlen = CHAR_STRING (translated, str); |
|
|
if (in_charlen != charlen) |
|
|
{ |
|
|
translated = c; |
|
|
charlen = CHAR_STRING (c, str); |
|
|
} |
|
|
|
|
|
/* If we are searching for something strange, |
|
|
an invalid multibyte code, don't use boyer-moore. */ |
|
|
if (! ASCII_BYTE_P (translated) |
|
|
&& (charlen == 1 /* 8bit code */ |
|
|
|| charlen != in_charlen /* invalid multibyte code */ |
|
|
)) |
|
|
boyer_moore_ok = 0; |
|
|
|
|
1179 |
TRANSLATE (inverse, inverse_trt, c); |
TRANSLATE (inverse, inverse_trt, c); |
1180 |
|
|
1181 |
/* Did this char actually get translated? |
/* Did this char actually get translated? |
1184 |
{ |
{ |
1185 |
/* Keep track of which character set row |
/* Keep track of which character set row |
1186 |
contains the characters that need translation. */ |
contains the characters that need translation. */ |
1187 |
int charset_base_code = c & ~0x3F; |
int this_high_bit = c & ~0x3F; |
1188 |
if (charset_base == -1) |
int trt_high_bit = ((inverse != c ? inverse : translated) |
1189 |
charset_base = charset_base_code; |
& ~0x3F); |
1190 |
else if (charset_base != charset_base_code) |
|
1191 |
|
if (this_high_bit != trt_high_bit) |
1192 |
|
boyer_moore_ok = 0; |
1193 |
|
else if (char_high_bits == -1) |
1194 |
|
char_high_bits = this_high_bit; |
1195 |
|
else if (char_high_bits != this_high_bit) |
1196 |
/* If two different rows appear, needing translation, |
/* If two different rows appear, needing translation, |
1197 |
then we cannot use boyer_moore search. */ |
then we cannot use boyer_moore search. */ |
1198 |
boyer_moore_ok = 0; |
boyer_moore_ok = 0; |
1199 |
} |
} |
1200 |
|
|
1201 |
/* Store this character into the translated pattern. */ |
/* Store this character into the translated pattern. */ |
1202 |
bcopy (str, pat, charlen); |
CHAR_STRING_ADVANCE (translated, pat); |
|
pat += charlen; |
|
1203 |
base_pat += in_charlen; |
base_pat += in_charlen; |
1204 |
len_byte -= in_charlen; |
len_byte -= in_charlen; |
1205 |
} |
} |
1207 |
else |
else |
1208 |
{ |
{ |
1209 |
/* Unibyte buffer. */ |
/* Unibyte buffer. */ |
1210 |
charset_base = 0; |
char_high_bits = 0; |
1211 |
while (--len >= 0) |
while (--len >= 0) |
1212 |
{ |
{ |
1213 |
int c, translated; |
int c, translated; |
1233 |
if (boyer_moore_ok) |
if (boyer_moore_ok) |
1234 |
return boyer_moore (n, pat, len, len_byte, trt, inverse_trt, |
return boyer_moore (n, pat, len, len_byte, trt, inverse_trt, |
1235 |
pos, pos_byte, lim, lim_byte, |
pos, pos_byte, lim, lim_byte, |
1236 |
charset_base); |
char_high_bits); |
1237 |
else |
else |
1238 |
return simple_search (n, pat, len, len_byte, trt, |
return simple_search (n, pat, len, len_byte, trt, |
1239 |
pos, pos_byte, lim, lim_byte); |
pos, pos_byte, lim, lim_byte); |
1466 |
|
|
1467 |
static int |
static int |
1468 |
boyer_moore (n, base_pat, len, len_byte, trt, inverse_trt, |
boyer_moore (n, base_pat, len, len_byte, trt, inverse_trt, |
1469 |
pos, pos_byte, lim, lim_byte, charset_base) |
pos, pos_byte, lim, lim_byte, char_high_bits) |
1470 |
int n; |
int n; |
1471 |
unsigned char *base_pat; |
unsigned char *base_pat; |
1472 |
int len, len_byte; |
int len, len_byte; |
1474 |
Lisp_Object inverse_trt; |
Lisp_Object inverse_trt; |
1475 |
int pos, pos_byte; |
int pos, pos_byte; |
1476 |
int lim, lim_byte; |
int lim, lim_byte; |
1477 |
int charset_base; |
int char_high_bits; |
1478 |
{ |
{ |
1479 |
int direction = ((n > 0) ? 1 : -1); |
int direction = ((n > 0) ? 1 : -1); |
1480 |
register int dirlen; |
register int dirlen; |
1575 |
while (! CHAR_HEAD_P (*charstart)) |
while (! CHAR_HEAD_P (*charstart)) |
1576 |
charstart--; |
charstart--; |
1577 |
untranslated = STRING_CHAR (charstart, ptr - charstart + 1); |
untranslated = STRING_CHAR (charstart, ptr - charstart + 1); |
1578 |
if (charset_base == (untranslated & ~0x3F)) |
if (char_high_bits == (untranslated & ~0x3F)) |
1579 |
{ |
{ |
1580 |
TRANSLATE (ch, trt, untranslated); |
TRANSLATE (ch, trt, untranslated); |
1581 |
if (! CHAR_HEAD_P (*ptr)) |
if (! CHAR_HEAD_P (*ptr)) |