# include "dgd.h" # include "str.h" # include "array.h" # include "interpret.h" # include "regex/regex.h" # include "rgx.h" # include <memory.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)); /* don't let regfree() try to free these */ patbuf.fastmap = 0; patbuf.translate = 0; 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; if (pattern[0].u.string->len != sizeof(struct re_pattern_buffer)) error("Invalid compiled pattern"); memcpy((char *) &patbuf, pattern[0].u.string->text, sizeof(struct re_pattern_buffer)); if (patbuf.allocated != (unsigned long) pattern[1].u.string->len || pattern[2].u.string->len != 256) 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[0].type = T_INT; v[1].type = T_INT; if (starts[i] == -1) { v[0].u.number = 0; v[1].u.number = -1; } else { v[0].u.number = starts[i]; v[1].u.number = ends[i] - 1; } } return result; }