int recursiveloop(Inst *pc, char *sp, char **subp, int nsubp) { char *old; for(;;) { switch(pc->opcode) { case Char: if(*sp != pc->c) return 0; case Any: pc++; sp++; continue; case Match: return 1; case Jmp: pc = pc->x; continue; case Split: if(recursiveloop(pc->x, sp, subp, nsubp)) return 1; pc = pc->y; continue; case Save: if(pc->n >= nsubp) { pc++; continue; } old = subp[pc->n]; subp[pc->n] = sp; if(recursiveloop(pc+1, sp, subp, nsubp)) return 1; subp[pc->n] = old; return 0; } fatal("recursiveloop"); } }
int recursiveloopprog(Prog *prog, char *input, char **subp, int nsubp) { return recursiveloop(prog->start, input, subp, nsubp); }
int re1_5_recursiveloopprog(ByteProg *prog, Subject *input, const char **subp, int nsubp, int is_anchored) { return recursiveloop(HANDLE_ANCHORED(prog->insts, is_anchored), input->begin, input, subp, nsubp); }
static int recursiveloop(char *pc, const char *sp, Subject *input, const char **subp, int nsubp) { const char *old; int off; for(;;) { if(inst_is_consumer(*pc)) { // If we need to match a character, but there's none left, it's fail if(sp >= input->end) return 0; } switch(*pc++) { case Char: if(*sp != *pc++) return 0; case Any: sp++; continue; case Class: case ClassNot: if (!_re1_5_classmatch(pc, sp)) return 0; pc += *(unsigned char*)pc * 2 + 1; sp++; continue; case NamedClass: if (!_re1_5_namedclassmatch(pc, sp)) return 0; pc++; sp++; continue; case Match: return 1; case Jmp: off = (signed char)*pc++; pc = pc + off; continue; case Split: off = (signed char)*pc++; if(recursiveloop(pc, sp, input, subp, nsubp)) return 1; pc = pc + off; continue; case RSplit: off = (signed char)*pc++; if(recursiveloop(pc + off, sp, input, subp, nsubp)) return 1; continue; case Save: off = (unsigned char)*pc++; if(off >= nsubp) { continue; } old = subp[off]; subp[off] = sp; if(recursiveloop(pc, sp, input, subp, nsubp)) return 1; subp[off] = old; return 0; case Bol: if(sp != input->begin) return 0; continue; case Eol: if(sp != input->end) return 0; continue; } re1_5_fatal("recursiveloop"); } }