/* Scheme48 interface to Henry Spencer's regular expression package. ** Copyright (c) 1993, 1994 by Olin Shivers. */ #include #include "regexp.h" #include "cstuff.h" /* Make sure our exports match up w/the implementation: */ #include "re1.h" /* Not multi-threaded reentrant. */ static char *regexp_error; /* Stash error msg in global. */ void regerror(char *msg) {regexp_error = msg;} /* ** Return NULL normally, error string on error. ** Stash number of bytes needed for compiled regexp into `*len' */ char *re_byte_len(const char *re, int *len) { int l; regexp_error = 0; *len = regcomp_len(re); return regexp_error; } /* ** Return NULL normally, error string on error. ** Compile regexp into string described by `cr'. */ char *re_compile(const char *re, s48_value cr) { int len = S48_STRING_LENGTH(cr); regexp *r = (regexp *) &S48_STRING_REF(cr, 0); regexp_error = 0; regcomp_comp(re, r, len); return regexp_error; } /* Return NULL normally, error string on error. ** Stash match info in start_vec and end_vec. ** Returns boolean match/no-match in hit. */ char *re_exec(s48_value cr, const char *string, int start, s48_value start_vec, s48_value end_vec, int *hit) { regexp *r = (regexp *) &S48_STRING_REF(cr, 0); *hit = 0; if( S48_VECTOR_LENGTH(start_vec) != NSUBEXP ) /* These tests should */ return "Illegal start vector"; /* never trigger. */ if( S48_VECTOR_LENGTH(end_vec) != NSUBEXP ) return "Illegal end vector"; regexp_error = 0; if( regexec(r, string+start) ) { int i; for(i=0; istartp[i]; const char *e = r->endp[i]; S48_VECTOR_REF(start_vec,i) = s ? s48_enter_fixnum(s - string) : S48_FALSE; S48_VECTOR_REF(end_vec,i) = e ? s48_enter_fixnum(e - string) : S48_FALSE; r->startp[i] = 0; /* Why did Sommerfeld */ r->endp[i] = 0; /* put these here? */ } *hit = 1; } return regexp_error; } char *re_subst(s48_value cr, const char *match, const char *src, int start, s48_value start_vec, s48_value end_vec, s48_value outbuf, int *len) { int i; regexp *r = (regexp *) &S48_STRING_REF(cr, 0); if( S48_VECTOR_LENGTH(start_vec) != NSUBEXP ) /* These tests should */ return "Illegal start vector"; /* never trigger. */ if( S48_VECTOR_LENGTH(end_vec) != NSUBEXP ) return "Illegal end vector"; for (i=0; istartp[i] = S48_FIXNUM_P(se) ? (match + s48_extract_fixnum(se)) : 0; r->endp[i] = S48_FIXNUM_P(ee) ? (match + s48_extract_fixnum(ee)) : 0; } regexp_error = 0; regnsub(r, src, &S48_STRING_REF(outbuf, 0), S48_STRING_LENGTH(outbuf)); *len = strlen(&S48_STRING_REF(outbuf, 0)); return regexp_error; } char *re_subst_len(s48_value cr, const char *match, const char *src, int start, s48_value start_vec, s48_value end_vec, int *len) { int i; regexp *r = (regexp *) &S48_STRING_REF(cr, 0); if( S48_VECTOR_LENGTH(start_vec) != NSUBEXP ) /* These tests should */ return "Illegal start vector"; /* never trigger. */ if( S48_VECTOR_LENGTH(end_vec) != NSUBEXP ) return "Illegal end vector"; for (i=0; istartp[i] = S48_FIXNUM_P(se) ? (match + s48_extract_fixnum(se)) : 0; r->endp[i] = S48_FIXNUM_P(ee) ? (match + s48_extract_fixnum(ee)) : 0; } regexp_error = 0; *len = regsublen(r, src); return regexp_error; } /* Return NULL normally, error string on error. ** Stash match info in start_vec and end_vec. ** Returns boolean match/no-match in hit. */ char *re_match(const char *re, const char *string, int start, s48_value start_vec, s48_value end_vec, int *hit) { regexp *prog; regexp_error = 0; *hit = 0; prog = regcomp(re); if( !prog ) return regexp_error; if( S48_VECTOR_LENGTH(start_vec) != NSUBEXP ) { /* These two tests */ Free(prog); return "Illegal start vector"; } if( S48_VECTOR_LENGTH(end_vec) != NSUBEXP ) { /* should never trigger. */ Free(prog); return "Illegal end vector"; } if( regexec(prog, string+start) ) { int i; for(i=0; istartp[i]; const char *e = prog->endp[i]; S48_VECTOR_REF(start_vec,i) = s ? s48_enter_fixnum(s - string) : S48_FALSE; S48_VECTOR_REF(end_vec,i) = e ? s48_enter_fixnum(e - string) : S48_FALSE; } *hit = 1; } Free(prog); return regexp_error; } char *filter_stringvec(const char *re, char const **stringvec, int *nummatch) { regexp *prog; regexp_error = 0; if( prog=regcomp(re) ) { char const **p = stringvec; char const **q = p; while(*p) { if( regexec(prog, *p) ) *q++ = *p; p++; } Free(prog); *nummatch = q-stringvec; } return regexp_error; }