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 | |
7 | static int |
8 | recursiveloop(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 | |
83 | int |
84 | re1_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 | |