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
recursiveloop(char * pc,const char * sp,Subject * input,const char ** subp,int nsubp)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
re1_5_recursiveloopprog(ByteProg * prog,Subject * input,const char ** subp,int nsubp,int is_anchored)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