| 2041 |
case OP_MINUPTO: |
case OP_MINUPTO: |
| 2042 |
if (isprint(c = code[3])) printf(" %c{", c); |
if (isprint(c = code[3])) printf(" %c{", c); |
| 2043 |
else printf(" \\x%02x{", c); |
else printf(" \\x%02x{", c); |
| 2044 |
if (*code != OP_EXACT) printf(","); |
if (*code != OP_EXACT) printf("0,"); |
| 2045 |
printf("%d}", (code[1] << 8) + code[2]); |
printf("%d}", (code[1] << 8) + code[2]); |
| 2046 |
if (*code == OP_MINUPTO) printf("?"); |
if (*code == OP_MINUPTO) printf("?"); |
| 2047 |
code += 3; |
code += 3; |
| 3299 |
since it's needed only for the extension \X option, and with any luck, a good |
since it's needed only for the extension \X option, and with any luck, a good |
| 3300 |
compiler will spot the tail recursion and compile it efficiently. |
compiler will spot the tail recursion and compile it efficiently. |
| 3301 |
|
|
| 3302 |
Arguments: The block containing the match data |
Arguments: |
| 3303 |
Returns: The return from setjump() |
eptr pointer in subject |
| 3304 |
|
ecode position in code |
| 3305 |
|
offset_top current top pointer |
| 3306 |
|
md pointer to "static" info for the match |
| 3307 |
|
|
| 3308 |
|
Returns: TRUE if matched |
| 3309 |
*/ |
*/ |
| 3310 |
|
|
| 3311 |
static int |
static BOOL |
| 3312 |
my_setjmp(match_data *match_block) |
match_with_setjmp(const uschar *eptr, const uschar *ecode, int offset_top, |
| 3313 |
|
match_data *match_block) |
| 3314 |
{ |
{ |
| 3315 |
return setjmp(match_block->fail_env); |
return setjmp(match_block->fail_env) == 0 && |
| 3316 |
|
match(eptr, ecode, offset_top, match_block); |
| 3317 |
} |
} |
| 3318 |
|
|
| 3319 |
|
|
| 3345 |
pcre_exec(const pcre *external_re, const pcre_extra *external_extra, |
pcre_exec(const pcre *external_re, const pcre_extra *external_extra, |
| 3346 |
const char *subject, int length, int options, int *offsets, int offsetcount) |
const char *subject, int length, int options, int *offsets, int offsetcount) |
| 3347 |
{ |
{ |
| 3348 |
int resetcount; |
int resetcount, ocount; |
|
int ocount = offsetcount; |
|
| 3349 |
int first_char = -1; |
int first_char = -1; |
| 3350 |
match_data match_block; |
match_data match_block; |
| 3351 |
const uschar *start_bits = NULL; |
const uschar *start_bits = NULL; |
| 3353 |
const uschar *end_subject; |
const uschar *end_subject; |
| 3354 |
const real_pcre *re = (const real_pcre *)external_re; |
const real_pcre *re = (const real_pcre *)external_re; |
| 3355 |
const real_pcre_extra *extra = (const real_pcre_extra *)external_extra; |
const real_pcre_extra *extra = (const real_pcre_extra *)external_extra; |
| 3356 |
|
BOOL using_temporary_offsets = FALSE; |
| 3357 |
BOOL anchored = ((re->options | options) & PCRE_ANCHORED) != 0; |
BOOL anchored = ((re->options | options) & PCRE_ANCHORED) != 0; |
| 3358 |
BOOL startline = (re->options & PCRE_STARTLINE) != 0; |
BOOL startline = (re->options & PCRE_STARTLINE) != 0; |
| 3359 |
|
|
| 3382 |
|
|
| 3383 |
/* If the expression has got more back references than the offsets supplied can |
/* If the expression has got more back references than the offsets supplied can |
| 3384 |
hold, we get a temporary bit of working store to use during the matching. |
hold, we get a temporary bit of working store to use during the matching. |
| 3385 |
Otherwise, we can use the vector supplied, rounding down the size of it to a |
Otherwise, we can use the vector supplied, rounding down its size to a multiple |
| 3386 |
multiple of 2. */ |
of 2. */ |
| 3387 |
|
|
| 3388 |
ocount &= (-2); |
ocount = offsetcount & (-2); |
| 3389 |
if (re->top_backref > 0 && re->top_backref + 1 >= ocount/2) |
if (re->top_backref > 0 && re->top_backref >= ocount/2) |
| 3390 |
{ |
{ |
| 3391 |
ocount = re->top_backref * 2 + 2; |
ocount = re->top_backref * 2 + 2; |
| 3392 |
match_block.offset_vector = (pcre_malloc)(ocount * sizeof(int)); |
match_block.offset_vector = (pcre_malloc)(ocount * sizeof(int)); |
| 3393 |
if (match_block.offset_vector == NULL) return PCRE_ERROR_NOMEMORY; |
if (match_block.offset_vector == NULL) return PCRE_ERROR_NOMEMORY; |
| 3394 |
|
using_temporary_offsets = TRUE; |
| 3395 |
DPRINTF(("Got memory to hold back references\n")); |
DPRINTF(("Got memory to hold back references\n")); |
| 3396 |
} |
} |
| 3397 |
else match_block.offset_vector = offsets; |
else match_block.offset_vector = offsets; |
| 3506 |
it unless PCRE_EXTRA is set, since only in that case is the "cut" operation |
it unless PCRE_EXTRA is set, since only in that case is the "cut" operation |
| 3507 |
enabled. */ |
enabled. */ |
| 3508 |
|
|
| 3509 |
if (((re->options & PCRE_EXTRA) != 0 && my_setjmp(&match_block) != 0) || |
if ((re->options & PCRE_EXTRA) != 0) |
| 3510 |
!match(start_match, re->code, 2, &match_block)) |
{ |
| 3511 |
continue; |
if (!match_with_setjmp(start_match, re->code, 2, &match_block)) |
| 3512 |
|
continue; |
| 3513 |
|
} |
| 3514 |
|
else if (!match(start_match, re->code, 2, &match_block)) continue; |
| 3515 |
|
|
| 3516 |
/* Copy the offset information from temporary store if necessary */ |
/* Copy the offset information from temporary store if necessary */ |
| 3517 |
|
|
| 3518 |
if (ocount != offsetcount) |
if (using_temporary_offsets) |
| 3519 |
{ |
{ |
| 3520 |
if (offsetcount >= 4) |
if (offsetcount >= 4) |
| 3521 |
{ |
{ |
| 3522 |
memcpy(offsets + 2, match_block.offset_vector + 2, |
memcpy(offsets + 2, match_block.offset_vector + 2, |
| 3523 |
(offsetcount - 2) * sizeof(int)); |
(offsetcount - 2) * sizeof(int)); |
| 3524 |
DPRINTF(("Copied offsets; freeing temporary memory\n")); |
DPRINTF(("Copied offsets from temporary memory\n")); |
| 3525 |
} |
} |
| 3526 |
if (match_block.end_offset_top > offsetcount) |
if (match_block.end_offset_top > offsetcount) |
| 3527 |
match_block.offset_overflow = TRUE; |
match_block.offset_overflow = TRUE; |
| 3545 |
match_block.errorcode == PCRE_ERROR_NOMATCH && |
match_block.errorcode == PCRE_ERROR_NOMATCH && |
| 3546 |
start_match++ < end_subject); |
start_match++ < end_subject); |
| 3547 |
|
|
| 3548 |
|
if (using_temporary_offsets) |
| 3549 |
|
{ |
| 3550 |
|
DPRINTF(("Freeing temporary memory\n")); |
| 3551 |
|
(pcre_free)(match_block.offset_vector); |
| 3552 |
|
} |
| 3553 |
|
|
| 3554 |
DPRINTF((">>>> returning %d\n", match_block.errorcode)); |
DPRINTF((">>>> returning %d\n", match_block.errorcode)); |
| 3555 |
|
|
| 3556 |
return match_block.errorcode; |
return match_block.errorcode; |