| 47 |
start_bits points to the bit map |
start_bits points to the bit map |
| 48 |
c is the character |
c is the character |
| 49 |
caseless the caseless flag |
caseless the caseless flag |
| 50 |
|
cd the block with char table pointers |
| 51 |
|
|
| 52 |
Returns: nothing |
Returns: nothing |
| 53 |
*/ |
*/ |
| 54 |
|
|
| 55 |
static void |
static void |
| 56 |
set_bit(uschar *start_bits, int c, BOOL caseless) |
set_bit(uschar *start_bits, int c, BOOL caseless, compile_data *cd) |
| 57 |
{ |
{ |
| 58 |
start_bits[c/8] |= (1 << (c&7)); |
start_bits[c/8] |= (1 << (c&7)); |
| 59 |
if (caseless && (pcre_ctypes[c] & ctype_letter) != 0) |
if (caseless && (cd->ctypes[c] & ctype_letter) != 0) |
| 60 |
start_bits[pcre_fcc[c]/8] |= (1 << (pcre_fcc[c]&7)); |
start_bits[cd->fcc[c]/8] |= (1 << (cd->fcc[c]&7)); |
| 61 |
} |
} |
| 62 |
|
|
| 63 |
|
|
| 74 |
code points to an expression |
code points to an expression |
| 75 |
start_bits points to a 32-byte table, initialized to 0 |
start_bits points to a 32-byte table, initialized to 0 |
| 76 |
caseless the current state of the caseless flag |
caseless the current state of the caseless flag |
| 77 |
|
cd the block with char table pointers |
| 78 |
|
|
| 79 |
Returns: TRUE if table built, FALSE otherwise |
Returns: TRUE if table built, FALSE otherwise |
| 80 |
*/ |
*/ |
| 81 |
|
|
| 82 |
static BOOL |
static BOOL |
| 83 |
set_start_bits(const uschar *code, uschar *start_bits, BOOL caseless) |
set_start_bits(const uschar *code, uschar *start_bits, BOOL caseless, |
| 84 |
|
compile_data *cd) |
| 85 |
{ |
{ |
| 86 |
register int c; |
register int c; |
| 87 |
|
|
| 99 |
|
|
| 100 |
if ((int)*tcode >= OP_BRA || *tcode == OP_ASSERT) |
if ((int)*tcode >= OP_BRA || *tcode == OP_ASSERT) |
| 101 |
{ |
{ |
| 102 |
if (!set_start_bits(tcode, start_bits, caseless)) return FALSE; |
if (!set_start_bits(tcode, start_bits, caseless, cd)) |
| 103 |
|
return FALSE; |
| 104 |
} |
} |
| 105 |
|
|
| 106 |
else switch(*tcode) |
else switch(*tcode) |
| 130 |
|
|
| 131 |
case OP_BRAZERO: |
case OP_BRAZERO: |
| 132 |
case OP_BRAMINZERO: |
case OP_BRAMINZERO: |
| 133 |
if (!set_start_bits(++tcode, start_bits, caseless)) return FALSE; |
if (!set_start_bits(++tcode, start_bits, caseless, cd)) |
| 134 |
|
return FALSE; |
| 135 |
do tcode += (tcode[1] << 8) + tcode[2]; while (*tcode == OP_ALT); |
do tcode += (tcode[1] << 8) + tcode[2]; while (*tcode == OP_ALT); |
| 136 |
tcode += 3; |
tcode += 3; |
| 137 |
try_next = TRUE; |
try_next = TRUE; |
| 143 |
case OP_MINSTAR: |
case OP_MINSTAR: |
| 144 |
case OP_QUERY: |
case OP_QUERY: |
| 145 |
case OP_MINQUERY: |
case OP_MINQUERY: |
| 146 |
set_bit(start_bits, tcode[1], caseless); |
set_bit(start_bits, tcode[1], caseless, cd); |
| 147 |
tcode += 2; |
tcode += 2; |
| 148 |
try_next = TRUE; |
try_next = TRUE; |
| 149 |
break; |
break; |
| 152 |
|
|
| 153 |
case OP_UPTO: |
case OP_UPTO: |
| 154 |
case OP_MINUPTO: |
case OP_MINUPTO: |
| 155 |
set_bit(start_bits, tcode[3], caseless); |
set_bit(start_bits, tcode[3], caseless, cd); |
| 156 |
tcode += 4; |
tcode += 4; |
| 157 |
try_next = TRUE; |
try_next = TRUE; |
| 158 |
break; |
break; |
| 167 |
|
|
| 168 |
case OP_PLUS: |
case OP_PLUS: |
| 169 |
case OP_MINPLUS: |
case OP_MINPLUS: |
| 170 |
set_bit(start_bits, tcode[1], caseless); |
set_bit(start_bits, tcode[1], caseless, cd); |
| 171 |
break; |
break; |
| 172 |
|
|
| 173 |
/* Single character type sets the bits and stops */ |
/* Single character type sets the bits and stops */ |
| 174 |
|
|
| 175 |
case OP_NOT_DIGIT: |
case OP_NOT_DIGIT: |
| 176 |
for (c = 0; c < 32; c++) start_bits[c] |= ~pcre_cbits[c+cbit_digit]; |
for (c = 0; c < 32; c++) |
| 177 |
|
start_bits[c] |= ~cd->cbits[c+cbit_digit]; |
| 178 |
break; |
break; |
| 179 |
|
|
| 180 |
case OP_DIGIT: |
case OP_DIGIT: |
| 181 |
for (c = 0; c < 32; c++) start_bits[c] |= pcre_cbits[c+cbit_digit]; |
for (c = 0; c < 32; c++) |
| 182 |
|
start_bits[c] |= cd->cbits[c+cbit_digit]; |
| 183 |
break; |
break; |
| 184 |
|
|
| 185 |
case OP_NOT_WHITESPACE: |
case OP_NOT_WHITESPACE: |
| 186 |
for (c = 0; c < 32; c++) start_bits[c] |= ~pcre_cbits[c+cbit_space]; |
for (c = 0; c < 32; c++) |
| 187 |
|
start_bits[c] |= ~cd->cbits[c+cbit_space]; |
| 188 |
break; |
break; |
| 189 |
|
|
| 190 |
case OP_WHITESPACE: |
case OP_WHITESPACE: |
| 191 |
for (c = 0; c < 32; c++) start_bits[c] |= pcre_cbits[c+cbit_space]; |
for (c = 0; c < 32; c++) |
| 192 |
|
start_bits[c] |= cd->cbits[c+cbit_space]; |
| 193 |
break; |
break; |
| 194 |
|
|
| 195 |
case OP_NOT_WORDCHAR: |
case OP_NOT_WORDCHAR: |
| 196 |
for (c = 0; c < 32; c++) |
for (c = 0; c < 32; c++) |
| 197 |
start_bits[c] |= ~(pcre_cbits[c] | pcre_cbits[c+cbit_word]); |
start_bits[c] |= ~(cd->cbits[c] | cd->cbits[c+cbit_word]); |
| 198 |
break; |
break; |
| 199 |
|
|
| 200 |
case OP_WORDCHAR: |
case OP_WORDCHAR: |
| 201 |
for (c = 0; c < 32; c++) |
for (c = 0; c < 32; c++) |
| 202 |
start_bits[c] |= (pcre_cbits[c] | pcre_cbits[c+cbit_word]); |
start_bits[c] |= (cd->cbits[c] | cd->cbits[c+cbit_word]); |
| 203 |
break; |
break; |
| 204 |
|
|
| 205 |
/* One or more character type fudges the pointer and restarts, knowing |
/* One or more character type fudges the pointer and restarts, knowing |
| 230 |
switch(tcode[1]) |
switch(tcode[1]) |
| 231 |
{ |
{ |
| 232 |
case OP_NOT_DIGIT: |
case OP_NOT_DIGIT: |
| 233 |
for (c = 0; c < 32; c++) start_bits[c] |= ~pcre_cbits[c+cbit_digit]; |
for (c = 0; c < 32; c++) |
| 234 |
|
start_bits[c] |= ~cd->cbits[c+cbit_digit]; |
| 235 |
break; |
break; |
| 236 |
|
|
| 237 |
case OP_DIGIT: |
case OP_DIGIT: |
| 238 |
for (c = 0; c < 32; c++) start_bits[c] |= pcre_cbits[c+cbit_digit]; |
for (c = 0; c < 32; c++) |
| 239 |
|
start_bits[c] |= cd->cbits[c+cbit_digit]; |
| 240 |
break; |
break; |
| 241 |
|
|
| 242 |
case OP_NOT_WHITESPACE: |
case OP_NOT_WHITESPACE: |
| 243 |
for (c = 0; c < 32; c++) start_bits[c] |= ~pcre_cbits[c+cbit_space]; |
for (c = 0; c < 32; c++) |
| 244 |
|
start_bits[c] |= ~cd->cbits[c+cbit_space]; |
| 245 |
break; |
break; |
| 246 |
|
|
| 247 |
case OP_WHITESPACE: |
case OP_WHITESPACE: |
| 248 |
for (c = 0; c < 32; c++) start_bits[c] |= pcre_cbits[c+cbit_space]; |
for (c = 0; c < 32; c++) |
| 249 |
|
start_bits[c] |= cd->cbits[c+cbit_space]; |
| 250 |
break; |
break; |
| 251 |
|
|
| 252 |
case OP_NOT_WORDCHAR: |
case OP_NOT_WORDCHAR: |
| 253 |
for (c = 0; c < 32; c++) |
for (c = 0; c < 32; c++) |
| 254 |
start_bits[c] |= ~(pcre_cbits[c] | pcre_cbits[c+cbit_word]); |
start_bits[c] |= ~(cd->cbits[c] | cd->cbits[c+cbit_word]); |
| 255 |
break; |
break; |
| 256 |
|
|
| 257 |
case OP_WORDCHAR: |
case OP_WORDCHAR: |
| 258 |
for (c = 0; c < 32; c++) |
for (c = 0; c < 32; c++) |
| 259 |
start_bits[c] |= (pcre_cbits[c] | pcre_cbits[c+cbit_word]); |
start_bits[c] |= (cd->cbits[c] | cd->cbits[c+cbit_word]); |
| 260 |
break; |
break; |
| 261 |
} |
} |
| 262 |
|
|
| 329 |
uschar start_bits[32]; |
uschar start_bits[32]; |
| 330 |
real_pcre_extra *extra; |
real_pcre_extra *extra; |
| 331 |
const real_pcre *re = (const real_pcre *)external_re; |
const real_pcre *re = (const real_pcre *)external_re; |
| 332 |
|
compile_data compile_block; |
| 333 |
|
|
| 334 |
*errorptr = NULL; |
*errorptr = NULL; |
| 335 |
|
|
| 352 |
if ((re->options & (PCRE_ANCHORED|PCRE_FIRSTSET|PCRE_STARTLINE)) != 0) |
if ((re->options & (PCRE_ANCHORED|PCRE_FIRSTSET|PCRE_STARTLINE)) != 0) |
| 353 |
return NULL; |
return NULL; |
| 354 |
|
|
| 355 |
|
/* Set the character tables in the block which is passed around */ |
| 356 |
|
|
| 357 |
|
compile_block.lcc = re->tables + lcc_offset; |
| 358 |
|
compile_block.fcc = re->tables + fcc_offset; |
| 359 |
|
compile_block.cbits = re->tables + cbits_offset; |
| 360 |
|
compile_block.ctypes = re->tables + ctypes_offset; |
| 361 |
|
|
| 362 |
/* See if we can find a fixed set of initial characters for the pattern. */ |
/* See if we can find a fixed set of initial characters for the pattern. */ |
| 363 |
|
|
| 364 |
memset(start_bits, 0, 32 * sizeof(uschar)); |
memset(start_bits, 0, 32 * sizeof(uschar)); |
| 365 |
if (!set_start_bits(re->code, start_bits, (re->options & PCRE_CASELESS) != 0)) |
if (!set_start_bits(re->code, start_bits, (re->options & PCRE_CASELESS) != 0, |
| 366 |
return NULL; |
&compile_block)) return NULL; |
| 367 |
|
|
| 368 |
/* Get an "extra" block and put the information therein. */ |
/* Get an "extra" block and put the information therein. */ |
| 369 |
|
|