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