diff options
Diffstat (limited to 'src/regexpmodule.c')
| -rw-r--r-- | src/regexpmodule.c | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/src/regexpmodule.c b/src/regexpmodule.c new file mode 100644 index 0000000..7c87217 --- /dev/null +++ b/src/regexpmodule.c @@ -0,0 +1,191 @@ +/*********************************************************** +Copyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The +Netherlands. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the names of Stichting Mathematisch +Centrum or CWI not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior permission. + +STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO +THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE +FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +******************************************************************/ + +/* Regular expression objects */ +/* This needs V8 or Henry Spencer's regexp! */ + +#include "allobjects.h" +#include "modsupport.h" + +#include "regexp.h" + +static object *RegexpError; /* Exception */ + +typedef struct { + OB_HEAD + object *re_string; /* The string (for printing) */ + regexp *re_prog; /* The compiled regular expression */ +} regexpobject; + +extern typeobject Regexptype; /* Really static, forward */ + +static regexpobject * +newregexpobject(string, prog) + object *string; + regexp *prog; +{ + regexpobject *re; + re = NEWOBJ(regexpobject, &Regexptype); + if (re != NULL) { + XINCREF(string); + re->re_string = string; + re->re_prog = prog; + } + return re; +} + +/* Regexp methods */ + +static void +regexp_dealloc(re) + regexpobject *re; +{ + XDECREF(re->re_string); + XDEL(re->re_prog); + DEL(re); +} + +static object * +makeresult(prog, buffer) + regexp *prog; + char *buffer; +{ + int n; + object *v; + /* Count substrings found, including \0, the main one */ + for (n = 0; n < 10 && prog->startp[n] != NULL; n++) + ; + v = newtupleobject(n); + if (v != NULL) { + int i; + for (i = 0; i < n; i++) { + object *w, *u; + long start, end; + start = prog->startp[i] - buffer; + end = prog->endp[i] - buffer; + if ( (w = newtupleobject(2)) == NULL || + (u = newintobject(start)) == NULL || + settupleitem(w, 0, u) != 0 || + (u = newintobject(end)) == NULL || + settupleitem(w, 1, u) != 0) { + XDECREF(w); + DECREF(v); + return NULL; + } + settupleitem(v, i, w); + } + } + return v; +} + +static object * +regexp_exec(re, args) + regexpobject *re; + object *args; +{ + object *v; + char *buffer; + int offset; + if (args != NULL && is_stringobject(args)) { + v = args; + offset = 0; + } + else if (!getstrintarg(args, &v, &offset)) + return NULL; + buffer = getstringvalue(v); +#ifndef MULTILINE +#define reglexec(prog, str, offset) regexec((prog), (str)+(offset)) +#endif + if (!reglexec(re->re_prog, buffer, offset)) + return newtupleobject(0); + return makeresult(re->re_prog, buffer); +} + +static struct methodlist regexp_methods[] = { + "exec", regexp_exec, + {NULL, NULL} /* sentinel */ +}; + +static object * +regexp_getattr(re, name) + regexpobject *re; + char *name; +{ + return findmethod(regexp_methods, (object *)re, name); +} + +static typeobject Regexptype = { + OB_HEAD_INIT(&Typetype) + 0, /*ob_size*/ + "regexp", /*tp_name*/ + sizeof(regexpobject), /*tp_size*/ + 0, /*tp_itemsize*/ + /* methods */ + regexp_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + regexp_getattr, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ +}; + +void +regerror(str) + char *str; +{ + err_setstr(RegexpError, str); +} + +static object * +regexp_compile(self, args) + object *self; + object *args; +{ + object *string; + regexp *prog; + if (!getstrarg(args, &string)) + return NULL; + prog = regcomp(getstringvalue(string)); + if (prog == NULL) + return NULL; /* regerror() has called err_seterr() */ + return (object *)newregexpobject(string, prog); +} + +static struct methodlist regexp_global_methods[] = { + {"compile", regexp_compile}, + {NULL, NULL} /* sentinel */ +}; + +initregexp() +{ + object *m, *d; + + m = initmodule("regexp", regexp_global_methods); + d = getmoduledict(m); + + /* Initialize regexp.error exception */ + RegexpError = newstringobject("regexp.error"); + if (RegexpError == NULL || dictinsert(d, "error", RegexpError) != 0) + fatal("can't define regexp.error"); +} |
