PTR REcompile(char *re, size_t len) { MACHINE m_stack[STACKSZ]; struct op { int token; int prec; } op_stack[STACKSZ]; register MACHINE *m_ptr; register struct op *op_ptr; register int t; /* do this first because it also checks if we have a run time stack */ RE_lex_init(re, len); if (len == 0) { STATE *p = (STATE *) RE_malloc(sizeof(STATE)); p->s_type = M_ACCEPT; return (PTR) p; } if (setjmp(err_buf)) return (PTR) 0; /* we used to try to recover memory left on machine stack ; but now m_ptr is in a register so it won't be right unless we force it out of a register which isn't worth the trouble */ /* initialize the stacks */ m_ptr = m_stack - 1; op_ptr = op_stack; op_ptr->token = 0; t = RE_lex(m_stack); while (1) { switch (t) { case T_STR: case T_ANY: case T_U: case T_START: case T_END: case T_CLASS: m_ptr++; break; case 0: /* end of reg expr */ if (op_ptr->token == 0) { /* done */ if (m_ptr == m_stack) return (PTR) m_ptr->start; else { /* machines still on the stack */ RE_panic("values still on machine stack"); } } /* otherwise fall thru to default which is operator case */ default: if ((op_ptr->prec = table[op_ptr->token][t]) == G) { do { /* op_pop */ if (op_ptr->token <= T_CAT) /*binary op */ m_ptr--; /* if not enough values on machine stack then we have a missing operand */ if (m_ptr < m_stack) RE_error_trap(-E4); switch (op_ptr->token) { case T_CAT: RE_cat(m_ptr, m_ptr + 1); break; case T_OR: RE_or(m_ptr, m_ptr + 1); break; case T_STAR: RE_close(m_ptr); break; case T_PLUS: RE_poscl(m_ptr); break; case T_Q: RE_01(m_ptr); break; default: /*nothing on ( or ) */ break; } op_ptr--; } while (op_ptr->prec != L); continue; /* back thru switch at top */ } if (op_ptr->prec < 0) { if (op_ptr->prec == E7) RE_panic("parser returns E7"); else RE_error_trap(-op_ptr->prec); } if (++op_ptr == op_stack + STACKSZ) { /* stack overflow */ RE_error_trap(-E5); } op_ptr->token = t; } /* end of switch */ if (m_ptr == m_stack + (STACKSZ - 1)) { /*overflow */ RE_error_trap(-E5); } t = RE_lex(m_ptr + 1); } }
void RE_poscl_limit(MACHINE * mp, int ilimit) { RE_poscl(mp); RE_set_limit(mp->start, ilimit); }