aboutsummaryrefslogtreecommitdiff
path: root/src/regexpmodule.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/regexpmodule.c')
-rw-r--r--src/regexpmodule.c191
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");
+}