diff --git a/src/modules/Regexp/Makefile.in b/src/modules/Regexp/Makefile.in index 21853b9fc4c4f4ec9110cbd08caed4824af78aa6..33850edf041a572cd9ebea8590df1d3ff985c135 100644 --- a/src/modules/Regexp/Makefile.in +++ b/src/modules/Regexp/Makefile.in @@ -1,6 +1,6 @@ SRCDIR=@srcdir@ VPATH=@srcdir@:@srcdir@/../..:../.. -OBJS=regexp.o glue.o +OBJS=glue.o @REGEXP_OBJS@ @dynamic_module_makefile@ @dependencies@ \ No newline at end of file diff --git a/src/modules/Regexp/configure.in b/src/modules/Regexp/configure.in index ed3283c8eec415697210f9591f054dac166c5e4c..67ddee25ddce4b09cca50ca1b69f5d00706675dd 100644 --- a/src/modules/Regexp/configure.in +++ b/src/modules/Regexp/configure.in @@ -1,7 +1,24 @@ -AC_INIT(regexp.c) +AC_INIT(pike_regexp.c) +AC_CONFIG_HEADER(config.h) sinclude(../module_configure.in) +AC_HAVE_HEADERS(regexp.h) + +AC_CHECK_FUNCS(regcomp regexec regerror regfree) + +AC_MSG_CHECKING(C lib has regexps) + +if test $ac_cv_header_regexp_h$ac_cv_func_regcomp$ac_cv_func_regexec$ac_cv_func_regerror$ac_cv_func_regfree = yesyesyesyesyes ; then + AC_DEFINE(USE_SYSTEM_REGEXP) + REGEXP_OBJS="" + AC_MSG_RESULT(yes) +else + REGEXP_OBJS="pike_regexp.o" + AC_MSG_RESULT(no) +fi + +AC_SUBST(REGEXP_OBJS) AC_OUTPUT(Makefile,echo FOO >stamp-h ) diff --git a/src/modules/Regexp/glue.c b/src/modules/Regexp/glue.c index 9da6245d8aeb83cb7574379c8f0c5a69bab9b722..d12810c6df6c2c367ee09062138848eabd8d7a5b 100644 --- a/src/modules/Regexp/glue.c +++ b/src/modules/Regexp/glue.c @@ -3,6 +3,11 @@ ||| Pike is distributed as GPL (General Public License) ||| See the files COPYING and DISCLAIMER for more information. \*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + #include "global.h" #include "types.h" #include "interpret.h" @@ -11,47 +16,93 @@ #include "array.h" #include "object.h" #include "macros.h" +#include "threads.h" +#ifdef USE_SYSTEM_REGEXP #include <regexp.h> +struct regexp_glue +{ + regex_t regexp; + int num_paren; +}; +#else +#include <pike_regexp.h> + struct regexp_glue { struct regexp *regexp; }; +#endif /* USE_SYSTEM_REGEXP */ + + #define THIS ((struct regexp_glue *)(fp->current_storage)) static void do_free() { if(THIS->regexp) { +#ifdef USE_SYSTEM_REGEXP + regfree(&(THIS->regexp)); +#else free((char *)THIS->regexp); THIS->regexp=0; +#endif /* USE_SYSTEM_REGEXP */ } } static void regexp_create(INT32 args) { + const char *str; + do_free(); if(args) { - if(sp[-args].type != T_STRING) - error("Bad argument 1 to regexp->create()\n"); + get_all_args("Regexp.regexp->create", args, "%s", &str); + +#ifdef USE_SYSTEM_REGEXP + { + int err = regcomp(&(THIS->regexp), str, 0); + int i; + char *paren_ptr; + + if (err) { + char buf[1024]; + regerror(err, &(THIS->regexp), buf, 1024); + error("Regexp.regexp->create(): Compilation failed:%s\n", buf); + } + for (i=0,paren_ptr=str; paren_ptr = strchr(paren_ptr, '('); i++) { + paren_ptr++; + } + THIS->num_paren = i; + } +#else THIS->regexp=regcomp(sp[-args].u.string->str, 0); +#endif } } static void regexp_match(INT32 args) { int i; - if(!args) - error("Too few arguments to regexp->match()\n"); - - if(sp[-args].type != T_STRING) - error("Bad argument 1 to regexp->match()\n"); - - i=regexec(THIS->regexp, sp[-args].u.string->str); + const char *str; +#ifdef USE_SYSTEM_REGEXP + regex_t *regexp = &(THIS->regexp); +#else + struct regexp *regexp = THIS->regexp; +#endif /* USE_SYSTEM_REGEXP */ + + get_all_args("Regexp.regexp->match", args, "%s", &str); + +#ifdef USE_SYSTEM_REGEXP + ALLOW_THREADS(); + i = !regexec(regexp, str, 0, NULL, 0); + DISALLOW_THREADS(); +#else + i=regexec(regexp, str); +#endif /* USE_SYSTEM_REGEXP */ pop_n_elems(args); push_int(i); } @@ -59,14 +110,47 @@ static void regexp_match(INT32 args) static void regexp_split(INT32 args) { struct pike_string *s; +#ifdef USE_SYSTEM_REGEXP + regex_t *r; + regmatch_t *pmatch; + size_t nmatch; + int match; +#else struct regexp *r; - if(!args) - error("Too few arguments to regexp->split()\n"); +#endif /* USE_SYSTEM_REGEXP */ + + get_all_args("Regexp.regexp->split", args, "%S", &s); + +#ifdef USE_SYSTEM_REGEXP + r = &(THIS->regexp); + nmatch = THIS->num_paren+1; + pmatch = xalloc(sizeof(regmatch_t)*nmatch); - if(sp[-args].type != T_STRING) - error("Bad argument 1 to regexp->split()\n"); + THREADS_ALLOW(); + match = !regexec(r, s->str, nmatch, pmatch, 0); + THREADS_DISALLOW(); + + if (match) { + int i,j; + + s->refs++; + pop_n_elems(args); - s=sp[-args].u.string; + for (i=1; i < nmatch; i++) { + if (pmatch[i].rm_sp && pmatch[i].rm_so != -1) { + push_string(make_shared_binary_string(pmatch[i].rm_sp, + pmatch[i].rm_eo-pmatch[i].rm_so)); + } else { + push_int(0); + } + } + f_aggregate_array(nmatch-1); + free_string(s); + } else { + pop_n_elems(args); + push_int(0); + } +#else if(regexec(r=THIS->regexp, s->str)) { int i,j; @@ -90,11 +174,16 @@ static void regexp_split(INT32 args) pop_n_elems(args); push_int(0); } +#endif /* USE_SYSTEM_REGEXP */ } static void init_regexp_glue(struct object *o) { +#ifdef USE_SYSTEM_REGEXP + MEMCLR(THIS, sizeof(struct regexp_glue)); +#else THIS->regexp=0; +#endif /* USE_SYSTEM_REGEXP */ } static void exit_regexp_glue(struct object *o)