226 |
#define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \ |
#define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \ |
227 |
{ \ |
{ \ |
228 |
printf("match() called in line %d\n", __LINE__); \ |
printf("match() called in line %d\n", __LINE__); \ |
229 |
rrc = match(ra,rb,rc,rd,re,rf,rg,rdepth+1); \ |
rrc = match(ra,rb,mstart,rc,rd,re,rf,rg,rdepth+1); \ |
230 |
printf("to line %d\n", __LINE__); \ |
printf("to line %d\n", __LINE__); \ |
231 |
} |
} |
232 |
#define RRETURN(ra) \ |
#define RRETURN(ra) \ |
236 |
} |
} |
237 |
#else |
#else |
238 |
#define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \ |
#define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \ |
239 |
rrc = match(ra,rb,rc,rd,re,rf,rg,rdepth+1) |
rrc = match(ra,rb,mstart,rc,rd,re,rf,rg,rdepth+1) |
240 |
#define RRETURN(ra) return ra |
#define RRETURN(ra) return ra |
241 |
#endif |
#endif |
242 |
|
|
255 |
frame->Xwhere = rw; \ |
frame->Xwhere = rw; \ |
256 |
newframe->Xeptr = ra;\ |
newframe->Xeptr = ra;\ |
257 |
newframe->Xecode = rb;\ |
newframe->Xecode = rb;\ |
258 |
|
newframe->Xmstart = mstart;\ |
259 |
newframe->Xoffset_top = rc;\ |
newframe->Xoffset_top = rc;\ |
260 |
newframe->Xims = re;\ |
newframe->Xims = re;\ |
261 |
newframe->Xeptrb = rf;\ |
newframe->Xeptrb = rf;\ |
292 |
|
|
293 |
const uschar *Xeptr; |
const uschar *Xeptr; |
294 |
const uschar *Xecode; |
const uschar *Xecode; |
295 |
|
const uschar *Xmstart; |
296 |
int Xoffset_top; |
int Xoffset_top; |
297 |
long int Xims; |
long int Xims; |
298 |
eptrblock *Xeptrb; |
eptrblock *Xeptrb; |
373 |
Arguments: |
Arguments: |
374 |
eptr pointer to current character in subject |
eptr pointer to current character in subject |
375 |
ecode pointer to current position in compiled code |
ecode pointer to current position in compiled code |
376 |
|
mstart pointer to the current match start position (can be modified |
377 |
|
by encountering \K) |
378 |
offset_top current top pointer |
offset_top current top pointer |
379 |
md pointer to "static" info for the match |
md pointer to "static" info for the match |
380 |
ims current /i, /m, and /s options |
ims current /i, /m, and /s options |
394 |
*/ |
*/ |
395 |
|
|
396 |
static int |
static int |
397 |
match(REGISTER USPTR eptr, REGISTER const uschar *ecode, |
match(REGISTER USPTR eptr, REGISTER const uschar *ecode, const uschar *mstart, |
398 |
int offset_top, match_data *md, unsigned long int ims, eptrblock *eptrb, |
int offset_top, match_data *md, unsigned long int ims, eptrblock *eptrb, |
399 |
int flags, unsigned int rdepth) |
int flags, unsigned int rdepth) |
400 |
{ |
{ |
422 |
|
|
423 |
frame->Xeptr = eptr; |
frame->Xeptr = eptr; |
424 |
frame->Xecode = ecode; |
frame->Xecode = ecode; |
425 |
|
frame->Xmstart = mstart; |
426 |
frame->Xoffset_top = offset_top; |
frame->Xoffset_top = offset_top; |
427 |
frame->Xims = ims; |
frame->Xims = ims; |
428 |
frame->Xeptrb = eptrb; |
frame->Xeptrb = eptrb; |
437 |
|
|
438 |
#define eptr frame->Xeptr |
#define eptr frame->Xeptr |
439 |
#define ecode frame->Xecode |
#define ecode frame->Xecode |
440 |
|
#define mstart frame->Xmstart |
441 |
#define offset_top frame->Xoffset_top |
#define offset_top frame->Xoffset_top |
442 |
#define ims frame->Xims |
#define ims frame->Xims |
443 |
#define eptrb frame->Xeptrb |
#define eptrb frame->Xeptrb |
616 |
|
|
617 |
if (md->partial && |
if (md->partial && |
618 |
eptr >= md->end_subject && |
eptr >= md->end_subject && |
619 |
eptr > md->start_match) |
eptr > mstart) |
620 |
md->hitend = TRUE; |
md->hitend = TRUE; |
621 |
|
|
622 |
switch(op) |
switch(op) |
793 |
md->recursive = rec->prevrec; |
md->recursive = rec->prevrec; |
794 |
memmove(md->offset_vector, rec->offset_save, |
memmove(md->offset_vector, rec->offset_save, |
795 |
rec->saved_max * sizeof(int)); |
rec->saved_max * sizeof(int)); |
796 |
md->start_match = rec->save_start; |
mstart = rec->save_start; |
797 |
ims = original_ims; |
ims = original_ims; |
798 |
ecode = rec->after_call; |
ecode = rec->after_call; |
799 |
break; |
break; |
802 |
/* Otherwise, if PCRE_NOTEMPTY is set, fail if we have matched an empty |
/* Otherwise, if PCRE_NOTEMPTY is set, fail if we have matched an empty |
803 |
string - backtracking will then try other alternatives, if any. */ |
string - backtracking will then try other alternatives, if any. */ |
804 |
|
|
805 |
if (md->notempty && eptr == md->start_match) RRETURN(MATCH_NOMATCH); |
if (md->notempty && eptr == mstart) RRETURN(MATCH_NOMATCH); |
806 |
md->end_match_ptr = eptr; /* Record where we ended */ |
md->end_match_ptr = eptr; /* Record where we ended */ |
807 |
md->end_offset_top = offset_top; /* and how many extracts were taken */ |
md->end_offset_top = offset_top; /* and how many extracts were taken */ |
808 |
|
md->start_match_ptr = mstart; /* and the start (\K can modify) */ |
809 |
RRETURN(MATCH_MATCH); |
RRETURN(MATCH_MATCH); |
810 |
|
|
811 |
/* Change option settings */ |
/* Change option settings */ |
911 |
cb.offset_vector = md->offset_vector; |
cb.offset_vector = md->offset_vector; |
912 |
cb.subject = (PCRE_SPTR)md->start_subject; |
cb.subject = (PCRE_SPTR)md->start_subject; |
913 |
cb.subject_length = md->end_subject - md->start_subject; |
cb.subject_length = md->end_subject - md->start_subject; |
914 |
cb.start_match = md->start_match - md->start_subject; |
cb.start_match = mstart - md->start_subject; |
915 |
cb.current_position = eptr - md->start_subject; |
cb.current_position = eptr - md->start_subject; |
916 |
cb.pattern_position = GET(ecode, 2); |
cb.pattern_position = GET(ecode, 2); |
917 |
cb.next_item_length = GET(ecode, 2 + LINK_SIZE); |
cb.next_item_length = GET(ecode, 2 + LINK_SIZE); |
973 |
|
|
974 |
memcpy(new_recursive.offset_save, md->offset_vector, |
memcpy(new_recursive.offset_save, md->offset_vector, |
975 |
new_recursive.saved_max * sizeof(int)); |
new_recursive.saved_max * sizeof(int)); |
976 |
new_recursive.save_start = md->start_match; |
new_recursive.save_start = mstart; |
977 |
md->start_match = eptr; |
mstart = eptr; |
978 |
|
|
979 |
/* OK, now we can do the recursion. For each top-level alternative we |
/* OK, now we can do the recursion. For each top-level alternative we |
980 |
restore the offset and recursion data. */ |
restore the offset and recursion data. */ |
1187 |
recursion_info *rec = md->recursive; |
recursion_info *rec = md->recursive; |
1188 |
DPRINTF(("Recursion (%d) succeeded - continuing\n", number)); |
DPRINTF(("Recursion (%d) succeeded - continuing\n", number)); |
1189 |
md->recursive = rec->prevrec; |
md->recursive = rec->prevrec; |
1190 |
md->start_match = rec->save_start; |
mstart = rec->save_start; |
1191 |
memcpy(md->offset_vector, rec->offset_save, |
memcpy(md->offset_vector, rec->offset_save, |
1192 |
rec->saved_max * sizeof(int)); |
rec->saved_max * sizeof(int)); |
1193 |
ecode = rec->after_call; |
ecode = rec->after_call; |
1266 |
if (eptr != md->start_subject + md->start_offset) RRETURN(MATCH_NOMATCH); |
if (eptr != md->start_subject + md->start_offset) RRETURN(MATCH_NOMATCH); |
1267 |
ecode++; |
ecode++; |
1268 |
break; |
break; |
1269 |
|
|
1270 |
|
/* Reset the start of match point */ |
1271 |
|
|
1272 |
|
case OP_SET_SOM: |
1273 |
|
mstart = eptr; |
1274 |
|
ecode++; |
1275 |
|
break; |
1276 |
|
|
1277 |
/* Assert before internal newline if multiline, or before a terminating |
/* Assert before internal newline if multiline, or before a terminating |
1278 |
newline unless endonly is set, else end of subject unless noteol is set. */ |
newline unless endonly is set, else end of subject unless noteol is set. */ |
3698 |
#ifdef NO_RECURSE |
#ifdef NO_RECURSE |
3699 |
#undef eptr |
#undef eptr |
3700 |
#undef ecode |
#undef ecode |
3701 |
|
#undef mstart |
3702 |
#undef offset_top |
#undef offset_top |
3703 |
#undef ims |
#undef ims |
3704 |
#undef eptrb |
#undef eptrb |
4178 |
|
|
4179 |
/* OK, we can now run the match. */ |
/* OK, we can now run the match. */ |
4180 |
|
|
4181 |
md->start_match = start_match; |
md->start_match_ptr = start_match; /* Insurance */ |
4182 |
md->match_call_count = 0; |
md->match_call_count = 0; |
4183 |
md->eptrn = 0; /* Next free eptrchain slot */ |
md->eptrn = 0; /* Next free eptrchain slot */ |
4184 |
rc = match(start_match, md->start_code, 2, md, ims, NULL, 0, 0); |
rc = match(start_match, md->start_code, start_match, 2, md, |
4185 |
|
ims, NULL, 0, 0); |
4186 |
|
|
4187 |
/* Any return other than MATCH_NOMATCH breaks the loop. */ |
/* Any return other than MATCH_NOMATCH breaks the loop. */ |
4188 |
|
|
4262 |
|
|
4263 |
rc = md->offset_overflow? 0 : md->end_offset_top/2; |
rc = md->offset_overflow? 0 : md->end_offset_top/2; |
4264 |
|
|
4265 |
/* If there is space, set up the whole thing as substring 0. */ |
/* If there is space, set up the whole thing as substring 0. The value of |
4266 |
|
md->start_match_ptr might be modified if \K was encountered on the success |
4267 |
|
matching path. */ |
4268 |
|
|
4269 |
if (offsetcount < 2) rc = 0; else |
if (offsetcount < 2) rc = 0; else |
4270 |
{ |
{ |
4271 |
offsets[0] = start_match - md->start_subject; |
offsets[0] = md->start_match_ptr - md->start_subject; |
4272 |
offsets[1] = md->end_match_ptr - md->start_subject; |
offsets[1] = md->end_match_ptr - md->start_subject; |
4273 |
} |
} |
4274 |
|
|