summaryrefslogtreecommitdiff
path: root/ext/pcre/pcrelib/pcre_exec.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/pcre/pcrelib/pcre_exec.c')
-rw-r--r--ext/pcre/pcrelib/pcre_exec.c302
1 files changed, 195 insertions, 107 deletions
diff --git a/ext/pcre/pcrelib/pcre_exec.c b/ext/pcre/pcrelib/pcre_exec.c
index 890e0f731a..68620829fb 100644
--- a/ext/pcre/pcrelib/pcre_exec.c
+++ b/ext/pcre/pcrelib/pcre_exec.c
@@ -6,7 +6,7 @@
and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
- Copyright (c) 1997-2006 University of Cambridge
+ Copyright (c) 1997-2007 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -48,6 +48,11 @@ possible. There are also some static supporting functions. */
#include "pcre_internal.h"
+/* Undefine some potentially clashing cpp symbols */
+
+#undef min
+#undef max
+
/* The chain of eptrblocks for tail recursions uses memory in stack workspace,
obtained at top level, the size of which is defined by EPTR_WORK_SIZE. */
@@ -183,20 +188,45 @@ calls by keeping local variables that need to be preserved in blocks of memory
obtained from malloc() instead instead of on the stack. Macros are used to
achieve this so that the actual code doesn't look very different to what it
always used to.
+
+The original heap-recursive code used longjmp(). However, it seems that this
+can be very slow on some operating systems. Following a suggestion from Stan
+Switzer, the use of longjmp() has been abolished, at the cost of having to
+provide a unique number for each call to RMATCH. There is no way of generating
+a sequence of numbers at compile time in C. I have given them names, to make
+them stand out more clearly.
+
+Crude tests on x86 Linux show a small speedup of around 5-8%. However, on
+FreeBSD, avoiding longjmp() more than halves the time taken to run the standard
+tests. Furthermore, not using longjmp() means that local dynamic variables
+don't have indeterminate values; this has meant that the frame size can be
+reduced because the result can be "passed back" by straight setting of the
+variable instead of being passed in the frame.
****************************************************************************
***************************************************************************/
+/* Numbers for RMATCH calls */
+
+enum { RM1=1, RM2, RM3, RM4, RM5, RM6, RM7, RM8, RM9, RM10,
+ RM11, RM12, RM13, RM14, RM15, RM16, RM17, RM18, RM19, RM20,
+ RM21, RM22, RM23, RM24, RM25, RM26, RM27, RM28, RM29, RM30,
+ RM31, RM32, RM33, RM34, RM35, RM36, RM37, RM38, RM39, RM40,
+ RM41, RM42, RM43, RM44, RM45, RM46, RM47 };
+
+
/* These versions of the macros use the stack, as normal. There are debugging
-versions and production versions. */
+versions and production versions. Note that the "rw" argument of RMATCH isn't
+actuall used in this definition. */
#ifndef NO_RECURSE
#define REGISTER register
+
#ifdef DEBUG
-#define RMATCH(rx,ra,rb,rc,rd,re,rf,rg) \
+#define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \
{ \
printf("match() called in line %d\n", __LINE__); \
- rx = match(ra,rb,rc,rd,re,rf,rg,rdepth+1); \
+ rrc = match(ra,rb,rc,rd,re,rf,rg,rdepth+1); \
printf("to line %d\n", __LINE__); \
}
#define RRETURN(ra) \
@@ -205,43 +235,37 @@ versions and production versions. */
return ra; \
}
#else
-#define RMATCH(rx,ra,rb,rc,rd,re,rf,rg) \
- rx = match(ra,rb,rc,rd,re,rf,rg,rdepth+1)
+#define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \
+ rrc = match(ra,rb,rc,rd,re,rf,rg,rdepth+1)
#define RRETURN(ra) return ra
#endif
#else
-/* These versions of the macros manage a private stack on the heap. Note
-that the rd argument of RMATCH isn't actually used. It's the md argument of
-match(), which never changes. */
+/* These versions of the macros manage a private stack on the heap. Note that
+the "rd" argument of RMATCH isn't actually used in this definition. It's the md
+argument of match(), which never changes. */
#define REGISTER
-#define RMATCH(rx,ra,rb,rc,rd,re,rf,rg)\
+#define RMATCH(ra,rb,rc,rd,re,rf,rg,rw)\
{\
heapframe *newframe = (pcre_stack_malloc)(sizeof(heapframe));\
- if (setjmp(frame->Xwhere) == 0)\
- {\
- newframe->Xeptr = ra;\
- newframe->Xecode = rb;\
- newframe->Xoffset_top = rc;\
- newframe->Xims = re;\
- newframe->Xeptrb = rf;\
- newframe->Xflags = rg;\
- newframe->Xrdepth = frame->Xrdepth + 1;\
- newframe->Xprevframe = frame;\
- frame = newframe;\
- DPRINTF(("restarting from line %d\n", __LINE__));\
- goto HEAP_RECURSE;\
- }\
- else\
- {\
- DPRINTF(("longjumped back to line %d\n", __LINE__));\
- frame = md->thisframe;\
- rx = frame->Xresult;\
- }\
+ frame->Xwhere = rw; \
+ newframe->Xeptr = ra;\
+ newframe->Xecode = rb;\
+ newframe->Xoffset_top = rc;\
+ newframe->Xims = re;\
+ newframe->Xeptrb = rf;\
+ newframe->Xflags = rg;\
+ newframe->Xrdepth = frame->Xrdepth + 1;\
+ newframe->Xprevframe = frame;\
+ frame = newframe;\
+ DPRINTF(("restarting from line %d\n", __LINE__));\
+ goto HEAP_RECURSE;\
+ L_##rw:\
+ DPRINTF(("jumped back to line %d\n", __LINE__));\
}
#define RRETURN(ra)\
@@ -251,9 +275,8 @@ match(), which never changes. */
(pcre_stack_free)(newframe);\
if (frame != NULL)\
{\
- frame->Xresult = ra;\
- md->thisframe = frame;\
- longjmp(frame->Xwhere, 1);\
+ rrc = ra;\
+ goto HEAP_RETURN;\
}\
return ra;\
}
@@ -299,6 +322,8 @@ typedef struct heapframe {
int Xprop_category;
int Xprop_chartype;
int Xprop_script;
+ int Xoclength;
+ uschar Xocchars[8];
#endif
int Xctype;
@@ -316,10 +341,9 @@ typedef struct heapframe {
eptrblock Xnewptrb;
- /* Place to pass back result, and where to jump back to */
+ /* Where to jump back to */
- int Xresult;
- jmp_buf Xwhere;
+ int Xwhere;
} heapframe;
@@ -441,6 +465,8 @@ HEAP_RECURSE:
#define prop_category frame->Xprop_category
#define prop_chartype frame->Xprop_chartype
#define prop_script frame->Xprop_script
+#define oclength frame->Xoclength
+#define occhars frame->Xocchars
#endif
#define ctype frame->Xctype
@@ -494,6 +520,8 @@ int prop_fail_result;
int prop_category;
int prop_chartype;
int prop_script;
+int oclength;
+uschar occhars[8];
#endif
int ctype;
@@ -534,6 +562,12 @@ defined). However, RMATCH isn't like a function call because it's quite a
complicated macro. It has to be used in one particular way. This shouldn't,
however, impact performance when true recursion is being used. */
+#ifdef SUPPORT_UTF8
+utf8 = md->utf8; /* Local copy of the flag */
+#else
+utf8 = FALSE;
+#endif
+
/* First check that we haven't called match() too many times, or that we
haven't exceeded the recursive call limit. */
@@ -542,12 +576,6 @@ if (rdepth >= md->match_limit_recursion) RRETURN(PCRE_ERROR_RECURSIONLIMIT);
original_ims = ims; /* Save for resetting on ')' */
-#ifdef SUPPORT_UTF8
-utf8 = md->utf8; /* Local copy of the flag */
-#else
-utf8 = FALSE;
-#endif
-
/* At the start of a group with an unlimited repeat that may match an empty
string, the match_cbegroup flag is set. When this is the case, add the current
subject pointer to the chain of such remembered pointers, to be checked when we
@@ -626,8 +654,8 @@ for (;;)
flags = (op == OP_SCBRA)? match_cbegroup : 0;
do
{
- RMATCH(rrc, eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
- ims, eptrb, flags);
+ RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
+ ims, eptrb, flags, RM1);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
md->capture_last = save_capture_last;
ecode += GET(ecode, 1);
@@ -670,8 +698,8 @@ for (;;)
/* For non-final alternatives, continue the loop for a NOMATCH result;
otherwise return. */
- RMATCH(rrc, eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,
- eptrb, flags);
+ RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,
+ eptrb, flags, RM2);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
ecode += GET(ecode, 1);
}
@@ -712,8 +740,8 @@ for (;;)
else
{
- RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL,
- match_condassert);
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL,
+ match_condassert, RM3);
if (rrc == MATCH_MATCH)
{
condition = TRUE;
@@ -791,7 +819,8 @@ for (;;)
case OP_ASSERTBACK:
do
{
- RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0);
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,
+ RM4);
if (rrc == MATCH_MATCH) break;
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
ecode += GET(ecode, 1);
@@ -817,7 +846,8 @@ for (;;)
case OP_ASSERTBACK_NOT:
do
{
- RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0);
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,
+ RM5);
if (rrc == MATCH_MATCH) RRETURN(MATCH_NOMATCH);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
ecode += GET(ecode,1);
@@ -946,8 +976,8 @@ for (;;)
flags = (*callpat >= OP_SBRA)? match_cbegroup : 0;
do
{
- RMATCH(rrc, eptr, callpat + _pcre_OP_lengths[*callpat], offset_top,
- md, ims, eptrb, flags);
+ RMATCH(eptr, callpat + _pcre_OP_lengths[*callpat], offset_top,
+ md, ims, eptrb, flags, RM6);
if (rrc == MATCH_MATCH)
{
DPRINTF(("Recursion matched\n"));
@@ -990,8 +1020,8 @@ for (;;)
do
{
- RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims,
- eptrb, 0);
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims,
+ eptrb, 0, RM7);
if (rrc == MATCH_MATCH) break;
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
ecode += GET(ecode,1);
@@ -1036,7 +1066,8 @@ for (;;)
if (*ecode == OP_KETRMIN)
{
- RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0,
+ RM8);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
ecode = prev;
flags = match_tail_recursed;
@@ -1044,7 +1075,7 @@ for (;;)
}
else /* OP_KETRMAX */
{
- RMATCH(rrc, eptr, prev, offset_top, md, ims, eptrb, match_cbegroup);
+ RMATCH(eptr, prev, offset_top, md, ims, eptrb, match_cbegroup, RM9);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
ecode += 1 + LINK_SIZE;
flags = match_tail_recursed;
@@ -1068,7 +1099,7 @@ for (;;)
case OP_BRAZERO:
{
next = ecode+1;
- RMATCH(rrc, eptr, next, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, next, offset_top, md, ims, eptrb, 0, RM10);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
do next += GET(next,1); while (*next == OP_ALT);
ecode = next + 1 + LINK_SIZE;
@@ -1079,7 +1110,7 @@ for (;;)
{
next = ecode+1;
do next += GET(next, 1); while (*next == OP_ALT);
- RMATCH(rrc, eptr, next + 1+LINK_SIZE, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, next + 1+LINK_SIZE, offset_top, md, ims, eptrb, 0, RM11);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
ecode++;
}
@@ -1184,7 +1215,8 @@ for (;;)
if (*ecode == OP_KETRMIN)
{
- RMATCH(rrc, eptr, ecode + 1+LINK_SIZE, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode + 1+LINK_SIZE, offset_top, md, ims, eptrb, 0,
+ RM12);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
ecode = prev;
flags |= match_tail_recursed;
@@ -1192,7 +1224,7 @@ for (;;)
}
else /* OP_KETRMAX */
{
- RMATCH(rrc, eptr, prev, offset_top, md, ims, eptrb, flags);
+ RMATCH(eptr, prev, offset_top, md, ims, eptrb, flags, RM13);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
ecode += 1 + LINK_SIZE;
flags = match_tail_recursed;
@@ -1591,7 +1623,7 @@ for (;;)
{
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM14);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (fi >= max || !match_ref(offset, eptr, length, md, ims))
RRETURN(MATCH_NOMATCH);
@@ -1612,7 +1644,7 @@ for (;;)
}
while (eptr >= pp)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM15);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
eptr -= length;
}
@@ -1717,7 +1749,7 @@ for (;;)
{
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM16);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
GETCHARINC(c, eptr);
@@ -1737,7 +1769,7 @@ for (;;)
{
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM17);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
c = *eptr++;
@@ -1774,7 +1806,7 @@ for (;;)
}
for (;;)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM18);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (eptr-- == pp) break; /* Stop if tried at original pos */
BACKCHAR(eptr);
@@ -1793,7 +1825,7 @@ for (;;)
}
while (eptr >= pp)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM19);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
eptr--;
}
@@ -1864,7 +1896,7 @@ for (;;)
{
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM20);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
GETCHARINC(c, eptr);
@@ -1888,7 +1920,7 @@ for (;;)
}
for(;;)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM21);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (eptr-- == pp) break; /* Stop if tried at original pos */
BACKCHAR(eptr)
@@ -2045,19 +2077,18 @@ for (;;)
if (length > 1)
{
- int oclength = 0;
- uschar occhars[8];
-
#ifdef SUPPORT_UCP
unsigned int othercase;
if ((ims & PCRE_CASELESS) != 0 &&
(othercase = _pcre_ucp_othercase(fc)) != NOTACHAR)
oclength = _pcre_ord2utf8(othercase, occhars);
+ else oclength = 0;
#endif /* SUPPORT_UCP */
for (i = 1; i <= min; i++)
{
if (memcmp(eptr, charptr, length) == 0) eptr += length;
+#ifdef SUPPORT_UCP
/* Need braces because of following else */
else if (oclength == 0) { RRETURN(MATCH_NOMATCH); }
else
@@ -2065,6 +2096,9 @@ for (;;)
if (memcmp(eptr, occhars, oclength) != 0) RRETURN(MATCH_NOMATCH);
eptr += oclength;
}
+#else /* without SUPPORT_UCP */
+ else { RRETURN(MATCH_NOMATCH); }
+#endif /* SUPPORT_UCP */
}
if (min == max) continue;
@@ -2073,10 +2107,11 @@ for (;;)
{
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM22);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
if (memcmp(eptr, charptr, length) == 0) eptr += length;
+#ifdef SUPPORT_UCP
/* Need braces because of following else */
else if (oclength == 0) { RRETURN(MATCH_NOMATCH); }
else
@@ -2084,6 +2119,9 @@ for (;;)
if (memcmp(eptr, occhars, oclength) != 0) RRETURN(MATCH_NOMATCH);
eptr += oclength;
}
+#else /* without SUPPORT_UCP */
+ else { RRETURN (MATCH_NOMATCH); }
+#endif /* SUPPORT_UCP */
}
/* Control never gets here */
}
@@ -2095,22 +2133,31 @@ for (;;)
{
if (eptr > md->end_subject - length) break;
if (memcmp(eptr, charptr, length) == 0) eptr += length;
+#ifdef SUPPORT_UCP
else if (oclength == 0) break;
else
{
if (memcmp(eptr, occhars, oclength) != 0) break;
eptr += oclength;
}
+#else /* without SUPPORT_UCP */
+ else break;
+#endif /* SUPPORT_UCP */
}
if (possessive) continue;
- while (eptr >= pp)
+ for(;;)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM23);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (eptr == pp) RRETURN(MATCH_NOMATCH);
+#ifdef SUPPORT_UCP
+ eptr--;
+ BACKCHAR(eptr);
+#else /* without SUPPORT_UCP */
eptr -= length;
+#endif /* SUPPORT_UCP */
}
- RRETURN(MATCH_NOMATCH);
}
/* Control never gets here */
}
@@ -2150,7 +2197,7 @@ for (;;)
{
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM24);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (fi >= max || eptr >= md->end_subject ||
fc != md->lcc[*eptr++])
@@ -2169,7 +2216,7 @@ for (;;)
if (possessive) continue;
while (eptr >= pp)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM25);
eptr--;
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
}
@@ -2188,7 +2235,7 @@ for (;;)
{
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM26);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (fi >= max || eptr >= md->end_subject || fc != *eptr++)
RRETURN(MATCH_NOMATCH);
@@ -2206,7 +2253,7 @@ for (;;)
if (possessive) continue;
while (eptr >= pp)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM27);
eptr--;
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
}
@@ -2351,7 +2398,7 @@ for (;;)
register unsigned int d;
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM28);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
GETCHARINC(d, eptr);
if (d < 256) d = md->lcc[d];
@@ -2365,7 +2412,7 @@ for (;;)
{
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM29);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (fi >= max || eptr >= md->end_subject || fc == md->lcc[*eptr++])
RRETURN(MATCH_NOMATCH);
@@ -2397,7 +2444,7 @@ for (;;)
if (possessive) continue;
for(;;)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM30);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (eptr-- == pp) break; /* Stop if tried at original pos */
BACKCHAR(eptr);
@@ -2415,7 +2462,7 @@ for (;;)
if (possessive) continue;
while (eptr >= pp)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM31);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
eptr--;
}
@@ -2460,7 +2507,7 @@ for (;;)
register unsigned int d;
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM32);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
GETCHARINC(d, eptr);
if (fi >= max || eptr >= md->end_subject || fc == d)
@@ -2473,7 +2520,7 @@ for (;;)
{
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM33);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (fi >= max || eptr >= md->end_subject || fc == *eptr++)
RRETURN(MATCH_NOMATCH);
@@ -2504,7 +2551,7 @@ for (;;)
if (possessive) continue;
for(;;)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM34);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (eptr-- == pp) break; /* Stop if tried at original pos */
BACKCHAR(eptr);
@@ -2522,7 +2569,7 @@ for (;;)
if (possessive) continue;
while (eptr >= pp)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM35);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
eptr--;
}
@@ -2919,7 +2966,7 @@ for (;;)
case PT_ANY:
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM36);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
GETCHARINC(c, eptr);
@@ -2930,7 +2977,7 @@ for (;;)
case PT_LAMP:
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM37);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
GETCHARINC(c, eptr);
@@ -2945,7 +2992,7 @@ for (;;)
case PT_GC:
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM38);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
GETCHARINC(c, eptr);
@@ -2958,7 +3005,7 @@ for (;;)
case PT_PC:
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM39);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
GETCHARINC(c, eptr);
@@ -2971,7 +3018,7 @@ for (;;)
case PT_SC:
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM40);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
GETCHARINC(c, eptr);
@@ -2993,7 +3040,7 @@ for (;;)
{
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM41);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
GETCHARINCTEST(c, eptr);
@@ -3022,7 +3069,7 @@ for (;;)
{
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM42);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (fi >= max || eptr >= md->end_subject ||
(ctype == OP_ANY && (ims & PCRE_DOTALL) == 0 &&
@@ -3096,7 +3143,7 @@ for (;;)
{
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM43);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (fi >= max || eptr >= md->end_subject ||
((ims & PCRE_DOTALL) == 0 && IS_NEWLINE(eptr)))
@@ -3242,7 +3289,7 @@ for (;;)
if (possessive) continue;
for(;;)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM44);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (eptr-- == pp) break; /* Stop if tried at original pos */
BACKCHAR(eptr);
@@ -3278,7 +3325,7 @@ for (;;)
if (possessive) continue;
for(;;)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM45);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (eptr-- == pp) break; /* Stop if tried at original pos */
for (;;) /* Move back over one extended */
@@ -3462,7 +3509,7 @@ for (;;)
if (possessive) continue;
for(;;)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM46);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (eptr-- == pp) break; /* Stop if tried at original pos */
BACKCHAR(eptr);
@@ -3576,7 +3623,7 @@ for (;;)
if (possessive) continue;
while (eptr >= pp)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM47);
eptr--;
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
}
@@ -3602,6 +3649,29 @@ for (;;)
} /* End of main loop */
/* Control never reaches here */
+
+
+/* When compiling to use the heap rather than the stack for recursive calls to
+match(), the RRETURN() macro jumps here. The number that is saved in
+frame->Xwhere indicates which label we actually want to return to. */
+
+#ifdef NO_RECURSE
+#define LBL(val) case val: goto L_RM##val;
+HEAP_RETURN:
+switch (frame->Xwhere)
+ {
+ LBL( 1) LBL( 2) LBL( 3) LBL( 4) LBL( 5) LBL( 6) LBL( 7) LBL( 8)
+ LBL( 9) LBL(10) LBL(11) LBL(12) LBL(13) LBL(14) LBL(15) LBL(16)
+ LBL(17) LBL(18) LBL(19) LBL(20) LBL(21) LBL(22) LBL(23) LBL(24)
+ LBL(25) LBL(26) LBL(27) LBL(28) LBL(29) LBL(30) LBL(31) LBL(32)
+ LBL(33) LBL(34) LBL(35) LBL(36) LBL(37) LBL(38) LBL(39) LBL(40)
+ LBL(41) LBL(42) LBL(43) LBL(44) LBL(45) LBL(46) LBL(47)
+ default:
+ DPRINTF(("jump error in pcre match: label %d non-existent\n", frame->Xwhere));
+ return PCRE_ERROR_INTERNAL;
+ }
+#undef LBL
+#endif /* NO_RECURSE */
}
@@ -3686,7 +3756,7 @@ Returns: > 0 => success; value is the number of elements filled in
< -1 => some kind of unexpected problem
*/
-PCRE_DATA_SCOPE int
+PCRE_EXP_DEFN int
pcre_exec(const pcre *argument_re, const pcre_extra *extra_data,
PCRE_SPTR subject, int length, int start_offset, int options, int *offsets,
int offsetcount)
@@ -3802,10 +3872,10 @@ md->eptrchain = eptrchain; /* Make workspace generally available */
md->lcc = tables + lcc_offset;
md->ctypes = tables + ctypes_offset;
-/* Handle different types of newline. The two bits give four cases. If nothing
-is set at run time, whatever was used at compile time applies. */
+/* Handle different types of newline. The three bits give eight cases. If
+nothing is set at run time, whatever was used at compile time applies. */
-switch ((((options & PCRE_NEWLINE_BITS) == 0)? re->options : options) &
+switch ((((options & PCRE_NEWLINE_BITS) == 0)? re->options : (pcre_uint32)options) &
PCRE_NEWLINE_BITS)
{
case 0: newline = NEWLINE; break; /* Compile-time default */
@@ -3814,10 +3884,15 @@ switch ((((options & PCRE_NEWLINE_BITS) == 0)? re->options : options) &
case PCRE_NEWLINE_CR+
PCRE_NEWLINE_LF: newline = ('\r' << 8) | '\n'; break;
case PCRE_NEWLINE_ANY: newline = -1; break;
+ case PCRE_NEWLINE_ANYCRLF: newline = -2; break;
default: return PCRE_ERROR_BADNEWLINE;
}
-if (newline < 0)
+if (newline == -2)
+ {
+ md->nltype = NLTYPE_ANYCRLF;
+ }
+else if (newline < 0)
{
md->nltype = NLTYPE_ANY;
}
@@ -3992,6 +4067,16 @@ for(;;)
{
while (start_match <= end_subject && !WAS_NEWLINE(start_match))
start_match++;
+
+ /* If we have just passed a CR and the newline option is ANY or ANYCRLF,
+ and we are now at a LF, advance the match position by one more character.
+ */
+
+ if (start_match[-1] == '\r' &&
+ (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) &&
+ start_match < end_subject &&
+ *start_match == '\n')
+ start_match++;
}
}
@@ -4107,11 +4192,14 @@ for(;;)
if (anchored || start_match > end_subject) break;
- /* If we have just passed a CR and the newline option is CRLF or ANY, and we
- are now at a LF, advance the match position by one more character. */
+ /* If we have just passed a CR and the newline option is CRLF or ANY or
+ ANYCRLF, and we are now at a LF, advance the match position by one more
+ character. */
if (start_match[-1] == '\r' &&
- (md->nltype == NLTYPE_ANY || md->nllen == 2) &&
+ (md->nltype == NLTYPE_ANY ||
+ md->nltype == NLTYPE_ANYCRLF ||
+ md->nllen == 2) &&
start_match < end_subject &&
*start_match == '\n')
start_match++;