void RE_close(MACHINE * mp) { register STATE *p; unsigned sz; sz = (unsigned) (mp->stop - mp->start + 1); if (!subre_accepts_empty(mp)) { /* * 2JA end * loop: * m * 2JB loop * end: * ACCEPT */ p = (STATE *) RE_malloc((sz + 2) * STATESZ); memcpy(p + 1, mp->start, sz * STATESZ); RE_free(mp->start); mp->start = p; mp->stop = p + (sz + 1); p->s_type = M_2JA; p->s_data.jump = (int) (sz + 1); (p += sz)->s_type = M_2JB; p->s_data.jump = -(int) (sz - 1); p->s_data.jump |= !(p->s_data.jump); (p + 1)->s_type = M_ACCEPT; return; } /* * 2JA end * loop: * SAVE_POS * m * 2JC loop * end: * ACCEPT */ p = (STATE *) RE_malloc((sz + 3) * STATESZ); memcpy(p + 2, mp->start, sz * STATESZ); RE_free(mp->start); mp->start = p; mp->stop = p + (sz + 2); p->s_type = M_2JA; p->s_data.jump = (int) (sz + 2); (++p)->s_type = M_SAVE_POS; (p += sz)->s_type = M_2JC; p->s_data.jump = -(int) sz; (p + 1)->s_type = M_ACCEPT; }
void RE_poscl(MACHINE * mp) { register STATE *p; unsigned sz; /* * loop: * SAVE_POS * m * 2JC loop * ACCEPT */ sz = (unsigned) (mp->stop - mp->start + 1); p = (STATE *) RE_malloc((sz + 2) * STATESZ); memcpy(p + 1, mp->start, sz * STATESZ); RE_free(mp->start); mp->start = p; mp->stop = p + (sz + 1); p++->s_type = M_SAVE_POS; p += sz - 1; p->s_type = M_2JC; p->limit = INT_MAX; p->s_data.jump = -((int) sz); (p + 1)->s_type = M_ACCEPT; }
void RE_close(MACHINE * mp) { register STATE *p; unsigned sz; /* * 2JA end * loop: * SAVE_POS * m * 2JC loop * end: * ACCEPT */ sz = (unsigned) (mp->stop - mp->start + 1); p = (STATE *) RE_malloc((sz + 3) * STATESZ); memcpy(p + 2, mp->start, sz * STATESZ); RE_free(mp->start); mp->start = p; mp->stop = p + (sz + 2); p->s_type = M_2JA; p->s_data.jump = (int) (sz + 2); (++p)->s_type = M_SAVE_POS; (p += sz)->s_type = M_2JC; p->limit = INT_MAX; p->s_data.jump = -(int) sz; (p + 1)->s_type = M_ACCEPT; }
/* initialize a two state machine */ static void new_TWO( int type, MACHINE * mp) /* init mp-> */ { mp->start = (STATE *) RE_malloc(2 * STATESZ); mp->stop = mp->start + 1; mp->start->s_type = (SType) type; mp->stop->s_type = M_ACCEPT; }
void RE_run_stack_init(void) { if (!RE_run_stack_base) { RE_run_stack_base = (RT_STATE *) RE_malloc(sizeof(RT_STATE) * STACKGROWTH); RE_run_stack_limit = RE_run_stack_base + STACKGROWTH; RE_run_stack_empty = RE_run_stack_base - 1; } }
void RE_pos_stack_init(void) { if (!RE_pos_stack_base) { RE_pos_stack_base = (RT_POS_ENTRY *) RE_malloc(sizeof(RT_POS_ENTRY) * STACKGROWTH); RE_pos_stack_limit = RE_pos_stack_base + STACKGROWTH; RE_pos_stack_empty = RE_pos_stack_base; RE_pos_stack_base->pos = NULL; /* RE_pos_peek(RE_pos_stack_empty) */ RE_pos_stack_base->owner = -1; /* avoid popping base */ RE_pos_stack_base->prev_offset = 0; /* avoid popping below base */ } }
void RE_01(MACHINE * mp) { unsigned sz; register STATE *p; sz = (unsigned) (mp->stop - mp->start + 1); p = (STATE *) RE_malloc((sz + 1) * STATESZ); memcpy(p + 1, mp->start, sz * STATESZ); RE_free(mp->start); mp->start = p; mp->stop = p + sz; p->s_type = M_2JB; p->s_data.jump = (int) sz; }
void RE_poscl(MACHINE * mp) { register STATE *p; unsigned sz; sz = (unsigned) (mp->stop - mp->start + 1); if (!subre_accepts_empty(mp)) { /* * loop: * m * 2JB loop * end: * ACCEPT */ mp->start = p = (STATE *) RE_realloc(mp->start, (sz + 1) * STATESZ); mp->stop = p + sz; p += --sz; p->s_type = M_2JB; p->s_data.jump = -sz; p->s_data.jump |= !(p->s_data.jump); (p + 1)->s_type = M_ACCEPT; return; } /* * loop: * SAVE_POS * m * 2JC loop * ACCEPT */ p = (STATE *) RE_malloc((sz + 2) * STATESZ); memcpy(p + 1, mp->start, sz * STATESZ); RE_free(mp->start); mp->start = p; mp->stop = p + (sz + 1); p++->s_type = M_SAVE_POS; p += sz - 1; p->s_type = M_2JC; p->s_data.jump = -((int) sz); (p + 1)->s_type = M_ACCEPT; }
void RE_or(MACHINE * mp, MACHINE * np) { register STATE *p; unsigned szm, szn; szm = (unsigned) (mp->stop - mp->start + 1); szn = (unsigned) (np->stop - np->start + 1); p = (STATE *) RE_malloc((szm + szn + 1) * STATESZ); memcpy(p + 1, mp->start, szm * STATESZ); RE_free(mp->start); mp->start = p; (mp->stop = p + szm + szn)->s_type = M_ACCEPT; p->s_type = M_2JA; p->s_data.jump = (int) (szm + 1); memcpy(p + szm + 1, np->start, szn * STATESZ); RE_free(np->start); (p += szm)->s_type = M_1J; p->s_data.jump = (int) szn; }
void RE_01(MACHINE * mp) { unsigned sz; register STATE *p; /* * 2JB end (jump desirable if not found) * m * end: * ACCEPT */ sz = (unsigned) (mp->stop - mp->start + 1); p = (STATE *) RE_malloc((sz + 1) * STATESZ); memcpy(p + 1, mp->start, sz * STATESZ); RE_free(mp->start); mp->start = p; mp->stop = p + sz; p->s_type = M_2JB; p->s_data.jump = (int) sz; }
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); } }