/[pcre]/code/trunk/pcre_exec.c
ViewVC logotype

Diff of /code/trunk/pcre_exec.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 123 by ph10, Mon Mar 12 15:19:06 2007 UTC revision 172 by ph10, Tue Jun 5 10:40:13 2007 UTC
# Line 48  possible. There are also some static sup Line 48  possible. There are also some static sup
48    
49  #include "pcre_internal.h"  #include "pcre_internal.h"
50    
51    /* Undefine some potentially clashing cpp symbols */
52    
53    #undef min
54    #undef max
55    
56  /* The chain of eptrblocks for tail recursions uses memory in stack workspace,  /* The chain of eptrblocks for tail recursions uses memory in stack workspace,
57  obtained at top level, the size of which is defined by EPTR_WORK_SIZE. */  obtained at top level, the size of which is defined by EPTR_WORK_SIZE. */
58    
# Line 183  calls by keeping local variables that ne Line 188  calls by keeping local variables that ne
188  obtained from malloc() instead instead of on the stack. Macros are used to  obtained from malloc() instead instead of on the stack. Macros are used to
189  achieve this so that the actual code doesn't look very different to what it  achieve this so that the actual code doesn't look very different to what it
190  always used to.  always used to.
191    
192    The original heap-recursive code used longjmp(). However, it seems that this
193    can be very slow on some operating systems. Following a suggestion from Stan
194    Switzer, the use of longjmp() has been abolished, at the cost of having to
195    provide a unique number for each call to RMATCH. There is no way of generating
196    a sequence of numbers at compile time in C. I have given them names, to make
197    them stand out more clearly.
198    
199    Crude tests on x86 Linux show a small speedup of around 5-8%. However, on
200    FreeBSD, avoiding longjmp() more than halves the time taken to run the standard
201    tests. Furthermore, not using longjmp() means that local dynamic variables
202    don't have indeterminate values; this has meant that the frame size can be
203    reduced because the result can be "passed back" by straight setting of the
204    variable instead of being passed in the frame.
205  ****************************************************************************  ****************************************************************************
206  ***************************************************************************/  ***************************************************************************/
207    
208    
209    /* Numbers for RMATCH calls */
210    
211    enum { RM1=1, RM2,  RM3,  RM4,  RM5,  RM6,  RM7,  RM8,  RM9,  RM10,
212           RM11,  RM12, RM13, RM14, RM15, RM16, RM17, RM18, RM19, RM20,
213           RM21,  RM22, RM23, RM24, RM25, RM26, RM27, RM28, RM29, RM30,
214           RM31,  RM32, RM33, RM34, RM35, RM36, RM37, RM38, RM39, RM40,
215           RM41,  RM42, RM43, RM44, RM45, RM46, RM47 };
216    
217    
218  /* These versions of the macros use the stack, as normal. There are debugging  /* These versions of the macros use the stack, as normal. There are debugging
219  versions and production versions. */  versions and production versions. Note that the "rw" argument of RMATCH isn't
220    actuall used in this definition. */
221    
222  #ifndef NO_RECURSE  #ifndef NO_RECURSE
223  #define REGISTER register  #define REGISTER register
224    
225  #ifdef DEBUG  #ifdef DEBUG
226  #define RMATCH(rx,ra,rb,rc,rd,re,rf,rg) \  #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    rx = 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) \
# Line 205  versions and production versions. */ Line 235  versions and production versions. */
235    return ra; \    return ra; \
236    }    }
237  #else  #else
238  #define RMATCH(rx,ra,rb,rc,rd,re,rf,rg) \  #define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \
239    rx = 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    
243  #else  #else
244    
245    
246  /* These versions of the macros manage a private stack on the heap. Note  /* These versions of the macros manage a private stack on the heap. Note that
247  that the rd argument of RMATCH isn't actually used. It's the md argument of  the "rd" argument of RMATCH isn't actually used in this definition. It's the md
248  match(), which never changes. */  argument of match(), which never changes. */
249    
250  #define REGISTER  #define REGISTER
251    
252  #define RMATCH(rx,ra,rb,rc,rd,re,rf,rg)\  #define RMATCH(ra,rb,rc,rd,re,rf,rg,rw)\
253    {\    {\
254    heapframe *newframe = (pcre_stack_malloc)(sizeof(heapframe));\    heapframe *newframe = (pcre_stack_malloc)(sizeof(heapframe));\
255    if (setjmp(frame->Xwhere) == 0)\    frame->Xwhere = rw; \
256      {\    newframe->Xeptr = ra;\
257      newframe->Xeptr = ra;\    newframe->Xecode = rb;\
258      newframe->Xecode = rb;\    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;\
262      newframe->Xflags = rg;\    newframe->Xflags = rg;\
263      newframe->Xrdepth = frame->Xrdepth + 1;\    newframe->Xrdepth = frame->Xrdepth + 1;\
264      newframe->Xprevframe = frame;\    newframe->Xprevframe = frame;\
265      frame = newframe;\    frame = newframe;\
266      DPRINTF(("restarting from line %d\n", __LINE__));\    DPRINTF(("restarting from line %d\n", __LINE__));\
267      goto HEAP_RECURSE;\    goto HEAP_RECURSE;\
268      }\    L_##rw:\
269    else\    DPRINTF(("jumped back to line %d\n", __LINE__));\
     {\  
     DPRINTF(("longjumped back to line %d\n", __LINE__));\  
     frame = md->thisframe;\  
     rx = frame->Xresult;\  
     }\  
270    }    }
271    
272  #define RRETURN(ra)\  #define RRETURN(ra)\
# Line 251  match(), which never changes. */ Line 276  match(), which never changes. */
276    (pcre_stack_free)(newframe);\    (pcre_stack_free)(newframe);\
277    if (frame != NULL)\    if (frame != NULL)\
278      {\      {\
279      frame->Xresult = ra;\      rrc = ra;\
280      md->thisframe = frame;\      goto HEAP_RETURN;\
     longjmp(frame->Xwhere, 1);\  
281      }\      }\
282    return ra;\    return ra;\
283    }    }
# Line 268  typedef struct heapframe { Line 292  typedef struct heapframe {
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;
# Line 318  typedef struct heapframe { Line 343  typedef struct heapframe {
343    
344    eptrblock Xnewptrb;    eptrblock Xnewptrb;
345    
346    /* Place to pass back result, and where to jump back to */    /* Where to jump back to */
347    
348    int  Xresult;    int Xwhere;
   jmp_buf Xwhere;  
349    
350  } heapframe;  } heapframe;
351    
# Line 349  made performance worse. Line 373  made performance worse.
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
# Line 368  Returns:       MATCH_MATCH if matched Line 394  Returns:       MATCH_MATCH if matched
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  {  {
# Line 396  frame->Xprevframe = NULL;            /* Line 422  frame->Xprevframe = NULL;            /*
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;
# Line 410  HEAP_RECURSE: Line 437  HEAP_RECURSE:
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
# Line 540  defined). However, RMATCH isn't like a f Line 568  defined). However, RMATCH isn't like a f
568  complicated macro. It has to be used in one particular way. This shouldn't,  complicated macro. It has to be used in one particular way. This shouldn't,
569  however, impact performance when true recursion is being used. */  however, impact performance when true recursion is being used. */
570    
571    #ifdef SUPPORT_UTF8
572    utf8 = md->utf8;       /* Local copy of the flag */
573    #else
574    utf8 = FALSE;
575    #endif
576    
577  /* First check that we haven't called match() too many times, or that we  /* First check that we haven't called match() too many times, or that we
578  haven't exceeded the recursive call limit. */  haven't exceeded the recursive call limit. */
579    
# Line 548  if (rdepth >= md->match_limit_recursion) Line 582  if (rdepth >= md->match_limit_recursion)
582    
583  original_ims = ims;    /* Save for resetting on ')' */  original_ims = ims;    /* Save for resetting on ')' */
584    
 #ifdef SUPPORT_UTF8  
 utf8 = md->utf8;       /* Local copy of the flag */  
 #else  
 utf8 = FALSE;  
 #endif  
   
585  /* At the start of a group with an unlimited repeat that may match an empty  /* At the start of a group with an unlimited repeat that may match an empty
586  string, the match_cbegroup flag is set. When this is the case, add the current  string, the match_cbegroup flag is set. When this is the case, add the current
587  subject pointer to the chain of such remembered pointers, to be checked when we  subject pointer to the chain of such remembered pointers, to be checked when we
# Line 588  for (;;) Line 616  for (;;)
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)
# Line 632  for (;;) Line 660  for (;;)
660        flags = (op == OP_SCBRA)? match_cbegroup : 0;        flags = (op == OP_SCBRA)? match_cbegroup : 0;
661        do        do
662          {          {
663          RMATCH(rrc, eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,          RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
664            ims, eptrb, flags);            ims, eptrb, flags, RM1);
665          if (rrc != MATCH_NOMATCH) RRETURN(rrc);          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
666          md->capture_last = save_capture_last;          md->capture_last = save_capture_last;
667          ecode += GET(ecode, 1);          ecode += GET(ecode, 1);
# Line 676  for (;;) Line 704  for (;;)
704        /* For non-final alternatives, continue the loop for a NOMATCH result;        /* For non-final alternatives, continue the loop for a NOMATCH result;
705        otherwise return. */        otherwise return. */
706    
707        RMATCH(rrc, eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,
708          eptrb, flags);          eptrb, flags, RM2);
709        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
710        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
711        }        }
# Line 718  for (;;) Line 746  for (;;)
746    
747      else      else
748        {        {
749        RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL,        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL,
750            match_condassert);            match_condassert, RM3);
751        if (rrc == MATCH_MATCH)        if (rrc == MATCH_MATCH)
752          {          {
753          condition = TRUE;          condition = TRUE;
# Line 765  for (;;) Line 793  for (;;)
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;
# Line 774  for (;;) Line 802  for (;;)
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 */
# Line 797  for (;;) Line 826  for (;;)
826      case OP_ASSERTBACK:      case OP_ASSERTBACK:
827      do      do
828        {        {
829        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,
830            RM4);
831        if (rrc == MATCH_MATCH) break;        if (rrc == MATCH_MATCH) break;
832        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
833        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
# Line 823  for (;;) Line 853  for (;;)
853      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
854      do      do
855        {        {
856        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,
857            RM5);
858        if (rrc == MATCH_MATCH) RRETURN(MATCH_NOMATCH);        if (rrc == MATCH_MATCH) RRETURN(MATCH_NOMATCH);
859        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
860        ecode += GET(ecode,1);        ecode += GET(ecode,1);
# Line 880  for (;;) Line 911  for (;;)
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);
# Line 942  for (;;) Line 973  for (;;)
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. */
# Line 952  for (;;) Line 983  for (;;)
983        flags = (*callpat >= OP_SBRA)? match_cbegroup : 0;        flags = (*callpat >= OP_SBRA)? match_cbegroup : 0;
984        do        do
985          {          {
986          RMATCH(rrc, eptr, callpat + _pcre_OP_lengths[*callpat], offset_top,          RMATCH(eptr, callpat + _pcre_OP_lengths[*callpat], offset_top,
987            md, ims, eptrb, flags);            md, ims, eptrb, flags, RM6);
988          if (rrc == MATCH_MATCH)          if (rrc == MATCH_MATCH)
989            {            {
990            DPRINTF(("Recursion matched\n"));            DPRINTF(("Recursion matched\n"));
# Line 996  for (;;) Line 1027  for (;;)
1027    
1028      do      do
1029        {        {
1030        RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims,        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims,
1031          eptrb, 0);          eptrb, 0, RM7);
1032        if (rrc == MATCH_MATCH) break;        if (rrc == MATCH_MATCH) break;
1033        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1034        ecode += GET(ecode,1);        ecode += GET(ecode,1);
# Line 1042  for (;;) Line 1073  for (;;)
1073    
1074      if (*ecode == OP_KETRMIN)      if (*ecode == OP_KETRMIN)
1075        {        {
1076        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,
1077            RM8);
1078        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1079        ecode = prev;        ecode = prev;
1080        flags = match_tail_recursed;        flags = match_tail_recursed;
# Line 1050  for (;;) Line 1082  for (;;)
1082        }        }
1083      else  /* OP_KETRMAX */      else  /* OP_KETRMAX */
1084        {        {
1085        RMATCH(rrc, eptr, prev, offset_top, md, ims, eptrb, match_cbegroup);        RMATCH(eptr, prev, offset_top, md, ims, eptrb, match_cbegroup, RM9);
1086        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1087        ecode += 1 + LINK_SIZE;        ecode += 1 + LINK_SIZE;
1088        flags = match_tail_recursed;        flags = match_tail_recursed;
# Line 1074  for (;;) Line 1106  for (;;)
1106      case OP_BRAZERO:      case OP_BRAZERO:
1107        {        {
1108        next = ecode+1;        next = ecode+1;
1109        RMATCH(rrc, eptr, next, offset_top, md, ims, eptrb, 0);        RMATCH(eptr, next, offset_top, md, ims, eptrb, 0, RM10);
1110        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1111        do next += GET(next,1); while (*next == OP_ALT);        do next += GET(next,1); while (*next == OP_ALT);
1112        ecode = next + 1 + LINK_SIZE;        ecode = next + 1 + LINK_SIZE;
# Line 1085  for (;;) Line 1117  for (;;)
1117        {        {
1118        next = ecode+1;        next = ecode+1;
1119        do next += GET(next, 1); while (*next == OP_ALT);        do next += GET(next, 1); while (*next == OP_ALT);
1120        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);
1121        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1122        ecode++;        ecode++;
1123        }        }
# Line 1155  for (;;) Line 1187  for (;;)
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;
# Line 1190  for (;;) Line 1222  for (;;)
1222    
1223      if (*ecode == OP_KETRMIN)      if (*ecode == OP_KETRMIN)
1224        {        {
1225        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,
1226            RM12);
1227        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1228        ecode = prev;        ecode = prev;
1229        flags |= match_tail_recursed;        flags |= match_tail_recursed;
# Line 1198  for (;;) Line 1231  for (;;)
1231        }        }
1232      else  /* OP_KETRMAX */      else  /* OP_KETRMAX */
1233        {        {
1234        RMATCH(rrc, eptr, prev, offset_top, md, ims, eptrb, flags);        RMATCH(eptr, prev, offset_top, md, ims, eptrb, flags, RM13);
1235        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1236        ecode += 1 + LINK_SIZE;        ecode += 1 + LINK_SIZE;
1237        flags = match_tail_recursed;        flags = match_tail_recursed;
# Line 1234  for (;;) Line 1267  for (;;)
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. */
1279    
# Line 1597  for (;;) Line 1637  for (;;)
1637          {          {
1638          for (fi = min;; fi++)          for (fi = min;; fi++)
1639            {            {
1640            RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM14);
1641            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1642            if (fi >= max || !match_ref(offset, eptr, length, md, ims))            if (fi >= max || !match_ref(offset, eptr, length, md, ims))
1643              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
# Line 1618  for (;;) Line 1658  for (;;)
1658            }            }
1659          while (eptr >= pp)          while (eptr >= pp)
1660            {            {
1661            RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM15);
1662            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1663            eptr -= length;            eptr -= length;
1664            }            }
# Line 1723  for (;;) Line 1763  for (;;)
1763            {            {
1764            for (fi = min;; fi++)            for (fi = min;; fi++)
1765              {              {
1766              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM16);
1767              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1768              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1769              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
# Line 1743  for (;;) Line 1783  for (;;)
1783            {            {
1784            for (fi = min;; fi++)            for (fi = min;; fi++)
1785              {              {
1786              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM17);
1787              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1788              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1789              c = *eptr++;              c = *eptr++;
# Line 1780  for (;;) Line 1820  for (;;)
1820              }              }
1821            for (;;)            for (;;)
1822              {              {
1823              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM18);
1824              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1825              if (eptr-- == pp) break;        /* Stop if tried at original pos */              if (eptr-- == pp) break;        /* Stop if tried at original pos */
1826              BACKCHAR(eptr);              BACKCHAR(eptr);
# Line 1799  for (;;) Line 1839  for (;;)
1839              }              }
1840            while (eptr >= pp)            while (eptr >= pp)
1841              {              {
1842              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM19);
1843              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1844              eptr--;              eptr--;
1845              }              }
# Line 1870  for (;;) Line 1910  for (;;)
1910          {          {
1911          for (fi = min;; fi++)          for (fi = min;; fi++)
1912            {            {
1913            RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM20);
1914            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1915            if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1916            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
# Line 1894  for (;;) Line 1934  for (;;)
1934            }            }
1935          for(;;)          for(;;)
1936            {            {
1937            RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM21);
1938            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1939            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
1940            BACKCHAR(eptr)            BACKCHAR(eptr)
# Line 2081  for (;;) Line 2121  for (;;)
2121            {            {
2122            for (fi = min;; fi++)            for (fi = min;; fi++)
2123              {              {
2124              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM22);
2125              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2126              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
2127              if (memcmp(eptr, charptr, length) == 0) eptr += length;              if (memcmp(eptr, charptr, length) == 0) eptr += length;
# Line 2122  for (;;) Line 2162  for (;;)
2162            if (possessive) continue;            if (possessive) continue;
2163            for(;;)            for(;;)
2164             {             {
2165             RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);             RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM23);
2166             if (rrc != MATCH_NOMATCH) RRETURN(rrc);             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2167             if (eptr == pp) RRETURN(MATCH_NOMATCH);             if (eptr == pp) RRETURN(MATCH_NOMATCH);
2168  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 2171  for (;;) Line 2211  for (;;)
2211          {          {
2212          for (fi = min;; fi++)          for (fi = min;; fi++)
2213            {            {
2214            RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM24);
2215            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2216            if (fi >= max || eptr >= md->end_subject ||            if (fi >= max || eptr >= md->end_subject ||
2217                fc != md->lcc[*eptr++])                fc != md->lcc[*eptr++])
# Line 2190  for (;;) Line 2230  for (;;)
2230          if (possessive) continue;          if (possessive) continue;
2231          while (eptr >= pp)          while (eptr >= pp)
2232            {            {
2233            RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM25);
2234            eptr--;            eptr--;
2235            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2236            }            }
# Line 2209  for (;;) Line 2249  for (;;)
2249          {          {
2250          for (fi = min;; fi++)          for (fi = min;; fi++)
2251            {            {
2252            RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM26);
2253            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2254            if (fi >= max || eptr >= md->end_subject || fc != *eptr++)            if (fi >= max || eptr >= md->end_subject || fc != *eptr++)
2255              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
# Line 2227  for (;;) Line 2267  for (;;)
2267          if (possessive) continue;          if (possessive) continue;
2268          while (eptr >= pp)          while (eptr >= pp)
2269            {            {
2270            RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM27);
2271            eptr--;            eptr--;
2272            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2273            }            }
# Line 2372  for (;;) Line 2412  for (;;)
2412            register unsigned int d;            register unsigned int d;
2413            for (fi = min;; fi++)            for (fi = min;; fi++)
2414              {              {
2415              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM28);
2416              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2417              GETCHARINC(d, eptr);              GETCHARINC(d, eptr);
2418              if (d < 256) d = md->lcc[d];              if (d < 256) d = md->lcc[d];
# Line 2386  for (;;) Line 2426  for (;;)
2426            {            {
2427            for (fi = min;; fi++)            for (fi = min;; fi++)
2428              {              {
2429              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM29);
2430              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2431              if (fi >= max || eptr >= md->end_subject || fc == md->lcc[*eptr++])              if (fi >= max || eptr >= md->end_subject || fc == md->lcc[*eptr++])
2432                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
# Line 2418  for (;;) Line 2458  for (;;)
2458          if (possessive) continue;          if (possessive) continue;
2459          for(;;)          for(;;)
2460              {              {
2461              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM30);
2462              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2463              if (eptr-- == pp) break;        /* Stop if tried at original pos */              if (eptr-- == pp) break;        /* Stop if tried at original pos */
2464              BACKCHAR(eptr);              BACKCHAR(eptr);
# Line 2436  for (;;) Line 2476  for (;;)
2476            if (possessive) continue;            if (possessive) continue;
2477            while (eptr >= pp)            while (eptr >= pp)
2478              {              {
2479              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM31);
2480              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2481              eptr--;              eptr--;
2482              }              }
# Line 2481  for (;;) Line 2521  for (;;)
2521            register unsigned int d;            register unsigned int d;
2522            for (fi = min;; fi++)            for (fi = min;; fi++)
2523              {              {
2524              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM32);
2525              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2526              GETCHARINC(d, eptr);              GETCHARINC(d, eptr);
2527              if (fi >= max || eptr >= md->end_subject || fc == d)              if (fi >= max || eptr >= md->end_subject || fc == d)
# Line 2494  for (;;) Line 2534  for (;;)
2534            {            {
2535            for (fi = min;; fi++)            for (fi = min;; fi++)
2536              {              {
2537              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM33);
2538              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2539              if (fi >= max || eptr >= md->end_subject || fc == *eptr++)              if (fi >= max || eptr >= md->end_subject || fc == *eptr++)
2540                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
# Line 2525  for (;;) Line 2565  for (;;)
2565            if (possessive) continue;            if (possessive) continue;
2566            for(;;)            for(;;)
2567              {              {
2568              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM34);
2569              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2570              if (eptr-- == pp) break;        /* Stop if tried at original pos */              if (eptr-- == pp) break;        /* Stop if tried at original pos */
2571              BACKCHAR(eptr);              BACKCHAR(eptr);
# Line 2543  for (;;) Line 2583  for (;;)
2583            if (possessive) continue;            if (possessive) continue;
2584            while (eptr >= pp)            while (eptr >= pp)
2585              {              {
2586              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM35);
2587              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2588              eptr--;              eptr--;
2589              }              }
# Line 2940  for (;;) Line 2980  for (;;)
2980            case PT_ANY:            case PT_ANY:
2981            for (fi = min;; fi++)            for (fi = min;; fi++)
2982              {              {
2983              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM36);
2984              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2985              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
2986              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
# Line 2951  for (;;) Line 2991  for (;;)
2991            case PT_LAMP:            case PT_LAMP:
2992            for (fi = min;; fi++)            for (fi = min;; fi++)
2993              {              {
2994              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM37);
2995              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2996              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
2997              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
# Line 2966  for (;;) Line 3006  for (;;)
3006            case PT_GC:            case PT_GC:
3007            for (fi = min;; fi++)            for (fi = min;; fi++)
3008              {              {
3009              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM38);
3010              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3011              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
3012              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
# Line 2979  for (;;) Line 3019  for (;;)
3019            case PT_PC:            case PT_PC:
3020            for (fi = min;; fi++)            for (fi = min;; fi++)
3021              {              {
3022              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM39);
3023              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3024              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
3025              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
# Line 2992  for (;;) Line 3032  for (;;)
3032            case PT_SC:            case PT_SC:
3033            for (fi = min;; fi++)            for (fi = min;; fi++)
3034              {              {
3035              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM40);
3036              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3037              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
3038              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
# Line 3014  for (;;) Line 3054  for (;;)
3054          {          {
3055          for (fi = min;; fi++)          for (fi = min;; fi++)
3056            {            {
3057            RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM41);
3058            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3059            if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
3060            GETCHARINCTEST(c, eptr);            GETCHARINCTEST(c, eptr);
# Line 3043  for (;;) Line 3083  for (;;)
3083          {          {
3084          for (fi = min;; fi++)          for (fi = min;; fi++)
3085            {            {
3086            RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM42);
3087            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3088            if (fi >= max || eptr >= md->end_subject ||            if (fi >= max || eptr >= md->end_subject ||
3089                 (ctype == OP_ANY && (ims & PCRE_DOTALL) == 0 &&                 (ctype == OP_ANY && (ims & PCRE_DOTALL) == 0 &&
# Line 3117  for (;;) Line 3157  for (;;)
3157          {          {
3158          for (fi = min;; fi++)          for (fi = min;; fi++)
3159            {            {
3160            RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM43);
3161            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3162            if (fi >= max || eptr >= md->end_subject ||            if (fi >= max || eptr >= md->end_subject ||
3163                 ((ims & PCRE_DOTALL) == 0 && IS_NEWLINE(eptr)))                 ((ims & PCRE_DOTALL) == 0 && IS_NEWLINE(eptr)))
# Line 3263  for (;;) Line 3303  for (;;)
3303          if (possessive) continue;          if (possessive) continue;
3304          for(;;)          for(;;)
3305            {            {
3306            RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM44);
3307            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3308            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
3309            BACKCHAR(eptr);            BACKCHAR(eptr);
# Line 3299  for (;;) Line 3339  for (;;)
3339          if (possessive) continue;          if (possessive) continue;
3340          for(;;)          for(;;)
3341            {            {
3342            RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM45);
3343            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3344            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
3345            for (;;)                        /* Move back over one extended */            for (;;)                        /* Move back over one extended */
# Line 3483  for (;;) Line 3523  for (;;)
3523          if (possessive) continue;          if (possessive) continue;
3524          for(;;)          for(;;)
3525            {            {
3526            RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM46);
3527            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3528            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
3529            BACKCHAR(eptr);            BACKCHAR(eptr);
# Line 3597  for (;;) Line 3637  for (;;)
3637          if (possessive) continue;          if (possessive) continue;
3638          while (eptr >= pp)          while (eptr >= pp)
3639            {            {
3640            RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM47);
3641            eptr--;            eptr--;
3642            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3643            }            }
# Line 3623  for (;;) Line 3663  for (;;)
3663    
3664    }             /* End of main loop */    }             /* End of main loop */
3665  /* Control never reaches here */  /* Control never reaches here */
3666    
3667    
3668    /* When compiling to use the heap rather than the stack for recursive calls to
3669    match(), the RRETURN() macro jumps here. The number that is saved in
3670    frame->Xwhere indicates which label we actually want to return to. */
3671    
3672    #ifdef NO_RECURSE
3673    #define LBL(val) case val: goto L_RM##val;
3674    HEAP_RETURN:
3675    switch (frame->Xwhere)
3676      {
3677      LBL( 1) LBL( 2) LBL( 3) LBL( 4) LBL( 5) LBL( 6) LBL( 7) LBL( 8)
3678      LBL( 9) LBL(10) LBL(11) LBL(12) LBL(13) LBL(14) LBL(15) LBL(16)
3679      LBL(17) LBL(18) LBL(19) LBL(20) LBL(21) LBL(22) LBL(23) LBL(24)
3680      LBL(25) LBL(26) LBL(27) LBL(28) LBL(29) LBL(30) LBL(31) LBL(32)
3681      LBL(33) LBL(34) LBL(35) LBL(36) LBL(37) LBL(38) LBL(39) LBL(40)
3682      LBL(41) LBL(42) LBL(43) LBL(44) LBL(45) LBL(46) LBL(47)
3683      default:
3684      DPRINTF(("jump error in pcre match: label %d non-existent\n", frame->Xwhere));
3685      return PCRE_ERROR_INTERNAL;
3686      }
3687    #undef LBL
3688    #endif  /* NO_RECURSE */
3689  }  }
3690    
3691    
# Line 3635  Undefine all the macros that were define Line 3698  Undefine all the macros that were define
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
# Line 3707  Returns:          > 0 => success; value Line 3771  Returns:          > 0 => success; value
3771                   < -1 => some kind of unexpected problem                   < -1 => some kind of unexpected problem
3772  */  */
3773    
3774  PCRE_DATA_SCOPE int  PCRE_EXP_DEFN int
3775  pcre_exec(const pcre *argument_re, const pcre_extra *extra_data,  pcre_exec(const pcre *argument_re, const pcre_extra *extra_data,
3776    PCRE_SPTR subject, int length, int start_offset, int options, int *offsets,    PCRE_SPTR subject, int length, int start_offset, int options, int *offsets,
3777    int offsetcount)    int offsetcount)
# Line 3826  md->ctypes = tables + ctypes_offset; Line 3890  md->ctypes = tables + ctypes_offset;
3890  /* Handle different types of newline. The three bits give eight cases. If  /* Handle different types of newline. The three bits give eight cases. If
3891  nothing is set at run time, whatever was used at compile time applies. */  nothing is set at run time, whatever was used at compile time applies. */
3892    
3893  switch ((((options & PCRE_NEWLINE_BITS) == 0)? re->options : options) &  switch ((((options & PCRE_NEWLINE_BITS) == 0)? re->options : (pcre_uint32)options) &
3894         PCRE_NEWLINE_BITS)         PCRE_NEWLINE_BITS)
3895    {    {
3896    case 0: newline = NEWLINE; break;   /* Compile-time default */    case 0: newline = NEWLINE; break;   /* Compile-time default */
# Line 3835  switch ((((options & PCRE_NEWLINE_BITS) Line 3899  switch ((((options & PCRE_NEWLINE_BITS)
3899    case PCRE_NEWLINE_CR+    case PCRE_NEWLINE_CR+
3900         PCRE_NEWLINE_LF: newline = ('\r' << 8) | '\n'; break;         PCRE_NEWLINE_LF: newline = ('\r' << 8) | '\n'; break;
3901    case PCRE_NEWLINE_ANY: newline = -1; break;    case PCRE_NEWLINE_ANY: newline = -1; break;
3902      case PCRE_NEWLINE_ANYCRLF: newline = -2; break;
3903    default: return PCRE_ERROR_BADNEWLINE;    default: return PCRE_ERROR_BADNEWLINE;
3904    }    }
3905    
3906  if (newline < 0)  if (newline == -2)
3907      {
3908      md->nltype = NLTYPE_ANYCRLF;
3909      }
3910    else if (newline < 0)
3911    {    {
3912    md->nltype = NLTYPE_ANY;    md->nltype = NLTYPE_ANY;
3913    }    }
# Line 4013  for(;;) Line 4082  for(;;)
4082        {        {
4083        while (start_match <= end_subject && !WAS_NEWLINE(start_match))        while (start_match <= end_subject && !WAS_NEWLINE(start_match))
4084          start_match++;          start_match++;
4085    
4086          /* If we have just passed a CR and the newline option is ANY or ANYCRLF,
4087          and we are now at a LF, advance the match position by one more character.
4088          */
4089    
4090          if (start_match[-1] == '\r' &&
4091               (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) &&
4092               start_match < end_subject &&
4093               *start_match == '\n')
4094            start_match++;
4095        }        }
4096      }      }
4097    
# Line 4099  for(;;) Line 4178  for(;;)
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    
# Line 4128  for(;;) Line 4208  for(;;)
4208    
4209    if (anchored || start_match > end_subject) break;    if (anchored || start_match > end_subject) break;
4210    
4211    /* If we have just passed a CR and the newline option is CRLF or ANY, and we    /* If we have just passed a CR and the newline option is CRLF or ANY or
4212    are now at a LF, advance the match position by one more character. */    ANYCRLF, and we are now at a LF, advance the match position by one more
4213      character. */
4214    
4215    if (start_match[-1] == '\r' &&    if (start_match[-1] == '\r' &&
4216         (md->nltype == NLTYPE_ANY || md->nllen == 2) &&         (md->nltype == NLTYPE_ANY ||
4217            md->nltype == NLTYPE_ANYCRLF ||
4218            md->nllen == 2) &&
4219         start_match < end_subject &&         start_match < end_subject &&
4220         *start_match == '\n')         *start_match == '\n')
4221      start_match++;      start_match++;
# Line 4179  if (rc == MATCH_MATCH) Line 4262  if (rc == MATCH_MATCH)
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    

Legend:
Removed from v.123  
changed lines
  Added in v.172

  ViewVC Help
Powered by ViewVC 1.1.5