#include "dgd.h" #include "str.h" #include "array.h" #include "interpret.h" #include "regex/regex.h" #include "rgx.h" static char trans_table[256]; /* * NAME: regexp->init() * DESCRIPTION: initialize regexp handling */ void rgx_init() { register int i; for (i = 0; i < 256; ++i) trans_table[i] = i; for (i = 'a'; i <= 'z'; ++i) trans_table[i] = i + 'A' - 'a'; } /* * NAME: regexp->new() * DESCRIPTION: create a new regexp buffer */ array *rgx_new(pattern, case_matters) string *pattern; int case_matters; { char *translate; struct re_pattern_buffer patbuf; char fastmap[256]; const char *compile_error; array *result; register value *v; translate = (case_matters ? (char *) 0 : trans_table); patbuf.buffer = 0; patbuf.allocated = 0; patbuf.used = 0; patbuf.fastmap = fastmap; patbuf.translate = translate; patbuf.fastmap_accurate = 0; compile_error = re_compile_pattern(pattern->text, pattern->len, &patbuf); if (compile_error != (char *) 0) { regfree(&patbuf); error(compile_error); } re_compile_fastmap(&patbuf); result = arr_new(3L); v = result->elts; v->type = T_STRING; str_ref(v->u.string = str_new((char *) &patbuf, (long) sizeof(patbuf))); ++v; v->type = T_STRING; str_ref(v->u.string = str_new((char *) patbuf.buffer, (long) patbuf.allocated)); ++v; v->type = T_STRING; str_ref(v->u.string = str_new(fastmap, 256L)); regfree(&patbuf); return result; } /* * NAME: regexp->match() * DESCRIPTION: perform regexp matching, given a pattern and subject string */ array *rgx_match(pattern, subject, reverse) value *pattern; string *subject; int reverse; { long sub_len; struct re_pattern_buffer *patbuf; struct re_registers regs; regoff_t starts[RGX_NREGS + 1], ends[RGX_NREGS + 1]; array *result; register value *v; register int i; patbuf = (struct re_pattern_buffer *) pattern->u.string->text; if (patbuf->allocated != (unsigned long) pattern[1].u.string->len || pattern[2].u.string->len != 256L) error("Invalid compiled pattern"); patbuf->buffer = (unsigned char *) pattern[1].u.string->text; patbuf->fastmap = pattern[2].u.string->text; regs.num_regs = RGX_NREGS; regs.start = starts; regs.end = ends; patbuf->regs_allocated = REGS_FIXED; sub_len = subject->len; if (re_search(patbuf, subject->text, sub_len, reverse ? sub_len : 0, reverse ? -(sub_len + 1) : sub_len + 1, ®s) == -1) return (array *) 0; result = arr_new((long) RGX_NREGS * 2); v = result->elts; v->type = T_INT; v->u.number = starts[0]; ++v; v->type = T_INT; v->u.number = ends[0] - 1; ++v; for (i = 1; i < RGX_NREGS; ++i, v += 2) { v->type = T_INT; v[1].type = T_INT; if (starts[i] == -1) { v->u.number = 0; v[1].u.number = -1; } else { v->u.number = starts[i]; v[1].u.number = ends[i] - 1; } } return result; }