You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
238 lines
6.7 KiB
238 lines
6.7 KiB
Index: Makefile.in |
|
--- Makefile.in.orig 2010-07-18 21:30:41.000000000 +0200 |
|
+++ Makefile.in 2010-07-22 21:25:22.000000000 +0200 |
|
@@ -191,6 +191,21 @@ |
|
# |
|
LIBOBJ = $(LIBOBJS$(USE_AMALGAMATION)) |
|
|
|
+# FTS3 support |
|
+ifdef FTS3 |
|
+TCC += -DSQLITE_ENABLE_FTS3 -I$(TOP)/ext/fts3 |
|
+endif |
|
+ |
|
+# RTREE support |
|
+ifdef RTREE |
|
+TCC += -DSQLITE_ENABLE_RTREE -I$(TOP)/ext/rtree |
|
+endif |
|
+ |
|
+# REGEXP support |
|
+ifdef REGEXP |
|
+TCC += -DSQLITE_ENABLE_REGEXP |
|
+LIBOBJ += regexp.lo |
|
+endif |
|
|
|
# All of the source code files. |
|
# |
|
@@ -325,6 +340,8 @@ |
|
SRC += \ |
|
$(TOP)/ext/rtree/rtree.h \ |
|
$(TOP)/ext/rtree/rtree.c |
|
+SRC += \ |
|
+ $(TOP)/ext/regexp/regexp.c |
|
|
|
|
|
# Generated source code files |
|
@@ -835,6 +852,8 @@ |
|
rtree.lo: $(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR) |
|
$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/rtree/rtree.c |
|
|
|
+regexp.lo: $(TOP)/ext/regexp/regexp.c $(HDR) $(EXTHDR) |
|
+ $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/regexp/regexp.c |
|
|
|
# Rules to build the 'testfixture' application. |
|
# |
|
Index: configure |
|
--- configure.orig 2010-07-18 21:30:41.000000000 +0200 |
|
+++ configure 2010-07-22 21:24:57.000000000 +0200 |
|
@@ -6012,11 +6012,7 @@ |
|
if $ac_preproc_ok; then |
|
: |
|
else |
|
- { { $as_echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check |
|
-See \`config.log' for more details." >&5 |
|
-$as_echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check |
|
-See \`config.log' for more details." >&2;} |
|
- { (exit 1); exit 1; }; } |
|
+ : |
|
fi |
|
|
|
ac_ext=c |
|
Index: ext/regexp/regexp.c |
|
--- ext/regexp/regexp.c.orig 2010-07-22 21:24:57.000000000 +0200 |
|
+++ ext/regexp/regexp.c 2010-07-22 21:24:57.000000000 +0200 |
|
@@ -0,0 +1,147 @@ |
|
+/* |
|
+ * SQLite REGEXP(regex, string) function |
|
+ * Copyright (c) 2010 by Ralf S. Engelschall <rse@engelschall.com> |
|
+ * |
|
+ * Based on Public Domain code from 2007 by Alexey Tourbin |
|
+ * <at@altlinux.org> which added plain PCRE based REGEXP function to |
|
+ * SQLite. In order to not require the SQLite _library_ to require the |
|
+ * external PCRE library, the code was adapted to the regex(3) API as |
|
+ * standardized by IEEE Std 1003.2 ("POSIX.2"), sections 2.8 (Regular |
|
+ * Expression Notation) and B.5 (C Binding for Regular Expression |
|
+ * Matching) and which is usually provided already by any modern Unix |
|
+ * system in libc. |
|
+ */ |
|
+ |
|
+#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_REGEXP) |
|
+ |
|
+/* standard includes */ |
|
+#include <assert.h> |
|
+#include <stdlib.h> |
|
+#include <string.h> |
|
+#include <regex.h> |
|
+ |
|
+/* SQLite includes */ |
|
+#ifndef SQLITE_CORE |
|
+#include "sqlite3ext.h" |
|
+SQLITE_EXTENSION_INIT1 |
|
+#else |
|
+#include "sqlite3.h" |
|
+#endif |
|
+ |
|
+/* regex cache configuration */ |
|
+#ifndef CACHE_SIZE |
|
+#define CACHE_SIZE 32 |
|
+#endif |
|
+typedef struct { |
|
+ char *str; |
|
+ regex_t re; |
|
+} cache_entry; |
|
+ |
|
+/* the SQL REGEXP(regex, string) function C implementation */ |
|
+static void regexp(sqlite3_context *ctx, int argc, sqlite3_value **argv) |
|
+{ |
|
+ const char *re_str, *str; |
|
+ regex_t *re; |
|
+ int i; |
|
+ int rc; |
|
+ int found; |
|
+ cache_entry *cache; |
|
+ cache_entry c; |
|
+ char err[1024]; |
|
+ |
|
+ /* sanity check arguments */ |
|
+ if (argc != 2) { |
|
+ sqlite3_result_error(ctx, "invalid number of arguments to REGEXP function", -1); |
|
+ return; |
|
+ } |
|
+ if ((re_str = (const char *)sqlite3_value_text(argv[0])) == NULL) { |
|
+ sqlite3_result_error(ctx, "no regexp argument given to REGEXP function", -1); |
|
+ return; |
|
+ } |
|
+ if ((str = (const char *)sqlite3_value_text(argv[1])) == NULL) { |
|
+ sqlite3_result_error(ctx, "no string argument given to REGEXP function", -1); |
|
+ return; |
|
+ } |
|
+ |
|
+ /* simple regex LRU caching */ |
|
+ if ((cache = sqlite3_user_data(ctx)) == NULL) { |
|
+ sqlite3_result_error(ctx, "no regex cache available", -1); |
|
+ return; |
|
+ } |
|
+ found = 0; |
|
+ for (i = 0; i < CACHE_SIZE && cache[i].str != NULL; i++) { |
|
+ if (strcmp(re_str, cache[i].str) == 0) { |
|
+ found = 1; |
|
+ break; |
|
+ } |
|
+ } |
|
+ if (found) { |
|
+ if (i > 0) { |
|
+ /* move cache[i] element to front for faster searching next time */ |
|
+ c = cache[i]; |
|
+ memmove(cache + 1, cache, i * sizeof(cache_entry)); |
|
+ cache[0] = c; |
|
+ } |
|
+ } |
|
+ else { |
|
+ /* compile and store regular expression */ |
|
+ int rc = regcomp(&(c.re), re_str, REG_EXTENDED|REG_NOSUB); |
|
+ if (rc != 0) { |
|
+ regerror(rc, &(c.re), err, sizeof(err)); |
|
+ char *e2 = sqlite3_mprintf("regex \"%s\" failed to compile: %s", re_str, err); |
|
+ sqlite3_result_error(ctx, e2, -1); |
|
+ sqlite3_free(e2); |
|
+ return; |
|
+ } |
|
+ if ((c.str = strdup(re_str)) == NULL) { |
|
+ sqlite3_result_error(ctx, "strdup: ENOMEM", -1); |
|
+ regfree(&(c.re)); |
|
+ return; |
|
+ } |
|
+ |
|
+ /* insert regex into cache (at first position) */ |
|
+ i = CACHE_SIZE - 1; |
|
+ if (cache[i].str != NULL) { |
|
+ /* expire oldest cache entry */ |
|
+ free(cache[i].str); |
|
+ regfree(&(cache[i].re)); |
|
+ } |
|
+ memmove(cache + 1, cache, i * sizeof(cache_entry)); |
|
+ cache[0] = c; |
|
+ } |
|
+ |
|
+ /* take compiled regular expression (either found old one or created new one) */ |
|
+ re = &(cache[0].re); |
|
+ |
|
+ /* apply regular expression onto given string and report matching result */ |
|
+ rc = regexec(re, str, 0, NULL, 0); |
|
+ sqlite3_result_int(ctx, rc == 0); |
|
+ |
|
+ return; |
|
+} |
|
+ |
|
+/* SQLITE_CORE (built-in) entry point */ |
|
+int sqlite3RegexpInit(sqlite3 *); |
|
+int sqlite3RegexpInit(sqlite3 *db) |
|
+{ |
|
+ cache_entry *cache = NULL; |
|
+ int rc = SQLITE_OK; |
|
+ |
|
+ if ((cache = calloc(CACHE_SIZE, sizeof(cache_entry))) == NULL) |
|
+ return SQLITE_NOMEM; |
|
+ rc = sqlite3_create_function(db, "REGEXP", 2, SQLITE_UTF8, cache, regexp, NULL, NULL); |
|
+ return rc; |
|
+} |
|
+ |
|
+#ifndef SQLITE_CORE |
|
+/* DSO entry point */ |
|
+int sqlite3_extension_init(sqlite3 *, char **, const sqlite3_api_routines *); |
|
+int sqlite3_extension_init(sqlite3 *db, char **err, const sqlite3_api_routines *api) |
|
+{ |
|
+ SQLITE_EXTENSION_INIT2(api) |
|
+ return sqlite3RegexpInit(db); |
|
+} |
|
+#endif |
|
+ |
|
+#endif |
|
+ |
|
Index: sqlite3.pc.in |
|
--- sqlite3.pc.in.orig 2010-06-21 13:48:22.000000000 +0200 |
|
+++ sqlite3.pc.in 2010-07-22 21:24:57.000000000 +0200 |
|
@@ -8,6 +8,5 @@ |
|
Name: SQLite |
|
Description: SQL database engine |
|
Version: @RELEASE@ |
|
-Libs: -L${libdir} -lsqlite3 |
|
-Libs.private: @LIBS@ |
|
+Libs: -L${libdir} -lsqlite3 @LIBS@ |
|
Cflags: -I${includedir} |
|
Index: src/main.c |
|
--- src/main.c.orig 2010-07-18 21:30:41.000000000 +0200 |
|
+++ src/main.c 2010-07-22 21:24:57.000000000 +0200 |
|
@@ -1869,6 +1869,13 @@ |
|
} |
|
#endif |
|
|
|
+#ifdef SQLITE_ENABLE_REGEXP |
|
+ if( !db->mallocFailed && rc==SQLITE_OK){ |
|
+ extern int sqlite3RegexpInit(sqlite3*); |
|
+ rc = sqlite3RegexpInit(db); |
|
+ } |
|
+#endif |
|
+ |
|
sqlite3Error(db, rc, 0); |
|
|
|
/* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking
|
|
|