Changeset: d5c2a21ccca2 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=d5c2a21ccca2
Modified Files:
        configure.ag
        monetdb5/modules/mal/pcre.c
Branch: port-monetdblite
Log Message:

Backported PCRE and POSIX regex free implementation from MonetDBLite


diffs (truncated from 861 to 300 lines):

diff --git a/configure.ag b/configure.ag
--- a/configure.ag
+++ b/configure.ag
@@ -1745,13 +1745,9 @@ AS_VAR_IF([have_pcre], [no], [
                [AC_MSG_RESULT([no]); have_gnuregex=no])
 ])
 
-AS_CASE([$enable_monetdb5-$have_pcre-$have_gnuregex],
-[yes-no-no], [
-       AC_MSG_ERROR([PCRE library or GNU regex library not found but required 
for MonetDB5])],
-[auto-no-no], [
-       enable_monetdb5=no
-       AS_VAR_IF([why_not_monetdb5], [], [
-               why_not_monetdb5="(PCRE library or GNU regex library not found 
but required for MonetDB5)"])])
+AS_VAR_IF([have_pcre], [no], [
+       AS_VAR_IF([have_gnuregex], [yes], [
+               AC_DEFINE([HAVE_LIBGNUREGEX], 1, [Define if you have the posix 
regex library])])])
 
 org_have_libxml2=yes
 have_libxml2=$org_have_libxml2
diff --git a/monetdb5/modules/mal/pcre.c b/monetdb5/modules/mal/pcre.c
--- a/monetdb5/modules/mal/pcre.c
+++ b/monetdb5/modules/mal/pcre.c
@@ -27,18 +27,18 @@
 #include <wchar.h>
 #include <wctype.h>
 
-#ifdef HAVE_LIBPCRE
+#if defined(HAVE_LIBPCRE)
 #include <pcre.h>
 #ifndef PCRE_STUDY_JIT_COMPILE
 /* old library version on e.g. EPEL 6 */
 #define pcre_free_study(x)             pcre_free(x)
 #endif
-
+#elif defined(HAVE_LIBGNUREGEX)
+#include <regex.h>
+typedef regex_t pcre;
 #else
-
-#include <regex.h>
-
-typedef regex_t pcre;
+#include "str.h"
+typedef void pcre;
 #endif
 
 mal_export str pcre_init(void *ret);
@@ -82,6 +82,7 @@ mal_export str LIKEjoin1(bat *r1, bat *r
 mal_export str ILIKEjoin(bat *r1, bat *r2, const bat *lid, const bat *rid, 
const str *esc, const bat *slid, const bat *srid, const bit *nil_matches, const 
lng *estimate);
 mal_export str ILIKEjoin1(bat *r1, bat *r2, const bat *lid, const bat *rid, 
const bat *slid, const bat *srid, const bit *nil_matches, const lng *estimate);
 
+#if defined(HAVE_LIBPCRE) || defined(HAVE_LIBGNUREGEX)
 /* current implementation assumes simple %keyword% [keyw%]* */
 typedef struct RE {
        char *k;
@@ -507,6 +508,91 @@ re_create(const char *pat, int nr, bool 
        re_destroy(r);
        return NULL;
 }
+#else
+static bit
+STRlike(const char* const_pattern, const char* const_data, bit 
case_insensitive, char escape)
+{
+       BATiter toi = bat_iterator(UTF8_lowerBat);
+       BATiter fromi = bat_iterator(UTF8_upperBat);
+       BUN UTF8_CONV_r;
+       char *back_pat = NULL, *back_str = NULL;
+       str pattern = (char*) const_pattern;
+       str pattern_start = NULL;
+       str data = (char*) const_data;
+       bit retval = 0;
+
+       (void) escape; // FIXME
+       if (case_insensitive) {
+               STRLower(&pattern, (const str*) &const_pattern);
+               pattern_start = pattern;
+       }
+
+       for (;;) {
+               unsigned char *c = (unsigned char *) data++;
+               unsigned char *d = (unsigned char *) pattern++;
+               char sz_c = 0, sz_d = 0;
+               unsigned int cp_c = 0, cp_d = 0;
+
+               switch (*d) {
+               case '_':
+                       if (*c == '\0')
+                               goto bailout;
+                       UTF8_GETCHAR_SZ(cp_c, sz_c, c);
+                       data += sz_c - 1;
+                       break;
+               case '%':
+                       if (*pattern == '\0') {
+                               retval = 1;
+                               goto bailout;
+                       }
+                       back_pat = pattern;
+                       back_str = --data; /* Allow zero-length match */
+                       break;
+               /* case '\\':
+                       d = *pat++;
+                       //FALLTHROUGH*/
+               default:        /* Literal character */
+                       if (case_insensitive && *c != '\0') {
+                               // get code points from strings
+                               UTF8_GETCHAR_SZ(cp_c, sz_c, c);
+                               UTF8_GETCHAR_SZ(cp_d, sz_d, d);
+
+                               if (cp_c < 0x80) {
+                                       if ('A' <= cp_c && cp_c <= 'Z')
+                                               cp_c += 'a' - 'A';
+                               } else {
+                                       HASHfnd_int(UTF8_CONV_r, fromi, &cp_c);
+                                       if (UTF8_CONV_r != BUN_NONE)
+                                               cp_c = *(int*) BUNtloc(toi, 
UTF8_CONV_r);
+                               }
+                               data += sz_c - 1;
+                               pattern += sz_d - 1;
+                               if (cp_c == cp_d)
+                                       break;
+                       } else {
+                               if (*c == *d) {
+                                       if (*d == '\0') {
+                                               retval = 1;
+                                               goto bailout;
+                                       }
+                                       break;
+                               }
+                       }
+                       if (*c == '\0' || !back_pat)
+                               goto bailout;   /* No point continuing */
+                       /* Try again from last *, one character later in str. */
+                       pattern = back_pat;
+                       data = ++back_str;
+                       break;
+               }
+       }
+bailout:
+hashfnd_failed:
+       if (case_insensitive)
+               GDKfree(pattern_start);
+       return retval;
+}
+#endif
 
 #ifdef HAVE_LIBPCRE
 static str
@@ -534,7 +620,7 @@ pcre_compile_wrap(pcre **res, const char
 /* scan select loop with candidates */
 #define candscanloop(TEST)                                                     
                                        \
        do {                                                                    
                                                        \
-               ALGODEBUG mnstr_printf(GDKerr,                                  
                                        \
+               ALGODEBUG mnstr_printf(GDKerr,                                  
                                \
                                                  
"#BATselect(b=%s#"BUNFMT",s=%s,anti=%d): "    \
                                                  "scanselect %s\n", 
BATgetId(b), BATcount(b),  \
                                                  s ? BATgetId(s) : "NULL", 
anti, #TEST);               \
@@ -551,7 +637,7 @@ pcre_compile_wrap(pcre **res, const char
 /* scan select loop without candidates */
 #define scanloop(TEST)                                                         
                                        \
        do {                                                                    
                                                        \
-               ALGODEBUG mnstr_printf(GDKerr,                                  
                                        \
+               ALGODEBUG mnstr_printf(GDKerr,                                  
                                \
                                                  
"#BATselect(b=%s#"BUNFMT",s=%s,anti=%d): "    \
                                                  "scanselect %s\n", 
BATgetId(b), BATcount(b),  \
                                                  s ? BATgetId(s) : "NULL", 
anti, #TEST);               \
@@ -568,14 +654,14 @@ pcre_compile_wrap(pcre **res, const char
 static str
 pcre_likeselect(BAT **bnp, BAT *b, BAT *s, const char *pat, bool caseignore, 
bool anti)
 {
-#ifdef HAVE_LIBPCRE
+#if defined(HAVE_LIBPCRE)
        int options = PCRE_UTF8 | PCRE_MULTILINE | PCRE_DOTALL;
        pcre *re;
        pcre_extra *pe;
        const char *error;
        int errpos;
        int ovector[10];
-#else
+#elif defined(HAVE_LIBGNUREGEX)
        int options = REG_NEWLINE | REG_NOSUB | REG_EXTENDED;
        regex_t re;
        int errcode;
@@ -588,14 +674,15 @@ pcre_likeselect(BAT **bnp, BAT *b, BAT *
 
        assert(ATOMstorage(b->ttype) == TYPE_str);
 
+#if defined(HAVE_LIBPCRE) || defined(HAVE_LIBGNUREGEX)
        if (caseignore) {
-#ifdef HAVE_LIBPCRE
+#if defined(HAVE_LIBPCRE)
                options |= PCRE_CASELESS;
 #else
                options |= REG_ICASE;
 #endif
        }
-#ifdef HAVE_LIBPCRE
+#if defined(HAVE_LIBPCRE)
        if ((re = pcre_compile(pat, options, &error, &errpos, NULL)) == NULL)
                throw(MAL, "pcre.likeselect",
                          OPERATION_FAILED ": compilation of pattern \"%s\" 
failed\n", pat);
@@ -605,18 +692,19 @@ pcre_likeselect(BAT **bnp, BAT *b, BAT *
                throw(MAL, "pcre.likeselect",
                          OPERATION_FAILED ": studying pattern \"%s\" 
failed\n", pat);
        }
-#else
+#else //GNU regex
        if ((errcode = regcomp(&re, pat, options)) != 0) {
                throw(MAL, "pcre.likeselect",
                          OPERATION_FAILED ": compilation of pattern \"%s\" 
failed\n", pat);
        }
 #endif
+#endif
        bn = COLnew(0, TYPE_oid, s ? BATcount(s) : BATcount(b), TRANSIENT);
        if (bn == NULL) {
-#ifdef HAVE_LIBPCRE
+#if defined(HAVE_LIBPCRE)
                pcre_free_study(pe);
                pcre_free(re);
-#else
+#elif defined(HAVE_LIBGNUREGEX)
                regfree(&re);
 #endif
                throw(MAL, "pcre.likeselect", SQLSTATE(HY001) MAL_MALLOC_FAIL);
@@ -636,10 +724,12 @@ pcre_likeselect(BAT **bnp, BAT *b, BAT *
                q = SORTfndfirst(s, &o);
                p = SORTfndfirst(s, &b->hseqbase);
                candlist = (const oid *) Tloc(s, p);
-#ifdef HAVE_LIBPCRE
+#if defined(HAVE_LIBPCRE)
 #define BODY     (pcre_exec(re, pe, v, (int) strlen(v), 0, 0, ovector, 10) >= 
0)
+#elif defined(HAVE_LIBGNUREGEX)
+#define BODY     (regexec(&re, v, (size_t) 0, NULL, 0) != REG_NOMATCH)
 #else
-#define BODY     (regexec(&re, v, (size_t) 0, NULL, 0) != REG_NOMATCH)
+#define BODY     (STRlike(pat, v, caseignore, '\0'))
 #endif
                if (anti)
                        candscanloop(v && *v != '\200' && !BODY);
@@ -663,10 +753,10 @@ pcre_likeselect(BAT **bnp, BAT *b, BAT *
                else
                        scanloop(v && *v != '\200' && BODY);
        }
-#ifdef HAVE_LIBPCRE
+#if defined(HAVE_LIBPCRE)
        pcre_free_study(pe);
        pcre_free(re);
-#else
+#elif defined(HAVE_LIBGNUREGEX)
        regfree(&re);
 #endif
        BATsetcount(bn, BATcount(bn)); /* set some properties */
@@ -680,16 +770,17 @@ pcre_likeselect(BAT **bnp, BAT *b, BAT *
 
   bunins_failed:
        BBPreclaim(bn);
-#ifdef HAVE_LIBPCRE
+#if defined(HAVE_LIBPCRE)
        pcre_free_study(pe);
        pcre_free(re);
-#else
+#elif defined(HAVE_LIBGNUREGEX)
        regfree(&re);
 #endif
        *bnp = NULL;
        throw(MAL, "pcre.likeselect", OPERATION_FAILED);
 }
 
+#if defined(HAVE_LIBPCRE) || defined(HAVE_LIBGNUREGEX)
 static str
 re_likeselect(BAT **bnp, BAT *b, BAT *s, const char *pat, bool caseignore, 
bool anti, bool use_strcmp)
 {
@@ -831,6 +922,7 @@ re_likeselect(BAT **bnp, BAT *b, BAT *s,
        *bnp = NULL;
        throw(MAL, "pcre.likeselect", OPERATION_FAILED);
 }
+#endif
 
 /* maximum number of back references and quoted \ or $ in replacement string */
 #define MAX_NR_REFS            20
@@ -1086,7 +1178,7 @@ pcre_replace(str *res, const char *origi
        (void) flags;
        (void) global;
        throw(MAL, global ? "pcre.replace" : "pcre.replace_first",
-                 "Database was compiled without PCRE support.");
+                 SQLSTATE(HY002) "Database was compiled without PCRE 
support.");
 #endif
 }
 
@@ -1212,7 +1304,7 @@ pcre_replace_bat(BAT **res, BAT *origin_
        (void) flags;
        (void) global;
        throw(MAL, global ? "batpcre.replace" : "batpcre.replace_first",
-                 "Database was compiled without PCRE support.");
+                 SQLSTATE(HY002) "Database was compiled without PCRE 
support.");
 #endif
 }
 
@@ -1223,6 +1315,7 @@ pcre_init(void *ret)
        return NULL;
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to