1// Copyright 2007-2009 Russ Cox. All Rights Reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5#include "re1.5.h"
6
7static int
8recursiveloop(char *pc, const char *sp, Subject *input, const char **subp, int nsubp)
9{
10 const char *old;
11 int off;
12
13 re1_5_stack_chk();
14
15 for(;;) {
16 if(inst_is_consumer(*pc)) {
17 // If we need to match a character, but there's none left, it's fail
18 if(sp >= input->end)
19 return 0;
20 }
21 switch(*pc++) {
22 case Char:
23 if(*sp != *pc++)
24 return 0;
25 MP_FALLTHROUGH
26 case Any:
27 sp++;
28 continue;
29 case Class:
30 case ClassNot:
31 if (!_re1_5_classmatch(pc, sp))
32 return 0;
33 pc += *(unsigned char*)pc * 2 + 1;
34 sp++;
35 continue;
36 case NamedClass:
37 if (!_re1_5_namedclassmatch(pc, sp))
38 return 0;
39 pc++;
40 sp++;
41 continue;
42 case Match:
43 return 1;
44 case Jmp:
45 off = (signed char)*pc++;
46 pc = pc + off;
47 continue;
48 case Split:
49 off = (signed char)*pc++;
50 if(recursiveloop(pc, sp, input, subp, nsubp))
51 return 1;
52 pc = pc + off;
53 continue;
54 case RSplit:
55 off = (signed char)*pc++;
56 if(recursiveloop(pc + off, sp, input, subp, nsubp))
57 return 1;
58 continue;
59 case Save:
60 off = (unsigned char)*pc++;
61 if(off >= nsubp) {
62 continue;
63 }
64 old = subp[off];
65 subp[off] = sp;
66 if(recursiveloop(pc, sp, input, subp, nsubp))
67 return 1;
68 subp[off] = old;
69 return 0;
70 case Bol:
71 if(sp != input->begin)
72 return 0;
73 continue;
74 case Eol:
75 if(sp != input->end)
76 return 0;
77 continue;
78 }
79 re1_5_fatal("recursiveloop");
80 }
81}
82
83int
84re1_5_recursiveloopprog(ByteProg *prog, Subject *input, const char **subp, int nsubp, int is_anchored)
85{
86 return recursiveloop(HANDLE_ANCHORED(prog->insts, is_anchored), input->begin, input, subp, nsubp);
87}
88