# 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;
}