<pre style='margin:0'>
Perry E. Metzger (pmetzger) pushed a commit to branch master
in repository macports-ports.
</pre>
<p><a href="https://github.com/macports/macports-ports/commit/daccb0f68f57cb36d00223bfb29fb41eb4b4830f">https://github.com/macports/macports-ports/commit/daccb0f68f57cb36d00223bfb29fb41eb4b4830f</a></p>
<pre style="white-space: pre; background: #F8F8F8">The following commit(s) were added to refs/heads/master by this push:
<span style='display:block; white-space:pre;color:#404040;'> new daccb0f68f5 sqlite3-pcre2: new port with SQLite regex extension
</span>daccb0f68f5 is described below
<span style='display:block; white-space:pre;color:#808000;'>commit daccb0f68f57cb36d00223bfb29fb41eb4b4830f
</span>Author: nilason <n_larsson@yahoo.com>
AuthorDate: Wed Jun 14 12:22:12 2023 +0200
<span style='display:block; white-space:pre;color:#404040;'> sqlite3-pcre2: new port with SQLite regex extension
</span>---
databases/sqlite3-pcre2/Portfile | 52 ++++++
databases/sqlite3-pcre2/files/prec2_c.diff | 251 +++++++++++++++++++++++++++++
databases/sqlite3-pcre2/files/test.sh | 10 ++
3 files changed, 313 insertions(+)
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/databases/sqlite3-pcre2/Portfile b/databases/sqlite3-pcre2/Portfile
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 00000000000..7de08ba7b48
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/databases/sqlite3-pcre2/Portfile
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,52 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+PortSystem 1.0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+name sqlite3-pcre2
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+version 0.1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+revision 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+categories databases
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+license public-domain
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+maintainers {yahoo.com:n_larsson @nilason} openmaintainer
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+description Perl-compatible regular expression support for SQLite
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+long_description {*}${description}.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+homepage https://git.altlinux.org/people/at/packages/?p=sqlite3-pcre.git
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+patchfiles-append prec2_c.diff
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+fetch.type git
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+git.url git://git.altlinux.org/people/at/packages/sqlite3-pcre.git
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+git.branch 4229ecc
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+depends_build port:pkgconfig
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+depends_lib port:sqlite3 \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ port:pcre2
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+use_configure no
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+build {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set cflags [exec ${prefix}/bin/pkg-config --cflags sqlite3 libpcre2-8]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set libs [exec ${prefix}/bin/pkg-config --libs sqlite3 libpcre2-8]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ system -W ${worksrcpath} "${configure.cc} -fPIC -dynamiclib \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ -o pcre2.dylib ${cflags} ${libs} \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ -current_version ${version} -compatibility_version ${version} pcre.c"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+destroot {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ file mkdir ${destroot}${prefix}/lib/sqlite3
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ file copy ${worksrcpath}/pcre2.dylib \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ${destroot}${prefix}/lib/sqlite3/pcre2.dylib
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+test.cmd ${filespath}/test.sh ${prefix} ${worksrcpath}/pcre2.dylib
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+test.run yes
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+notes-append \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+"Load the installed SQLite extension with\
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+'.load ${prefix}/lib/sqlite3/pcre2.dylib'."
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/databases/sqlite3-pcre2/files/prec2_c.diff b/databases/sqlite3-pcre2/files/prec2_c.diff
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 00000000000..6d4ae8daa3a
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/databases/sqlite3-pcre2/files/prec2_c.diff
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,251 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Patch made with:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+https://github.com/christian-proust/sqlite3-pcre2/blob/e3e02a4af39d5dfdbd2cc8801696ed9ae2faf569/pcre2.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+with the additional change to 'const unsigned char *pattern_str, *subject_str;'.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- pcre.c.orig 2023-06-14 08:44:05.000000000 +0200
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ pcre.c 2023-06-14 09:01:48.000000000 +0200
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1,22 +1,24 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- * Written by Alexey Tourbin <at@altlinux.org>.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Initially written by Alexey Tourbin <at@altlinux.org>.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * The author has dedicated the code to the public domain. Anyone is free
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * to copy, modify, publish, use, compile, sell, or distribute the original
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * code, either in source code form or as a compiled binary, for any purpose,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * commercial or non-commercial, and by any means.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#define PCRE2_CODE_UNIT_WIDTH 8
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <assert.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <stdlib.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <string.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#include <pcre.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <pcre2.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <sqlite3ext.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ SQLITE_EXTENSION_INIT1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ typedef struct {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- char *s;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- pcre *p;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- pcre_extra *e;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ char *pattern_str;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int pattern_len;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ pcre2_code *pattern_code;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ } cache_entry;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #ifndef CACHE_SIZE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -24,96 +26,136 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ static
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-void regexp(sqlite3_context *ctx, int argc, sqlite3_value **argv)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- const char *re, *str;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- pcre *p;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- pcre_extra *e;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void regexp(sqlite3_context *ctx, int argc, sqlite3_value **argv) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ const unsigned char *pattern_str, *subject_str;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int pattern_len, subject_len;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ pcre2_code *pattern_code;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ assert(argc == 2);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* check null */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (sqlite3_value_type(argv[0]) == SQLITE_NULL || sqlite3_value_type(argv[1]) == SQLITE_NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- re = (const char *) sqlite3_value_text(argv[0]);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (!re) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- sqlite3_result_error(ctx, "no regexp", -1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ pattern_str = sqlite3_value_text(argv[0]);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (!pattern_str) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sqlite3_result_error(ctx, "no pattern", -1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ pattern_len = sqlite3_value_bytes(argv[0]);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- str = (const char *) sqlite3_value_text(argv[1]);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (!str) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- sqlite3_result_error(ctx, "no string", -1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ subject_str = sqlite3_value_text(argv[1]);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (!subject_str) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sqlite3_result_error(ctx, "no subject", -1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ subject_len = sqlite3_value_bytes(argv[1]);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* simple LRU cache */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- int i;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- int found = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- cache_entry *cache = sqlite3_user_data(ctx);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- assert(cache);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- for (i = 0; i < CACHE_SIZE && cache[i].s; i++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (strcmp(re, cache[i].s) == 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- found = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (found) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (i > 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- cache_entry c = cache[i];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- memmove(cache + 1, cache, i * sizeof(cache_entry));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- cache[0] = c;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- cache_entry c;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- const char *err;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- int pos;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- c.p = pcre_compile(re, 0, &err, &pos, NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (!c.p) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- char *e2 = sqlite3_mprintf("%s: %s (offset %d)", re, err, pos);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- sqlite3_result_error(ctx, e2, -1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- sqlite3_free(e2);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- c.e = pcre_study(c.p, 0, &err);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- c.s = strdup(re);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (!c.s) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- sqlite3_result_error(ctx, "strdup: ENOMEM", -1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- pcre_free(c.p);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- pcre_free(c.e);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- i = CACHE_SIZE - 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (cache[i].s) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- free(cache[i].s);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- assert(cache[i].p);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- pcre_free(cache[i].p);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- pcre_free(cache[i].e);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- memmove(cache + 1, cache, i * sizeof(cache_entry));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- cache[0] = c;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- p = cache[0].p;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- e = cache[0].e;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int i;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int found = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ cache_entry *cache = sqlite3_user_data(ctx);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ assert(cache);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (i = 0; i < CACHE_SIZE && cache[i].pattern_str; i++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ pattern_len == cache[i].pattern_len
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ && memcmp(pattern_str, cache[i].pattern_str, pattern_len) == 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ found = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (found) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (i > 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ cache_entry c = cache[i];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ memmove(cache + 1, cache, i * sizeof(cache_entry));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ cache[0] = c;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ cache_entry c;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ const char *err;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int error_code;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ PCRE2_SIZE error_position;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ c.pattern_code = pcre2_compile(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ pattern_str, /* the pattern */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ pattern_len, /* the length of the pattern */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0, /* default options */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ &error_code, /* for error number */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ &error_position, /* for error offset */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ NULL); /* use default compile context */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (!c.pattern_code) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ PCRE2_UCHAR error_buffer[256];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ pcre2_get_error_message(error_code, error_buffer, sizeof(error_buffer));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ char *e2 = sqlite3_mprintf(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ "Cannot compile pattern \"%s\" at offset %d: %s",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ pattern_str, (int)error_position, error_buffer);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sqlite3_result_error(ctx, e2, -1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sqlite3_free(e2);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ c.pattern_str = malloc(pattern_len);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (!c.pattern_str) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sqlite3_result_error(ctx, "malloc: ENOMEM", -1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ pcre2_code_free(c.pattern_code);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ memcpy(c.pattern_str, pattern_str, pattern_len);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ c.pattern_len = pattern_len;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ i = CACHE_SIZE - 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (cache[i].pattern_str) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ free(cache[i].pattern_str);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ assert(cache[i].pattern_code);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ pcre2_code_free(cache[i].pattern_code);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ memmove(cache + 1, cache, i * sizeof(cache_entry));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ cache[0] = c;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ pattern_code = cache[0].pattern_code;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- int rc;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- assert(p);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- rc = pcre_exec(p, e, str, strlen(str), 0, 0, NULL, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- sqlite3_result_int(ctx, rc >= 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int rc;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ pcre2_match_data *match_data;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ assert(pattern_code);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ match_data = pcre2_match_data_create_from_pattern(pattern_code, NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rc = pcre2_match(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ pattern_code, /* the compiled pattern */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ subject_str, /* the subject string */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ subject_len, /* the length of the subject */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0, /* start at offset 0 in the subject */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0, /* default options */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ match_data, /* block for storing the result */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ NULL); /* use default match context */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ assert(rc != 0); // because we have not set match_data
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if(rc >= 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // Normal case because we have not set match_data
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sqlite3_result_int(ctx, 1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ } else if(rc == PCRE2_ERROR_NOMATCH) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sqlite3_result_int(ctx, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ } else { // (rc < 0 and the code is not one of the above)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ PCRE2_UCHAR error_buffer[256];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ pcre2_get_error_message(rc, error_buffer, sizeof(error_buffer));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ char *e2 = sqlite3_mprintf("%s", error_buffer);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sqlite3_result_error(ctx, e2, -1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sqlite3_free(e2);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ pcre2_match_data_free(match_data);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-int sqlite3_extension_init(sqlite3 *db, char **err, const sqlite3_api_routines *api)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- SQLITE_EXTENSION_INIT2(api)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- cache_entry *cache = calloc(CACHE_SIZE, sizeof(cache_entry));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (!cache) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- *err = "calloc: ENOMEM";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- return 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- sqlite3_create_function(db, "REGEXP", 2, SQLITE_UTF8, cache, regexp, NULL, NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- return 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++int sqlite3_extension_init(sqlite3 *db, char **err, const sqlite3_api_routines *api) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ SQLITE_EXTENSION_INIT2(api)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ cache_entry *cache = calloc(CACHE_SIZE, sizeof(cache_entry));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (!cache) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *err = "calloc: ENOMEM";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sqlite3_create_function(db, "REGEXP", 2, SQLITE_UTF8, cache, regexp, NULL, NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/databases/sqlite3-pcre2/files/test.sh b/databases/sqlite3-pcre2/files/test.sh
</span>new file mode 100755
<span style='display:block; white-space:pre;color:#808080;'>index 00000000000..a404e50cf31
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/databases/sqlite3-pcre2/files/test.sh
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,10 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#!/bin/sh
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+prefix="${1}"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+dylib="${2}"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+"${prefix}/bin/sqlite3" >out <<EOF
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.load ${dylib}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+SELECT "asdf" REGEXP "(?i)^A";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+EOF
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+grep 1 out
</span></pre><pre style='margin:0'>
</pre>