public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/coccinelle] rawhide: New version 1.3.3 (RHBZ#2519492)
@ 2026-09-04 10:20 Richard W.M. Jones
0 siblings, 0 replies; only message in thread
From: Richard W.M. Jones @ 2026-09-04 10:20 UTC (permalink / raw)
To: git-commits
A new commit has been pushed.
Repo : rpms/coccinelle
Branch : rawhide
Commit : fdc6f37097ce284b477965033e55a5cea97edb89
Author : Richard W.M. Jones <rjones@redhat.com>
Date : 2026-09-04T11:06:28+01:00
Stats : +9/-9858 in 12 file(s)
URL : https://src.fedoraproject.org/rpms/coccinelle/c/fdc6f37097ce284b477965033e55a5cea97edb89?branch=rawhide
Log:
New version 1.3.3 (RHBZ#2519492)
Drop ocaml-pcre2, egrep patches which are now upstream.
---
diff --git a/.gitignore b/.gitignore
index 31ea387..d6abfd6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
/coccinelle-*.tgz
/coccinelle-*.tar.gz
/coccinelle-1.3.1.tar.bz2
+/coccinelle-1.3.3.tar.bz2
diff --git a/0001-replace-pcre-with-pcre2.patch b/0001-replace-pcre-with-pcre2.patch
deleted file mode 100644
index 886dcf7..0000000
--- a/0001-replace-pcre-with-pcre2.patch
+++ /dev/null
@@ -1,272 +0,0 @@
-From 51f5162da9f773ad4efe4572fa49c4334fd35a11 Mon Sep 17 00:00:00 2001
-From: Olaf Hering <olaf@aepfle.de>
-Date: Wed, 19 Mar 2025 09:14:35 +0100
-Subject: [PATCH 1/9] replace pcre with pcre2
-
-Since pcre is unmaintained, the usage of ocaml-pcre will be replaced
-with ocaml-pcre2. While other regular expession libraries for OCaml
-exists, they are not as feature complete as pcre2 is.
-
-This is the minimal change to use the system ocaml-pcre2. To reduce the
-size of this patch, a separate commit might be required to import
-pcre2-ocaml.git into bundles and use it in the build system.
-
-Signed-off-by: Olaf Hering <olaf@aepfle.de>
-(cherry picked from commit 0af334383425b4de18f1d9a087e38838c75c2c4d)
----
- Makefile | 4 ++--
- Makefile.config.in | 18 +++++++++---------
- Makefile.libs | 18 +++++++++---------
- coccinelle.opam | 2 +-
- configure.ac | 16 ++++++++--------
- globals/regexp_pcre.ml | 6 +++---
- setup/fake-subst.sh | 6 +++---
- 7 files changed, 35 insertions(+), 35 deletions(-)
-
-diff --git a/Makefile b/Makefile
-index 0f6b2313f..6b624e378 100644
---- a/Makefile
-+++ b/Makefile
-@@ -101,7 +101,7 @@ PREFIX_spgen := tools/spgen/source/
- CORE_LIBS := unix str ocamlcommon \
- $(STDCOMPATDIR)/stdcompat \
- $(patsubst %,bytes,$(BYTESDIR)) \
-- $(patsubst %,pcre,$(filter %/pcre.cma,$(LNKLIBS)))
-+ $(patsubst %,pcre2,$(filter %/pcre2.cma,$(LNKLIBS)))
-
- ifeq ($(OCAMLATLEAST50),no)
- CORE_LIBS += bigarray
-@@ -214,7 +214,7 @@ MENHIR_LIB := \
- $(addsuffix /menhirLib$(LIBSUFFIX),$(filter %/menhirLib,$(MAKELIBS)))
- PARMAP_LIB := $(addsuffix /parmap$(LIBSUFFIX),$(filter %/parmap,$(MAKELIBS)))
- PYML_LIB := $(addsuffix /pyml$(LIBSUFFIX),$(filter %/pyml,$(MAKELIBS)))
--PCRE_LIB := $(addsuffix /pcre$(LIBSUFFIX),$(filter %/pcre,$(MAKELIBS)))
-+PCRE_LIB := $(addsuffix /pcre2$(LIBSUFFIX),$(filter %/pcre2,$(MAKELIBS)))
- STDCOMPAT_LIB := $(STDCOMPATDIR)/stdcompat$(LIBSUFFIX)
-
- STDCOMPAT_USERS := parsing_c/type_annoter_c cocci parsing_cocci/check_meta \
-diff --git a/Makefile.config.in b/Makefile.config.in
-index dbafa35a5..6bad1a7a6 100644
---- a/Makefile.config.in
-+++ b/Makefile.config.in
-@@ -5,18 +5,18 @@
- VERSION=@PACKAGE_VERSION@
-
- # * for each library $1, add another entry in the same manner
--MAKELIBS=@MAKE_dynlink@ @MAKE_menhirLib@ @MAKE_pyml@ @MAKE_pcre@ \
-+MAKELIBS=@MAKE_dynlink@ @MAKE_menhirLib@ @MAKE_pyml@ @MAKE_pcre2@ \
- @MAKE_parmap@
--LNKLIBS=@MODULES_dynlink@ @MODULES_menhirLib@ @MODULES_pcre@ @MODULES_pyml@ \
-+LNKLIBS=@MODULES_dynlink@ @MODULES_menhirLib@ @MODULES_pcre2@ @MODULES_pyml@ \
- @MODULES_parmap@
- OPTLNKLIBS=@MODULESOPT_dynlink@ @MODULESOPT_menhirLib@ @MODULESOPT_pyml@ \
-- @MODULESOPT_pcre@ @MODULESOPT_parmap@
--INCLIBS=@PATH_dynlink@ @PATH_menhirLib@ @PATH_pyml@ @PATH_pcre@ \
-+ @MODULESOPT_pcre2@ @MODULESOPT_parmap@
-+INCLIBS=@PATH_dynlink@ @PATH_menhirLib@ @PATH_pyml@ @PATH_pcre2@ \
- @PATH_parmap@
--FLAGSLIBS=@FLAGS_dynlink@ @FLAGS_menhirLib@ @FLAGS_pyml@ @FLAGS_pcre@ \
-+FLAGSLIBS=@FLAGS_dynlink@ @FLAGS_menhirLib@ @FLAGS_pyml@ @FLAGS_pcre2@ \
- @FLAGS_parmap@
- OPTFLAGSLIBS=@OPTFLAGS_dynlink@ @OPTFLAGS_menhirLib@ @OPTFLAGS_pyml@ \
-- @OPTFLAGS_pcre@ @OPTFLAGS_parmap@
-+ @OPTFLAGS_pcre2@ @OPTFLAGS_parmap@
- # * end of library variables
-
- # system packages inc libs
-@@ -106,7 +106,7 @@ METAINFO_DIR=@METAINFO_DIR@
-
- # selected libraries
- FEATURE_menhirLib=@FEATURE_menhirLib@
--FEATURE_pcre=@FEATURE_pcre@
-+FEATURE_pcre=@FEATURE_pcre2@
-
- # Features
- FEATURE_PYTHON=@FEATURE_PYTHON@
-@@ -114,7 +114,7 @@ FEATURE_OCAML=@FEATURE_OCAML@
- NO_OCAMLFIND=@SUBSTITUTED_OCAMLFIND@
-
- # Include paths
--PCREDIR=@PATH_pcre@
-+PCREDIR=@PATH_pcre2@
- PARMAPDIR=@PATH_parmap@
- PYMLDIR=@PATH_pyml@
- MENHIRDIR=@PATH_menhirLib@
-@@ -129,4 +129,4 @@ REGEXP_FILE=@REGEXP_FILE@
-
- MENHIR_FLAGS=@DEFAULT_MENHIR_FLAGS@
-
--OCAMLATLEAST50=@OCAMLATLEAST50@
-\ No newline at end of file
-+OCAMLATLEAST50=@OCAMLATLEAST50@
-diff --git a/Makefile.libs b/Makefile.libs
-index 96e05d26f..ed6ce302f 100644
---- a/Makefile.libs
-+++ b/Makefile.libs
-@@ -36,15 +36,15 @@ OPTFLAGS_pyml = $(CFLAGS_pyml:%=-ccopt %) -cclib -lpyml_stubs
-
- # pcre library
- # Note: see the comment of the pycaml library about the double appearance of the stubs library.
--LOCAL_pcre = $(BYTESDIR:=/bytes.cma) $(PCREDIR)/pcre.cma
--LOCALOPT_pcre = $(BYTESDIR:=/bytes.cmxa) $(PCREDIR)/pcre.cmxa
--GLOBAL_pcre = $(BYTESDIR:=/bytes.cma) $(PCREDIR)/pcre.cma
--GLOBALOPT_pcre = $(BYTESDIR:=/bytes.cmxa) $(PCREDIR)/pcre.cmxa
--FLAGS_pcre = \
-- $(PCRE_LIBS:%=-ccopt %) -cclib -L$(PCREDIR) -dllib -lpcre_stubs \
-- -cclib -lpcre_stubs
--OPTFLAGS_pcre = \
-- $(PCRE_LIBS:%=-ccopt %) -cclib -L$(PCREDIR) -cclib -lpcre_stubs
-+LOCAL_pcre2 = $(BYTESDIR:=/bytes.cma) $(PCREDIR)/pcre2.cma
-+LOCALOPT_pcre2 = $(BYTESDIR:=/bytes.cmxa) $(PCREDIR)/pcre2.cmxa
-+GLOBAL_pcre2 = $(BYTESDIR:=/bytes.cma) $(PCREDIR)/pcre2.cma
-+GLOBALOPT_pcre2 = $(BYTESDIR:=/bytes.cmxa) $(PCREDIR)/pcre2.cmxa
-+FLAGS_pcre2 = \
-+ $(PCRE_LIBS:%=-ccopt %) -cclib -L$(PCREDIR) -dllib -lpcre2_stubs \
-+ -cclib -lpcre2_stubs
-+OPTFLAGS_pcre2 = \
-+ $(PCRE_LIBS:%=-ccopt %) -cclib -L$(PCREDIR) -cclib -lpcre2_stubs
-
- # dynlink library
- LOCAL_dynlink =
-diff --git a/coccinelle.opam b/coccinelle.opam
-index ce7485c7a..c07ebce0d 100644
---- a/coccinelle.opam
-+++ b/coccinelle.opam
-@@ -18,7 +18,7 @@ depends: [
- "ocaml"
- "menhir"
- "ocamlfind"
-- "pcre"
-+ "pcre2"
- "stdcompat"
- "pyml" { >= "20171117" }
- "conf-pkg-config"
-diff --git a/configure.ac b/configure.ac
-index 9106bc704..cd9005a87 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -144,7 +144,7 @@ dnl add a line for each package that is
- dnl configured via AC_CHECK_COCCI_EXTPKG
- dnl or AC_REQ_COCCI_EXTPKG
- AC_COCCI_INIT_PKG_EMPTY([dynlink])
--AC_COCCI_INIT_PKG_EMPTY([pcre])
-+AC_COCCI_INIT_PKG_EMPTY([pcre2])
- AC_COCCI_INIT_PKG_EMPTY([bytes]) dnl for recent versions of pcre on old OCaml
- AC_COCCI_INIT_PKG_EMPTY([pyml])
- AC_COCCI_INIT_PKG_EMPTY([stdcompat])
-@@ -368,18 +368,18 @@ dnl OCAML_PKG_pcre: if "local" use str package
- AC_ARG_ENABLE([pcre-syntax], AS_HELP_STRING([--enable-pcre-syntax], [enable pcre regular expression syntax (default: auto)]))
- AS_IF([test "x$enable_pcre_syntax" != "xno"],
- [dnl
-- PKG_CHECK_MODULES([PCRE], [libpcre],[AC_SUBST([HAVE_PCRE],[yes])],[AC_SUBST([HAVE_PCRE],[no])])
-+ PKG_CHECK_MODULES([PCRE], [libpcre2-8],[AC_SUBST([HAVE_PCRE],[yes])],[AC_SUBST([HAVE_PCRE],[no])])
- AS_IF([test -z "$enable_pcre_syntax" -a "x$HAVE_PCRE" != xyes],
- [dnl
- AC_SUBST([enable_pcre_syntax], [no])
- ],
- [dnl
- AS_IF([test "x$enable_pcre" = "xno"], [AC_SUBST([enable_pcre], [local])])
-- AC_CHECK_COCCI_EXTPKG([pcre]) dnl will set $enable_pcre to 'yes', 'no', or 'local'
-+ AC_CHECK_COCCI_EXTPKG([pcre2]) dnl will set $enable_pcre to 'yes', 'no', or 'local'
- AS_IF([test "x$enable_pcre" = "xyes"],
- [dnl
- AC_MSG_CHECKING([if pcre depends on bytes])
-- AS_IF([test "x`$OCAMLFIND query -r -format '%p' pcre 2>/dev/null | grep bytes`" = "xbytes"],
-+ AS_IF([test "x`$OCAMLFIND query -r -format '%p' pcre2 2>/dev/null | grep bytes`" = "xbytes"],
- [dnl
- AC_MSG_RESULT([yes])
- AC_MSG_CHECKING([if bytes is an actual module])
-@@ -406,14 +406,14 @@ AS_IF([test "x$enable_pcre_syntax" != xno],
- AC_MSG_NOTICE([support for pcre syntax is enabled])
- ],
- [dnl
-- AC_MSG_ERROR([the pcre feature is enabled but the pkg-config libpcre library is not found])
-+ AC_MSG_ERROR([the pcre feature is enabled but the pkg-config libpcre2-8 library is not found])
- ])
-
- AC_SUBST([REGEXP_MODULE], [Regexp_pcre])
- AC_SUBST([REGEXP_FILE], [regexp_pcre.ml])
- ],
- [dnl
-- AC_COCCI_INIT_PKG_EMPTY([pcre])
-+ AC_COCCI_INIT_PKG_EMPTY([pcre2])
- AC_SUBST([REGEXP_MODULE], [Regexp_str])
- AC_SUBST([REGEXP_FILE], [regexp_str.ml])
- ])
-@@ -570,7 +570,7 @@ AS_IF([test "$MAKE_stdcompat"],
- AS_IF([test "$MAKE_parmap"],
- AC_CONFIG_SUBDIRS(bundles/parmap))
-
--AS_IF([test "$MAKE_pcre"],
-+AS_IF([test "$MAKE_pcre2"],
- [AS_IF([test "x$OCAMLATLEAST4030" = xno ],
- [AC_SUBST([CAMLnoreturn_start], [])
- AC_SUBST([CAMLnoreturn_end], [])],
-@@ -632,7 +632,7 @@ python scripting: $enable_python (overridable with --enable-python)
-
- pcre regexes: $enable_pcre_syntax (overridable with --enable-pcre-syntax)
- pcre module: $enable_pcre (for local package use --disable-pcre)
--pcre library: $HAVE_PCRE (requires the libpcre-ocaml-dev package)
-+pcre library: $HAVE_PCRE (requires the libpcre2-ocaml-dev package)
-
- optimized spatch: $enable_opt (overridable with --disable-opt)
-
-diff --git a/globals/regexp_pcre.ml b/globals/regexp_pcre.ml
-index d09f8528f..93073758f 100644
---- a/globals/regexp_pcre.ml
-+++ b/globals/regexp_pcre.ml
-@@ -5,7 +5,7 @@
- *)
-
- type regexp =
-- Pcre of int (* Pcre.regexp *)
-+ Pcre of int (* Pcre2.regexp *)
- | Str of Str.regexp
-
- (* A table is used because PCRE regular expressions are not comparable.
-@@ -26,7 +26,7 @@ let regexp string =
- begin
- let c = !pcre_ctr in
- pcre_ctr := !pcre_ctr + 1;
-- Hashtbl.add pcre_table c (Pcre.regexp string);
-+ Hashtbl.add pcre_table c (Pcre2.regexp string);
- Pcre c
- end
- else Str (Str.regexp string)
-@@ -35,7 +35,7 @@ let string_match regexp string =
- match regexp with
- Pcre regexp ->
- let regexp = Hashtbl.find pcre_table regexp in
-- Pcre.pmatch ~rex:regexp string
-+ Pcre2.pmatch ~rex:regexp string
- | Str regexp ->
- try
- ignore(Str.search_forward regexp string 0);
-diff --git a/setup/fake-subst.sh b/setup/fake-subst.sh
-index eb999d3ec..2aa2a2702 100755
---- a/setup/fake-subst.sh
-+++ b/setup/fake-subst.sh
-@@ -19,7 +19,7 @@ set -e
- # the next lines in the file.
-
- # the replies file assumes that the
--# libpcre and python libraries are installed, and
-+# libpcre2 and python libraries are installed, and
- # that none of the optional ocaml libraries are
- # installed.
-
-@@ -102,9 +102,9 @@ pythonlibs() {
- echo "-L${prefix}/lib -lpython${version}"
- }
-
--# succeeds only if "/usr/include/pcre.h" exists
-+# succeeds only if "/usr/include/pcre2.h" exists
- checkpcre() {
-- test -f /usr/include/pcre.h
-+ test -f /usr/include/pcre2.h
- }
-
- # iterate through pattern-response pairs
---
-2.52.0
-
diff --git a/0002-use-pcre2-instead-of-pcre-in-some-more-places.patch b/0002-use-pcre2-instead-of-pcre-in-some-more-places.patch
deleted file mode 100644
index a40d2db..0000000
--- a/0002-use-pcre2-instead-of-pcre-in-some-more-places.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From 321f6c1317d53c3263a4e0f35d2a43f2ab85f56b Mon Sep 17 00:00:00 2001
-From: Victor Gambier <victor.gambier@inria.fr>
-Date: Wed, 17 Dec 2025 13:28:06 +0100
-Subject: [PATCH 2/9] use pcre2 instead of pcre in some more places
-
-(cherry picked from commit fa062fb3660b1237d32d27fb5027cb68f4c5aae1)
----
- Makefile | 12 ++++++------
- 1 file changed, 6 insertions(+), 6 deletions(-)
-
-diff --git a/Makefile b/Makefile
-index 6b624e378..cddb81ce6 100644
---- a/Makefile
-+++ b/Makefile
-@@ -121,7 +121,7 @@ LIBRARIES_spatch := $(LIBRARIES)
-
- LIBRARIES_spgen := $(CORE_LIBRARIES)
-
--CORE_BUNDLES=stdcompat menhirLib pcre
-+CORE_BUNDLES=stdcompat menhirLib pcre2
-
- ALL_BUNDLES=$(CORE_BUNDLES) parmap pyml
-
-@@ -319,8 +319,8 @@ install-spatch : spatch$(TOOLS_SUFFIX)
- $(INSTALL_PROGRAM) bundles/pyml/dllpyml_stubs.so \
- $(DESTDIR)$(LIBDIR); \
- fi
-- if test -f bundles/pcre/dllpcre_stubs.so; then \
-- $(INSTALL_PROGRAM) bundles/pcre/dllpcre_stubs.so \
-+ if test -f bundles/pcre2/dllpcre2_stubs.so; then \
-+ $(INSTALL_PROGRAM) bundles/pcre2/dllpcre2_stubs.so \
- $(DESTDIR)$(LIBDIR); \
- fi
- $(INSTALL_PROGRAM) spatch$(TOOLS_SUFFIX) $(DESTDIR)$(BINDIR)/spatch
-@@ -521,11 +521,11 @@ endif
- ifneq ($(PCRE_LIB),)
- ifeq ($(NATIVE),yes)
- $(PCRE_LIB): $(STDCOMPAT_LIB)
-- $(MAKE) -C bundles/pcre all
-- $(MAKE) -C bundles/pcre all.opt
-+ $(MAKE) -C bundles/pcre2 all
-+ $(MAKE) -C bundles/pcre2 all.opt
- else
- $(PCRE_LIB): $(STDCOMPAT_LIB)
-- $(MAKE) -C bundles/pcre all
-+ $(MAKE) -C bundles/pcre2 all
- endif
- endif
-
---
-2.52.0
-
diff --git a/0003-replace-pcre-with-pcre2-in-install.txt-instructions.patch b/0003-replace-pcre-with-pcre2-in-install.txt-instructions.patch
deleted file mode 100644
index 78d46c4..0000000
--- a/0003-replace-pcre-with-pcre2-in-install.txt-instructions.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From d35f8b08de850f591408a0f6cdd5de25f1751947 Mon Sep 17 00:00:00 2001
-From: Victor Gambier <victor.gambier@inria.fr>
-Date: Wed, 17 Dec 2025 11:39:12 +0100
-Subject: [PATCH 3/9] replace pcre with pcre2 in install.txt instructions
-
-(cherry picked from commit 0facd403f168aabe21ae19b0f0d9491a36271b4b)
----
- install.txt | 20 ++++++++++----------
- 1 file changed, 10 insertions(+), 10 deletions(-)
-
-diff --git a/install.txt b/install.txt
-index 0ae9a3889..13aee9ae7 100644
---- a/install.txt
-+++ b/install.txt
-@@ -30,14 +30,14 @@ On Debian/Ubuntu, install the following packages:
- If you do not install libparmap-ocaml-dev, then you will automatically use
- the bundle instead. However, if you used opam to switch to a different
- version of OCaml, you must uninstall libparmap-ocaml-dev / libparmap-ocaml.
-- - libpcre-ocaml-dev (optional, for PCRE support, bundled)
-- If you do not install libpcre-ocaml-dev, then you will automatically use
-+ - libpcre2-ocaml-dev (optional, for PCRE support, bundled)
-+ If you do not install libpcre2-ocaml-dev, then you will automatically use
- the bundle instead. However, in order for the bundle to work, you also
- need:
-- - libpcre3-dev (optional, not bundled)
-+ - libpcre2-dev (optional, not bundled)
- Additionally, if you used opam to switch to a different version of OCaml
-- and want PCRE support, then make sure you have libpcre-ocaml-dev /
-- libpcre-ocaml uninstalled and libpcre3-dev installed, otherwise Coccinelle
-+ and want PCRE support, then make sure you have libpcre2-ocaml-dev /
-+ libpcre2-ocaml uninstalled and libpcre2-dev installed, otherwise Coccinelle
- will not compile.
-
- On Fedora, install the following packages:
-@@ -49,16 +49,16 @@ On Fedora, install the following packages:
- - ocaml-findlib-devel
- - ocaml-ocamldoc
- - ocaml-menhir (optional, bundled)
-- - ocaml-pcre-devel (optional, bundled)
-+ - ocaml-pcre2-devel (optional, bundled)
- Note: if you used opam to switch to a different version of OCaml,
-- installing ocaml-pcre-devel will make compilation impossible. Additionally,
-+ installing ocaml-pcre2-devel will make compilation impossible. Additionally,
- PCRE support and OCaml scripting will be impossible.
- If you want Python scripting: Coccinelle is not compatible with Python 3.13,
- which is the default on Fedora as of 2024-12-19. Consider switching to Python
- 3.12, for example.
-
- On Arch Linux, install the following packages:
--$ pacman -Syu pkg-config ocaml ocaml-findlib autoconf automake pcre make
-+$ pacman -Syu pkg-config ocaml ocaml-findlib autoconf automake pcre2 make
- as well as the C compiler of your choice.
- Note: if you used opam to switch to a different version of OCaml, OCaml
- scripting will be impossible.
-@@ -70,12 +70,12 @@ bundles):
- dev-build/libtool
- dev-lang/ocaml
- dev-lang/python
-- dev-libs/libpcre
-+ dev-libs/libpcre2
- dev-ml/camlp4
- dev-ml/findlib
- dev-ml/menhir
- dev-ml/parmap
-- dev-ml/pcre-ocaml
-+ dev-ml/pcre2-ocaml
- dev-ml/stdcompat
- You may also need:
- dev-ml/sexplib
---
-2.52.0
-
diff --git a/0004-replace-pcre-bundle-with-pcre2-bundle.patch b/0004-replace-pcre-bundle-with-pcre2-bundle.patch
deleted file mode 100644
index c49a587..0000000
--- a/0004-replace-pcre-bundle-with-pcre2-bundle.patch
+++ /dev/null
@@ -1,9235 +0,0 @@
-From bd1adc7faf90939e796ca053b90f7d45da2cbd5c Mon Sep 17 00:00:00 2001
-From: Victor Gambier <victor.gambier@inria.fr>
-Date: Wed, 14 Jan 2026 12:03:48 +0100
-Subject: [PATCH 4/9] replace pcre bundle with pcre2 bundle
-
-Source for pcre2 code:
-https://github.com/camlp5/pcre2-ocaml/tree/4c932fcb4d9d27a077d02369196ab3f0a5774362
-
-(cherry picked from commit d1a67eab7aa4a10e54a15ff515173aae76b3b3d7)
----
- bundles/pcre/.gitignore | 4 -
- bundles/pcre/bytes_compat.ml | 5 -
- bundles/pcre/pcre-ocaml/CHANGES.md | 29 -
- bundles/pcre/pcre-ocaml/Makefile | 10 -
- bundles/pcre/pcre-ocaml/README.md | 110 --
- bundles/pcre/pcre-ocaml/dune | 4 -
- bundles/pcre/pcre-ocaml/dune-project | 2 -
- bundles/pcre/pcre-ocaml/examples/Makefile | 9 -
- bundles/pcre/pcre-ocaml/examples/README.md | 28 -
- bundles/pcre/pcre-ocaml/examples/dune | 4 -
- bundles/pcre/pcre-ocaml/examples/pcregrep.ml | 113 --
- bundles/pcre/pcre-ocaml/examples/subst.ml | 54 -
- bundles/pcre/pcre-ocaml/pcre.opam | 27 -
- .../pcre/pcre-ocaml/pre-v7.3.0-CHANGES.txt | 698 ----------
- bundles/pcre/pcre-ocaml/src/.gitignore | 1 -
- bundles/pcre/pcre-ocaml/src/Makefile | 9 -
- .../pcre/pcre-ocaml/src/config/discover.ml | 15 -
- bundles/pcre/pcre-ocaml/src/config/dune | 4 -
- bundles/pcre/pcre-ocaml/src/dune | 16 -
- bundles/pcre/pcre-ocaml/src/pcre.ml.in | 1055 --------------
- bundles/pcre/pcre-ocaml/src/pcre.mli | 930 -------------
- bundles/pcre/pcre-ocaml/src/pcre_stubs.c.in | 862 ------------
- .../pcre2-ocaml}/.gitignore | 0
- bundles/pcre2/pcre2-ocaml/CHANGELOG.md | 69 +
- .../pcre2-ocaml}/LICENSE.md | 4 +-
- bundles/pcre2/pcre2-ocaml/Makefile | 15 +
- bundles/pcre2/pcre2-ocaml/README.md | 138 ++
- bundles/pcre2/pcre2-ocaml/dune | 9 +
- bundles/pcre2/pcre2-ocaml/dune-project | 32 +
- bundles/pcre2/pcre2-ocaml/examples/Makefile | 9 +
- bundles/pcre2/pcre2-ocaml/examples/README.md | 48 +
- .../pcre2-ocaml}/examples/cloc.ml | 2 +-
- .../pcre2-ocaml}/examples/count_hash.ml | 6 +-
- .../pcre2/pcre2-ocaml/examples/dfa_restart.ml | 40 +
- bundles/pcre2/pcre2-ocaml/examples/dune | 4 +
- .../pcre2/pcre2-ocaml/examples/pcre2grep.ml | 128 ++
- bundles/pcre2/pcre2-ocaml/examples/subst.ml | 57 +
- bundles/pcre2/pcre2-ocaml/lib/Makefile | 15 +
- .../pcre2-ocaml/lib}/config/Makefile | 0
- .../pcre2/pcre2-ocaml/lib/config/discover.ml | 14 +
- bundles/pcre2/pcre2-ocaml/lib/config/dune | 4 +
- bundles/pcre2/pcre2-ocaml/lib/dune | 18 +
- bundles/pcre2/pcre2-ocaml/lib/pcre2.ml | 1231 +++++++++++++++++
- bundles/pcre2/pcre2-ocaml/lib/pcre2.mli | 1068 ++++++++++++++
- bundles/pcre2/pcre2-ocaml/lib/pcre2_stubs.c | 807 +++++++++++
- .../pcre2/pcre2-ocaml/pa_ppx_test/Makefile | 11 +
- .../pcre2-ocaml/pa_ppx_test/pcre2_tests.ml | 249 ++++
- bundles/pcre2/pcre2-ocaml/pcre2.opam | 37 +
- bundles/pcre2/pcre2-ocaml/test/dune | 14 +
- .../pcre2/pcre2-ocaml/test/old_pcre2_tests.ml | 24 +
- bundles/pcre2/pcre2-ocaml/test/pcre2_tests.ml | 746 ++++++++++
- 51 files changed, 4794 insertions(+), 3994 deletions(-)
- delete mode 100644 bundles/pcre/.gitignore
- delete mode 100644 bundles/pcre/bytes_compat.ml
- delete mode 100644 bundles/pcre/pcre-ocaml/CHANGES.md
- delete mode 100644 bundles/pcre/pcre-ocaml/Makefile
- delete mode 100644 bundles/pcre/pcre-ocaml/README.md
- delete mode 100644 bundles/pcre/pcre-ocaml/dune
- delete mode 100644 bundles/pcre/pcre-ocaml/dune-project
- delete mode 100644 bundles/pcre/pcre-ocaml/examples/Makefile
- delete mode 100644 bundles/pcre/pcre-ocaml/examples/README.md
- delete mode 100644 bundles/pcre/pcre-ocaml/examples/dune
- delete mode 100644 bundles/pcre/pcre-ocaml/examples/pcregrep.ml
- delete mode 100644 bundles/pcre/pcre-ocaml/examples/subst.ml
- delete mode 100644 bundles/pcre/pcre-ocaml/pcre.opam
- delete mode 100644 bundles/pcre/pcre-ocaml/pre-v7.3.0-CHANGES.txt
- delete mode 100644 bundles/pcre/pcre-ocaml/src/.gitignore
- delete mode 100644 bundles/pcre/pcre-ocaml/src/Makefile
- delete mode 100644 bundles/pcre/pcre-ocaml/src/config/discover.ml
- delete mode 100644 bundles/pcre/pcre-ocaml/src/config/dune
- delete mode 100644 bundles/pcre/pcre-ocaml/src/dune
- delete mode 100644 bundles/pcre/pcre-ocaml/src/pcre.ml.in
- delete mode 100644 bundles/pcre/pcre-ocaml/src/pcre.mli
- delete mode 100644 bundles/pcre/pcre-ocaml/src/pcre_stubs.c.in
- rename bundles/{pcre/pcre-ocaml => pcre2/pcre2-ocaml}/.gitignore (100%)
- create mode 100644 bundles/pcre2/pcre2-ocaml/CHANGELOG.md
- rename bundles/{pcre/pcre-ocaml => pcre2/pcre2-ocaml}/LICENSE.md (99%)
- create mode 100644 bundles/pcre2/pcre2-ocaml/Makefile
- create mode 100644 bundles/pcre2/pcre2-ocaml/README.md
- create mode 100644 bundles/pcre2/pcre2-ocaml/dune
- create mode 100644 bundles/pcre2/pcre2-ocaml/dune-project
- create mode 100644 bundles/pcre2/pcre2-ocaml/examples/Makefile
- create mode 100644 bundles/pcre2/pcre2-ocaml/examples/README.md
- rename bundles/{pcre/pcre-ocaml => pcre2/pcre2-ocaml}/examples/cloc.ml (97%)
- rename bundles/{pcre/pcre-ocaml => pcre2/pcre2-ocaml}/examples/count_hash.ml (62%)
- create mode 100644 bundles/pcre2/pcre2-ocaml/examples/dfa_restart.ml
- create mode 100644 bundles/pcre2/pcre2-ocaml/examples/dune
- create mode 100644 bundles/pcre2/pcre2-ocaml/examples/pcre2grep.ml
- create mode 100644 bundles/pcre2/pcre2-ocaml/examples/subst.ml
- create mode 100644 bundles/pcre2/pcre2-ocaml/lib/Makefile
- rename bundles/{pcre/pcre-ocaml/src => pcre2/pcre2-ocaml/lib}/config/Makefile (100%)
- create mode 100644 bundles/pcre2/pcre2-ocaml/lib/config/discover.ml
- create mode 100644 bundles/pcre2/pcre2-ocaml/lib/config/dune
- create mode 100644 bundles/pcre2/pcre2-ocaml/lib/dune
- create mode 100644 bundles/pcre2/pcre2-ocaml/lib/pcre2.ml
- create mode 100644 bundles/pcre2/pcre2-ocaml/lib/pcre2.mli
- create mode 100644 bundles/pcre2/pcre2-ocaml/lib/pcre2_stubs.c
- create mode 100644 bundles/pcre2/pcre2-ocaml/pa_ppx_test/Makefile
- create mode 100644 bundles/pcre2/pcre2-ocaml/pa_ppx_test/pcre2_tests.ml
- create mode 100644 bundles/pcre2/pcre2-ocaml/pcre2.opam
- create mode 100644 bundles/pcre2/pcre2-ocaml/test/dune
- create mode 100644 bundles/pcre2/pcre2-ocaml/test/old_pcre2_tests.ml
- create mode 100644 bundles/pcre2/pcre2-ocaml/test/pcre2_tests.ml
-
-diff --git a/bundles/pcre/.gitignore b/bundles/pcre/.gitignore
-deleted file mode 100644
-index 2388919a1..000000000
---- a/bundles/pcre/.gitignore
-+++ /dev/null
-@@ -1,4 +0,0 @@
--META
--mmottl-pcre-ocaml-258b72c
--.prepare
--pcre-ocaml/src/pcre.ml
-\ No newline at end of file
-diff --git a/bundles/pcre/bytes_compat.ml b/bundles/pcre/bytes_compat.ml
-deleted file mode 100644
-index fd7c2c8b9..000000000
---- a/bundles/pcre/bytes_compat.ml
-+++ /dev/null
-@@ -1,5 +0,0 @@
--include String
--
--external unsafe_to_string: t -> string = "%identity"
--
--external unsafe_of_string: string -> t = "%identity"
-diff --git a/bundles/pcre/pcre-ocaml/CHANGES.md b/bundles/pcre/pcre-ocaml/CHANGES.md
-deleted file mode 100644
-index 0b0f5ba92..000000000
---- a/bundles/pcre/pcre-ocaml/CHANGES.md
-+++ /dev/null
-@@ -1,29 +0,0 @@
--### 7.3.5 (2018-10-25)
--
-- * Switched to dune, dune-release, and OPAM 2.0
--
--
--### 7.3.4 (2017-11-22)
--
-- * Improved finalization of regular expressions and tables for better
-- performance
--
--
--### 7.3.3 (2017-10-17)
--
-- * Fixed external declaration bug in internal regexp compile function
--
--
--### 7.3.2 (2017-10-10)
--
-- * Improved compatibility with MSVC
--
--
--### 7.3.1 (2017-10-08)
--
-- * Used untagged integers when declaring external functions
--
--
--### 7.3.0 (2017-07-27)
--
-- * Switched to jbuilder and topkg
-diff --git a/bundles/pcre/pcre-ocaml/Makefile b/bundles/pcre/pcre-ocaml/Makefile
-deleted file mode 100644
-index 8a5fb073c..000000000
---- a/bundles/pcre/pcre-ocaml/Makefile
-+++ /dev/null
-@@ -1,10 +0,0 @@
--.PHONY: all clean doc
--
--all:
-- dune build @install
--
--clean:
-- dune clean
--
--doc:
-- dune build @doc
-diff --git a/bundles/pcre/pcre-ocaml/README.md b/bundles/pcre/pcre-ocaml/README.md
-deleted file mode 100644
-index b11e04116..000000000
---- a/bundles/pcre/pcre-ocaml/README.md
-+++ /dev/null
-@@ -1,110 +0,0 @@
--## PCRE-OCaml - Perl Compatibility Regular Expressions for OCaml
--
--This [OCaml](http://www.ocaml.org)-library interfaces the C-library
--[PCRE](http://www.pcre.org) (Perl-compatibility Regular Expressions). It can be
--used for string matching with "PERL"-style regular expressions.
--
--### Features
--
--PCRE-OCaml offers the following functionality for operating on strings:
--
-- * Searching for patterns
-- * Extracting subpatterns
-- * Splitting strings according to patterns
-- * Pattern substitution
--
--Other reasons to use PCRE-OCaml:
--
-- * The PCRE-library by Philip Hazel has been under development for many
-- years and is fairly advanced and stable. It implements just about all
-- of the functionality that can be found in PERL regular expressions.
-- The higher-level functions written in OCaml (split, replace, etc.),
-- too, are compatible with the corresponding PERL-functions to the extent
-- that OCaml allows. Most people find the syntax of PERL-style regular
-- expressions more straightforward and powerful than the Emacs-style regular
-- expressions used in the `Str`-module in the standard OCaml distribution.
--
-- * PCRE-OCaml is reentrant and thus thread-safe, which is not the case
-- for the `Str`-module in the OCaml standard library. Using reentrant
-- libraries also means more convenience for programmers. They do not
-- have to reason about states in which the library might be in.
--
-- * The high-level functions for replacement and substitution, which are all
-- implemented in OCaml, are much faster than the ones in the `Str`-module.
-- In fact, when compiled to native code, they even seem to be significantly
-- faster than those found in PERL (PERL is written in C).
--
-- * You can rely on the data returned being unique. In other terms: if
-- the result of a function is a string, you can safely use destructive
-- updates on it without having to fear side effects.
--
-- * The interface to the library makes use of labels and default arguments
-- to give you a high degree of programming comfort.
--
--### Usage
--
--Please consult the [API](https://mmottl.github.io/pcre-ocaml/api/pcre)
--for details.
--
--A general concept the user may need to understand is that most functions
--allow for two different kinds of flags:
--
-- 1. "Convenience"-flags that make for readable and concise code, but which
-- need to be translated to an internal representation on each call.
-- Example:
--
-- ```ocaml
-- let rex = Pcre.regexp ~flags:[`ANCHORED; `CASELESS] "some pattern" in
-- (* ... *)
-- ```
--
-- This makes it easy to pass flags on the fly. They will be translated to
-- the internal format automatically. However, if this happens to be in a
-- loop, this translation will occur on each iteration. If you really need
-- to save as much performance as possible, you should use the next approach.
--
-- 2. "Internal" flags that need to be defined and translated from
-- "convenience"-flags before function calls, but which allow for optimum
-- performance in loops. Example:
--
-- ```ocaml
-- let iflags = Pcre.cflags [`ANCHORED; `CASELESS] in
-- for i = 1 to 1000 do
-- let rex = Pcre.regexp ~iflags "some pattern constructed at runtime" in
-- (* ... *)
-- done
-- ```
--
-- Factoring out the translation of flags for regular expressions may
-- save some cycles, but don't expect too much. You can save more CPU
-- time when lifting the creation of regular expressions out of loops.
-- Example for what not to do:
--
-- ```ocaml
-- for i = 1 to 1000 do
-- let chunks = Pcre.split ~pat:"[ \t]+" "foo bar" in
-- (* ... *)
-- done
-- ```
--
-- Better:
--
-- ```ocaml
-- let rex = Pcre.regexp "[ \t]+" in
-- for i = 1 to 1000 do
-- let chunks = Pcre.split ~rex "foo bar" in
-- (* ... *)
-- done
-- ```
--
--The provided functions use optional arguments with intuitive defaults. For
--example, the `Pcre.split`-function will assume whitespace as pattern. The
--`examples`-directory contains a few example applications demonstrating the
--functionality of PCRE-OCaml.
--
--### Contact Information and Contributing
--
--Please submit bugs reports, feature requests, contributions and similar to
--the [GitHub issue tracker](https://github.com/mmottl/pcre-ocaml/issues).
--
--Up-to-date information is available at: <https://mmottl.github.io/pcre-ocaml>
-diff --git a/bundles/pcre/pcre-ocaml/dune b/bundles/pcre/pcre-ocaml/dune
-deleted file mode 100644
-index 66984ad7e..000000000
---- a/bundles/pcre/pcre-ocaml/dune
-+++ /dev/null
-@@ -1,4 +0,0 @@
--(env
-- (dev (flags (:standard -w -9 -principal)))
-- (release (ocamlopt_flags (:standard -O3)))
--)
-diff --git a/bundles/pcre/pcre-ocaml/dune-project b/bundles/pcre/pcre-ocaml/dune-project
-deleted file mode 100644
-index e14ceb0d1..000000000
---- a/bundles/pcre/pcre-ocaml/dune-project
-+++ /dev/null
-@@ -1,2 +0,0 @@
--(lang dune 1.1)
--(name pcre)
-diff --git a/bundles/pcre/pcre-ocaml/examples/Makefile b/bundles/pcre/pcre-ocaml/examples/Makefile
-deleted file mode 100644
-index 540bc9f8b..000000000
---- a/bundles/pcre/pcre-ocaml/examples/Makefile
-+++ /dev/null
-@@ -1,9 +0,0 @@
--TARGETS = $(addsuffix .bc, cloc count_hash pcregrep subst)
--
--.PHONY: all clean
--
--all:
-- @dune build $(TARGETS)
--
--clean:
-- @dune clean
-diff --git a/bundles/pcre/pcre-ocaml/examples/README.md b/bundles/pcre/pcre-ocaml/examples/README.md
-deleted file mode 100644
-index 1916310b3..000000000
---- a/bundles/pcre/pcre-ocaml/examples/README.md
-+++ /dev/null
-@@ -1,28 +0,0 @@
--## Examples
--
--### cloc
--
--This program reads C-sources from stdin and prints them to stdout with
--comments and empty lines removed. Useful for counting LOCs.
--
--### count_hash
--
--This program reads text from stdin, counts all equal words that are separated by
--whitespace and prints the result to stdout.
--
--### pcregrep
--
--A grep-like program using Perl-compatible regular expressions. Start the
--program with argument `-help` to see what it does!
--
--### subst
--
--Substitutes text in files using Perl-compatible regular expressions and
--substitution patterns. Start the program with argument `-help` to see what it
--does!
--
--Example invocation:
--
--```sh
--subst '([Tt])ermcap' '$1ermCap' < /etc/termcap
--```
-diff --git a/bundles/pcre/pcre-ocaml/examples/dune b/bundles/pcre/pcre-ocaml/examples/dune
-deleted file mode 100644
-index 729c6e4d1..000000000
---- a/bundles/pcre/pcre-ocaml/examples/dune
-+++ /dev/null
-@@ -1,4 +0,0 @@
--(executables
-- (names cloc count_hash pcregrep subst)
-- (libraries pcre)
--)
-diff --git a/bundles/pcre/pcre-ocaml/examples/pcregrep.ml b/bundles/pcre/pcre-ocaml/examples/pcregrep.ml
-deleted file mode 100644
-index 1c31528e5..000000000
---- a/bundles/pcre/pcre-ocaml/examples/pcregrep.ml
-+++ /dev/null
-@@ -1,113 +0,0 @@
--open Pcre
--open Printf
--
--let filenames = ref true
--and filenames_only = ref false
--and count_only = ref false
--and invert = ref false
--and number = ref false
--and silent = ref false
--and whole_lines = ref false
--
--let parse_args () =
-- let ignore_case = ref false
--
-- and pat = ref None
-- and files = ref [] in
--
-- let c = "-c", Arg.Set count_only, "Count lines only."
-- and h = "-h", Arg.Clear filenames,
-- "Suppress printing of filenames when searching multiple files."
-- and i = "-i", Arg.Set ignore_case, "Ignore case."
-- and l = "-l", Arg.Set filenames_only,
-- "Only print names of files containing matching lines (once)."
-- and n = "-n", Arg.Set number,
-- "Precede each line by its line number in the file."
-- and s = "-s", Arg.Set silent,
-- "Display nothing but error messages. Exit status indicates match."
-- and v = "-v", Arg.Set invert,
-- "Invert sense of the match: finds nonmatching lines."
-- and x = "-x", Arg.Set whole_lines,
-- "Force the pattern to be anchored and to match the entire line."
-- and usage =
-- "Usage: pcregrep [options] pattern [file] ...\n\n\
-- Searches files for character patterns.\n"
-- and anon_arg arg =
-- if !pat = None then pat := Some arg
-- else files := arg :: !files in
--
-- let args = [c; h; i; l; n; s; v; x] in
-- Arg.parse args anon_arg usage;
--
-- let flags =
-- let flag_list = if !ignore_case then [`CASELESS] else [] in
-- if !whole_lines then `ANCHORED :: flag_list else flag_list in
--
-- let rex =
-- match !pat with
-- | Some pat -> regexp ~flags pat
-- | None -> eprintf "%s: not enough arguments!\n" Sys.argv.(0);
-- Arg.usage args usage; exit 2 in
-- rex, List.rev !files
--
--let _ =
-- let rex, files = parse_args ()
-- and rfl = rflags [] in
--
-- let _, ovector = make_ovector rex in
--
-- let pcregrep file name =
-- let ret_code = ref 1
-- and linenumber = ref 0
-- and count = ref 0
--
-- and stdin_print_name () =
-- match name with
-- | Some filename -> print_endline filename
-- | None -> print_endline "<stdin>"
--
-- and print_name () =
-- match name with Some name -> printf "%s:" name | None -> () in
--
-- let try_match line =
-- let matched =
-- try
-- unsafe_pcre_exec rfl rex ~pos:0 ~subj_start:0 ~subj:line ovector None;
-- if !whole_lines && ovector.(1) <> String.length line then false
-- else true
-- with Not_found -> false in
--
-- incr linenumber;
--
-- if matched <> !invert then begin
-- if !count_only then incr count
-- else if !filenames_only then begin stdin_print_name (); raise Exit end
-- else if !silent then raise Exit
-- else begin
-- print_name ();
-- if !number then printf "%d:" !linenumber;
-- print_endline line
-- end;
-- ret_code := 0 end in
--
-- try
-- foreach_line ~ic:file try_match;
-- if !count_only then begin
-- print_name ();
-- printf "%d\n" !count end;
-- !ret_code
-- with Exit -> 0 in
--
-- if files = [] then exit (pcregrep stdin None);
--
-- if List.length files = 1 then filenames := false;
-- if !filenames_only then filenames := true;
--
-- let collect ret_code filename =
-- try
-- let file = open_in filename in
-- let frc = pcregrep file (if !filenames then Some filename else None) in
-- close_in file;
-- if frc = 0 && ret_code = 1 then 0 else ret_code
-- with Sys_error msg -> prerr_endline msg; 2 in
-- exit (List.fold_left collect 1 files)
-diff --git a/bundles/pcre/pcre-ocaml/examples/subst.ml b/bundles/pcre/pcre-ocaml/examples/subst.ml
-deleted file mode 100644
-index 24701dda1..000000000
---- a/bundles/pcre/pcre-ocaml/examples/subst.ml
-+++ /dev/null
-@@ -1,54 +0,0 @@
--open Pcre
--
--let parse_args () =
-- let quick = ref false
-- and first = ref false
-- and ignore_case = ref false
-- and offset = ref 0
--
-- and pat = ref None
-- and substr = ref None in
--
-- let q = "-q", Arg.Set quick,
-- "Quick replacement. Interpretes substitution as plain text."
-- and f = "-f", Arg.Set first, "Replace first occurrence in line only."
-- and i = "-i", Arg.Set ignore_case, "Ignore case."
-- and ofs = "-ofs", Arg.Int (fun n -> offset := n),
-- "Start matching at column n."
--
-- and usage =
-- "Usage: subst [-q] [-f] [-i] [-ofs offset] pattern substitution\n\n\
-- Reads lines from standard input and replaces occurrences of\n\
-- the PERL-style regular expression \"pattern\" with \"substitution\",\n\
-- printing the result to standard output.\n\
-- In default mode the contents of \"substitution\" will be interpreted\n\
-- similarly to its equivalent in PERL.\n"
--
-- and anon_arg arg =
-- match !pat, !substr with
-- | None, _ -> pat := Some arg
-- | _, None -> substr := Some arg
-- | _ -> raise (Arg.Bad "too many arguments!") in
--
-- let args = [q; f; i; ofs] in
-- Arg.parse args anon_arg usage;
--
-- let flags = if !ignore_case then [`CASELESS] else [] in
--
-- let rex, sstr =
-- match !pat, !substr with
-- | Some rex, Some sstr -> regexp ~flags rex, sstr
-- | _ -> prerr_endline (Sys.argv.(0) ^ ": not enough arguments!");
-- Arg.usage args usage; exit 1 in
--
-- match !quick, !first with
-- | false, false -> fun s -> replace ~rex ~pos:!offset ~templ:sstr s
-- | true, false -> fun s -> qreplace ~rex ~pos:!offset ~templ:sstr s
-- | false, true -> fun s -> replace_first ~rex ~pos:!offset ~templ:sstr s
-- | true, true -> fun s -> qreplace_first ~rex ~pos:!offset ~templ:sstr s
--
--let _ =
-- let substitute = parse_args () in
-- foreach_line (fun line ->
-- try print_endline (substitute line)
-- with Invalid_argument _ -> print_endline line)
-diff --git a/bundles/pcre/pcre-ocaml/pcre.opam b/bundles/pcre/pcre-ocaml/pcre.opam
-deleted file mode 100644
-index 4ef1e77e9..000000000
---- a/bundles/pcre/pcre-ocaml/pcre.opam
-+++ /dev/null
-@@ -1,27 +0,0 @@
--opam-version: "2.0"
--maintainer: "Markus Mottl <markus.mottl@gmail.com>"
--authors: [ "Markus Mottl <markus.mottl@gmail.com>" ]
--license: "LGPL-2.1+ with OCaml linking exception"
--homepage: "https://mmottl.github.io/pcre-ocaml"
--doc: "https://mmottl.github.io/pcre-ocaml/api"
--dev-repo: "git+https://github.com/mmottl/pcre-ocaml.git"
--bug-reports: "https://github.com/mmottl/pcre-ocaml/issues"
--
--build: [
-- ["dune" "subst"] {pinned}
-- ["dune" "build" "-p" name "-j" jobs]
--]
--
--depends: [
-- "ocaml" {>= "4.04"}
-- "dune" {build & >= "1.4.0"}
-- "conf-libpcre" {build}
-- "base" {build}
-- "base-bytes"
--]
--
--synopsis: "Bindings to the Perl Compatibility Regular Expressions library"
--
--description: """
--pcre-ocaml offers library functions for string pattern matching and
--substitution, similar to the functionality offered by the Perl language."""
-diff --git a/bundles/pcre/pcre-ocaml/pre-v7.3.0-CHANGES.txt b/bundles/pcre/pcre-ocaml/pre-v7.3.0-CHANGES.txt
-deleted file mode 100644
-index 9bc9875f0..000000000
---- a/bundles/pcre/pcre-ocaml/pre-v7.3.0-CHANGES.txt
-+++ /dev/null
-@@ -1,698 +0,0 @@
--2016-02-25: Minor version release v7.2.3:
--
-- Fixed callout bug introduced with v7.2.0.
--
-- Thanks to Raman Varabets for the bug report!
--
--2016-02-23: Fixed linking problem with old versions of PCRE (< 8.20).
--
-- Fixed backward compatibility issue with OCaml <= 3.12.
--
--2016-02-22: Fixed a subgroup matching bug.
--
-- Thanks to Cheng Lou for the bug report!
--
--2015-08-21: Made GC less aggressive reclaiming regexps and chartables.
--
--2014-12-10: Fixed another limit handling bug in the full_split function.
--
--2014-12-02: Fixed a limit handling bug in the full_split function.
--
-- Thanks to Rudi Grinberg <rudi.grinberg@gmail.com> for the report!
--
--2014-10-23: Fixed string handling for new OCaml version 4.02 (String/Bytes
-- modules). Requires new findlib version (>= 1.5).
--
--2014-07-06: Moved to GitHub.
--
--2014-06-04: Multiple bug fixes:
--
-- * Allcation bug when performing callouts
-- * Unprotected root when performing callouts
-- * More portable offset copying in the C-stubs
-- * Fixed a PERL-compatibility bug in the splitting routines
--
-- The bug fixes required a minor API-change in an unsafe function,
-- which is almost surely not directly called by any users.
--
--2012-07-20: Downgraded findlib version requirement to support the Debian
-- testing branch.
--
-- Added --with-pcre-config flag to configure location of PCRE
-- configuration generator.
--
--2012-07-15: New major release version 7.0.0:
--
-- * Upgraded to OCaml 4.00
-- * Switched to Oasis for packaging
-- * Switched to OCamlBuild for the build process
-- * Rewrote README in Markdown
-- * Added stricter compilation flags
-- * Minor bugfixes
--
--2012-01-04: Fixed native code debug build target by updating OCamlMakefile.
--
-- Thanks to Stéphane Glondu <glondu@debian.org> for the patch!
--
--2011-12-15: Fixed a Windows portability bug in the C-bindings.
--
-- Thanks to Evgenii Lepikhin <johnlepikhin@gmail.com> for the patch!
--
--2011-11-09: Updated OCamlMakefile to fix linking order.
--
--2011-01-16: Added support for limit recursion flag.
--
-- Thanks to Delphin Lecucq <Delphin.LECUCQ@3ds.com> for the patch!
--
--2010-10-31: Improved Windows support with MSVC.
--
-- Thanks to Sylvain Le Gall <sylvain@le-gall.net> for the patch!
--
--2010-04-01: Added new function:
--
-- * regexp_or
--
--2009-06-20: Fixed bug in configuration functions that could lead to a segfault.
--
-- Thanks to Gerd Stolpmann <gerd@gerd-stolpmann.de> for the patch!
--
--2009-05-07: Changed API wrt. error handling and thus made a major release.
--
-- Improved behavior in the presence of recursion limit errors.
-- Thanks to Martin Jambon <martinj@mylife.com> for this patch!
--
--2009-04-23: Fixed build problem on MinGW.
--
-- Thanks to Gerd Stolpmann <gerd@gerd-stolpmann.de> for the patch!
--
--2009-03-08: Fixed build problem on Mac OS X with macports.
--
-- Thanks to Ralph Douglass <ralph@grayskies.net> for the
-- initial patch.
--
-- Update OCamlMakefile.
--
-- Improved Godi-distribution.
--
--2008-05-06: Fixed build problem with newer versions of PCRE.
--
--2008-03-14: Synced with Jane Street tree.
--
--2008-01-25: Added new function:
--
-- * names
--
-- This function returns the names of all named substrings in a
-- regular expression.
--
-- Thanks to Benedikt Grundmann <bgrundmann@janestreet.com>
-- for the patch!
--
--2007-07-12: Improved build scripts for Windows.
--
-- Thanks to Christophe Troestler
-- <Christophe.Troestler@umh.ac.be> for the patch!
--
--2007-07-12: Improved documentation for Win32 builds, and added some build
-- scripts usable on Windows.
--
-- Thanks to Christophe Troestler
-- <Christophe.Troestler@umh.ac.be> for this contribution!
--
--2007-04-23: callback_exn -> caml_callback_exn.
--
-- Updated OCamlMakefile.
--
--2006-11-22: Updated OCamlMakefile.
--
--2006-06-11: Updated to pcre-5.0!
--
-- New representation for callbacks: they now take only one
-- argument (a record of the callback data).
--
-- Added partial matching and auto callouts.
--
--2006-01-16: Updated OCamlMakefile.
--
-- Removed a superfluous binding.
--
--2005-08-18: Fixed a small compilation problem on rare platforms by
-- upgrading OCamlMakefile.
--
--2005-06-08: Relaxed license. Fixed copyright headers.
--
--2005-05-31: Fixed some uncleanliness reported by Saffire (FFI-type checker).
--
--2004-09-17: Fixed a bug concerning null patterns in exec_all (extract_all
-- and extract_all_opt are also affected).
--
-- Updated OCamlMakefile.
--
--2004-05-19: Updated Makefile.mingw.
-- Thanks to Jeff Henrikson <jehenrik@yahoo.com> for the patch!
--
-- Updated OCamlMakefile.
--
--2004-04-29: Changed behaviour of "get_substring"!!!
--
-- It now does not return the empty string anymore if an
-- accessed substring was not captured. It raises the exception
-- "Not_found" instead.
--
-- Three new functions:
--
-- * get_opt_substrings
-- * extract_opt
-- * extract_all_opt
--
-- These behave like the functions without "opt", but return
-- "Some substring" if a substring was captured, and "None"
-- otherwise.
--
--2004-04-27: Updated OCamlMakefile.
--
--2004-04-24: Updated OCamlMakefile.
--
--2004-03-28: Changed interface to build-time configuration functions
-- of PCRE.
--
-- Updated OCamlMakefile.
--
--2004-02-21: Added CAMLprim in the C-interface where appropriate.
--
--2004-02-08: Fixed a minor bug concerning returning unit values from C.
--
--2004-01-31: Added pcre_make.win32/Makefile.mingw. Thanks to Jeffrey
-- Henrikson <JEFHEN@SAFECO.com> for this contribution!
--
-- Update OCamlMakefile.
--
--2004-01-13: Updated pcre_make.win32/pcre.h.
--
--2003-12-30: Fixed documentation.
--
--2003-12-21: Updated to pcre-4.5!
--
-- New function:
--
-- * config_stackrecurse
--
-- New exception:
--
-- * BadUTF8Offset
--
-- Updated OCamlMakefile.
--
--2003-12-19: Fixed a small (but probably unnoticable) bug concerning
-- allocation of optional values in the C-stubs.
--
--2003-12-12: Updated OCamlMakefile. Renamed stubs (invisible to users).
--
--2003-11-16: Updated pcre_make.win32/pcre.h to reflect newest PCRE-version.
-- May help Windows users.
--
--2003-10-08: Upgraded to pcre-4.4!
--
-- New flag for compiling patterns: NO_UTF8_CHECK
-- New exception: BadUTF8
--
-- Updated OCamlMakefile.
--
--2003-09-30: Fixed a bug in the documentation.
-- Updated OCamlMakefile.
--
--2003-06-17: Fixed a bug in the documentation.
-- Updated OCamlMakefile.
--
--2003-05-29: Updated to pcre-4.3!
--
-- Major change: callouts are now fully supported! This allows
-- the matching engine call OCaml-code while matching - quite
-- powerful! Please see the interface specification for more
-- information.
--
-- Many small changes (improvements) in C-code. Updated
-- documentation.
--
--2003-04-08: Updated OCamlMakefile. Reformatted documentation.
--
--2003-03-20: Added new function "get_subject". Patched OCamlMakefile.
--
--2003-03-18: Major update: upgraded to pcre-4.1!
--
-- Better UTF8-support.
-- New flag "NO_AUTO_CAPTURE".
--
-- New values:
--
-- * config_utf8
-- * config_newline
-- * config_link_size
-- * config_match_limit
--
-- Renamed all occurrences of "firstchar" to "firstbyte".
--
-- New functions:
--
-- * studysize
-- * namecount
-- * nameentrysize
-- * get_stringnumber
--
-- Updated OCamlMakefile.
--
--2003-01-07: Updated OCamlMakefile to make use of "findlib".
--
-- Added support for UTF-8 character encodings.
--
-- Better installation and documentation for Win32.
--
-- Thanks to Artem Prisyznuk <tema@sit.kiev.ua> for the above
-- patches!
--
--2002-12-14: Fixed a bug concerning zero-sized matches effecting
-- "replace", "qreplace", "substitute_substrings" and
-- "substitute".
--
-- Updated OCamlMakefile.
--
--2002-12-08: Improved documentation of "pcre_exec".
--
--2002-11-24: Fixed a bug in "full_split" concerning matched subgroups.
--
--2002-11-12: Added a new function "extract_all" (see interface
-- documentation).
--
--2002-08-16: Fixed a bug in the "split"-function:
--
-- The Perl-splitting semantics was not completely adhered to:
-- leading whitespace was stripped after the matching process
-- rather than before, which lead to incompatible behaviour
-- when a maximum bound was used.
--
-- Thanks to Yutaka Oiwa <oiwa@yl.is.s.u-tokyo.ac.jp> for the
-- bug report!
--
-- Updated OCamlMakefile.
--
--2002-07-31: Fixed a bug in the following functions:
--
-- * replace
-- * qreplace
-- * substitute_substrings
--
-- Transformed most part of the library to make it slightly
-- more efficient and simple. The interface is still the same!
--
-- Updated OCamlMakefile + documentation.
--
--2002-07-15: Fixed a mistake in the documentation.
--
--2002-05-05: Fixed a bug with the generation of byte-code libraries that
-- dynamically link the PCRE.
--
--2002-05-01: Removed C-library from distribution! Users must install it
-- on their own now. Reorganized whole distribution and updated
-- OCamlMakefile again for better support of dynamic and/or
-- static libraries.
--
--2002-04-30: Updated OcamlMakefile: it does not ask for confirmation
-- during installation anymore!
--
--2002-03-06: Upgraded to pcre-3.9. This should not change anything for
-- OCaml-users.
--
--2002-03-01: Updated OcamlMakefile.
--
--2002-02-24: Separated compilation of library and examples to prevent
-- confusions when the library needs to be installed before
-- one can build the examples.
--
--2002-02-15: Fixed a bug in the pcre_exec-function which was introduced
-- ten days ago during correction of another bug (thanks to
-- Gerd Stolpmann for the report!).
--
--2002-02-15: Added the option to compile the library statically only.
--
-- Updated INSTALL-notes to explain possible installation
-- problems associated with support of dynamic linking.
--
-- Added META-file for findlib.
--
--2002-02-12: Rewrote interface documentation to support OCamldoc.
--
-- Fixed a portability bug with shared libraries.
--
--2002-02-10: Removed project from Sourceforge for simpler maintainance.
--
--2002-02-07: Important news: library is linked dynamically now by default.
--
--2002-02-06: Fixed a stupid bug affecting the following functions
-- (thanks to Jacek Chrzaszcz for the bug report!):
--
-- * num_of_subs
-- * get_substring
-- * get_substring_ofs
-- * get_substrings
-- * extract
--
-- Also done: converted literal pattern strings in the library
-- and the cloc-example so that the escape char (backslash) does
-- not cause warnings anymore with the new OCaml-release. The
-- latter is more paranoid about unknown escape combinations,
-- requiring the user to add extra backslashes.
--
--2002-01-07: Fixed a stupid bug: the position argument (offset) was
-- not correctly handled in replacement and substitution
-- functions, leading to wrong results. As it seems, people
-- seldom use arguments other than zero...
--
-- The "subst"-example now assumes that offsets other than zero
-- should not lead to an error if it exceeds the line length.
-- The line is just copied instead.
--
--2001-12-28: Added README.win32 (courtesy of John W. Small).
--
-- Updated README so that it is generated by Hevea.
--
--2001-11-19: Upgraded to the newest release of the underlying C-library
-- (PCRE-3.7).
--
-- Added a tiny patch to satisfy the Visual C++ compiler under
-- W2K (thanks to John W. Small!).
--
-- Updated contact address.
--
--2001-11-17: Updated OcamlMakefile.
--
--2001-09-15: Upgraded to the newest release of the underlying C-library
-- (PCRE-3.5).
--
-- Added a new function: substitute_substrings
--
-- It is similar to "substitute", but takes the full substring
-- information of the match rather than the matching string.
-- Thanks to Patrick M. Doane for proposing this missing feature!
--
--2001-09-07: Updated OcamlMakefile
--
--2001-08-27: Fixed a bug in the splitting function: leading whitespace was
-- accidently always removed when using a regular expression
-- rather than a pattern. This behaviour should only happen
-- for the default whitespace pattern, which is used if you
-- do not specify any pattern or regexp in the function call.
--
--2001-06-30: Removed "Printexc.catch" from examples: is going to be
-- deprecated in upcoming OCaml-release.
--
--2001-05-22: Fixed typo in documentation.
--
--2001-04-25: Added a new function: asplit
--
-- It is identical to "split" with the exception that it
-- returns a string array instead of a string list. This makes
-- it easier for the user to access strings by index.
--
-- Added a new option to "get_substrings" and "extract": full_match
--
-- When "full_match" is true (default: yes), then the resulting
-- string array will contain the full match at index 0,
-- otherwise the result will only contain captured substrings.
--
-- Removed superfluous comments in "pcre.ml": they are already
-- present in the interface documentation anyway.
--
--2001-04-08: Small patch that makes this library compile on OpenBSD, too.
--
--2001-01-30: Made Makefile more general (allows simpler addition of
-- further examples).
--
--2001-01-24: Updated OcamlMakefile: made default definition of
-- "OCAMLLIBPATH" backwards compatible again: some people
-- do not use the CVS-version of OCaml, which supports the
-- "-where"-option. People with the new compiler will not
-- notice any effect.
--
--2001-01-06: Added a new function: exec_all
--
-- It allows you to execute pattern matching over a whole
-- string until no more matches can be found: then it returns
-- the array of all matching "substrings". You can extract
-- subpatterns of each of those matching substrings again with
-- the usual functions.
--
-- Fixed a minor inconsistency in "next_match".
--
--2000-12-23: Updated OcamlMakefile: makes use of the new "-where"-keyword
-- to find the path to the standard library if it is not
-- defined.
--
--2000-12-14: Pedantry in the C-interface: added "const" qualifiers.
--
--2000-12-09: Made some functions tail-recursive (very unlikely to cause
-- any noticable effect for most people).
--
--2000-12-02: Cleaned up the code a bit for distribution on SourceForge.
-- Speed of some operations should be very slightly improved, too.
--
--2000-11-16: Fixed a stupid bug that could crash your programs under rare
-- circumstances (when you use faulty regular expressions).
--
-- Added an internally used exception (InternalError) to the
-- interface of the library. This allows the user to handle
-- the case when the C-engine exhibits undefined behaviour
-- (should never happen, anyway).
--
--2000-09-27: Upgraded to the newest release of the underlying C-library
-- (PCRE-3.4).
--
-- See "pcre-C/ChangeLog" for more information (mostly minor
-- bugfixes).
--
-- Renamed "pgrep" to "pcregrep" to prevent name hiding on
-- Solaris (change as suggested in the C-library distribution).
--
--2000-06-24: Updated OcamlMakefile
--
--2000-06-13: Updated OcamlMakefile
--
--2000-06-12: Mini-optimisation: lifted a pure value out of a function body.
--
--2000-06-11: Updated OcamlMakefile
--
--2000-06-08: Added installation routine + updated OcamlMakefile again:
--
-- This upgrade makes installation much easier! Read the
-- updated INSTALL-file!
--
--2000-06-07: Updated to new OcamlMakefile
--
--2000-06-05: Added a new function:
--
-- get_substring_ofs substrings n
--
-- This allows you to get the offset positions of the matching
-- pattern and the substrings directly from a value of type
-- "substring". See the interface documentation for details.
--
--2000-05-15: Upgraded to the newest release of the underlying C-library
-- (PCRE-3.2).
--
-- This does not add new features, but is said to fix some
-- PERL-compatibility bugs and improves portability.
--
--2000-05-04: Minor update of C-interface:
--
-- Use the new "hash_variant"-function to compute the hash value of
-- variants (used Callback.register before - a bit clumsy).
--
--2000-04-24: New release: compiles with OCaml-3.00.
--
-- Lots of changes in interface! OCaml-3.00 introduced some syntax
-- changes for labels. Additionally, no keywords are allowed for
-- them. All this required quite some renamings. I tried to stick to
-- the new labels of the "str"-library as close as makes sense.
-- Sorry for this inconvenience, but I think that adhering to some
-- "standard" is a Good Thing...
--
-- For further information on the changes, look at the documentation
-- of the interface file.
--
--2000-04-23: Minor cleanup of C-interface:
--
-- Made local functions + variables static and moved a check for
-- error codes (lint should be happier now).
--
--2000-04-01: Changed linking of the library again (marginally):
--
-- The new linking semantics for byte code libraries allows passing
-- of flags that are remembered. This then only requires linking
-- executables against "pcre.cma" - the C-library ("libpcre.a") will
-- be linked in automatically.
--
--2000-03-30: Cleaned up the C-interface:
--
-- Removed a possible bug in the allocation of firstchar values.
--
-- Saner handling of polymorphic variants (not hard-wired
-- integers anymore - registered via callbacks).
--
-- Better GC-settings: much nicer to the GC now (fewer full
-- cycles - hardly more memory consumption). Should make
-- programs run slightly faster when regular expressions are
-- often allocated.
--
-- Changed linking of the library to suit the semantics of
-- the upcoming OCaml-major release (backward compatible).
--
--2000-02-07: Changed interface of function "foreach_file":
--
-- No idea why I implemented a tuple in the interface instead of a
-- curried function. Must have been the drugs... ;-)
--
-- Former interface:
--
-- val foreach_file :
-- string list -> (string * in_channel -> unit) -> unit
--
-- Current interface:
--
-- val foreach_file :
-- string list -> (string -> in_channel -> unit) -> unit
--
-- Additionally, this function now also closes the file channel
-- in case of an exception. The exception gets reraised,
-- of course.
--
--2000-02-05: Eliminated a PERL-incompatibility of the "split"-function:
--
-- When neither the pattern nor the compiled regular
-- expression are specified, "split" defaults to a whitespace
-- pattern. However, PERL additionally strips leading
-- whitespace, but *only* when in "default" mode.
--
-- This last "feature" (?) was overseen during the introduction
-- of labels and default arguments.
--
--2000-02-05: Updated the C-library to the newest release (pcre-3.0).
--
-- This is a major release, but the changes to the OCaml-part
-- are rather small: just the functionality concerning
-- information on compiled patterns has changed.
--
-- Instead of the former "info"-function, several ones are
-- provided. I think this is the most convenient way to handle
-- this, because it does not force the user to do explicit
-- pattern matching on results: due to the number of new
-- info-options this would have been rather confusing.
--
-- Because the old PCRE-function "pcre_info" is obsolete,
-- I chose to drop its OCaml-interface completely. I do not
-- think that it is an often used part, anyway.
--
-- See the interface file and the ChangeLog + documentation
-- of the C-library to see, what has changed in detail.
--
-- The other few changes just marginally effect efficiency. One
-- bug was present in the last release in the "info"-part
-- (polymorphic variants were not correctly represented).
-- This has changed anyway and should work fine now.
--
--2000-01-10: "foreach_line" uses stdin as labeled (label: 'in') default
-- argument now.
--
--1999-12-29: Lots of changes:
--
-- * Uses the new features of OCaml 2.99:
--
-- Labeled parameters and default arguments for much more
-- convenience. E.g. write
--
-- split pos:1 "foo bar"
--
-- to get the list ["oo"; "bar"].
--
-- Polymorphic variants for passing options: this change allows,
-- for example, using the data constructor "ANCHORED" for both
-- compiling flags and at matching time instead of "C_ANCHORED"
-- and "R_ANCHORED".
--
-- * Got rid of all the superfluous shortcuts, like "bounded_psplit"
-- and the like. Labeled parameters are much more readable and
-- convenient.
--
-- * Removed the functions compatible to the "Str"-module. It's
-- probably rather confusing for people to see two different kinds
-- of implementations.
--
-- * Renamed functions due to the use of labels and the removing of
-- the obsolete compatibility functions.
--
-- * Updated documentation with more details on using the library.
--
--1999-12-21: Small change (2 chars...) to make the C-interface compile with
-- the newest release (OCaml 2.99).
--
--1999-09-27: Fixed a bug which occurs, when replacements or substitutions
-- in strings are longer than the subject string itself.
-- This concerns functions "replace_all", "qreplace_all" and
-- "substitute_all" + their variants.
--
-- THANKS to GERD STOLPMANN (Gerd.Stolpmann@darmstadt.netsurf.de)
-- for finding another bug!
--
--1999-09-21: Fixed some bugs in "pcre_intf.c":
--
-- "Store_field" was used inappropriately throughout the file,
-- which could lead to segfaults in the garbage collector. This
-- was corrected by using the "Field"-macro where appropriate.
--
-- Protected an input parameter from being reclaimed too early.
--
-- Initialized a field before throwing an exception to please
-- the GC.
--
-- The GC should be happy now...
--
-- THANKS to GERD STOLPMANN (Gerd.Stolpmann@darmstadt.netsurf.de)
-- for the patch!
--
--1999-08-31: Updated to pcre-2.08 - this should fix some bugs. See
-- "pcre-C/ChangeLog" for details.
--
-- Renamed directory "pcre-C-2.07" to "pcre-C" to allow for
-- easier upgrading.
--
-- Added CVS-info to sources.
--
--1999-08-24: Updated to pcre-2.07. Splitting is 100% PERL-compatible now.
-- New runtime option: NOTEMPTY (see interface for details).
--
-- Two additional examples: cloc and count_hash.
--
-- New functions: sregexpo, sregexp, sregexp_case_fold.
--
--1999-08-02: Exception handling more regular now:
--
-- Raises [Invalid_argument] instead of [Failure] where
-- appropriate.
-- Raises [InternalError] if C-library exhibits undefined
-- behaviour (has never happened so far).
--
-- Updated comments.
--
--1999-07-30: Bugfix in "pcre_intf.c":
--
-- "pcre_ocaml" should work now on 64-bit architectures...
--
--1999-07-29: Small fix in "pcre_intf.c":
--
-- strict compilers (gcc is not very strict) otherwise complain
-- about undefined behaviour in a certain line.
--
-- Explicitely mention all include files.
-- Removed unused variable.
--
-- Also moved a line for efficiency...
--
--1999-07-28: First release.
-diff --git a/bundles/pcre/pcre-ocaml/src/.gitignore b/bundles/pcre/pcre-ocaml/src/.gitignore
-deleted file mode 100644
-index 7da7cb2d0..000000000
---- a/bundles/pcre/pcre-ocaml/src/.gitignore
-+++ /dev/null
-@@ -1 +0,0 @@
--pcre_stubs.c
-\ No newline at end of file
-diff --git a/bundles/pcre/pcre-ocaml/src/Makefile b/bundles/pcre/pcre-ocaml/src/Makefile
-deleted file mode 100644
-index 724653615..000000000
---- a/bundles/pcre/pcre-ocaml/src/Makefile
-+++ /dev/null
-@@ -1,9 +0,0 @@
--TARGETS = pcre.cma libpcre_stubs.a
--
--.PHONY: all clean
--
--all:
-- @dune build $(TARGETS)
--
--clean:
-- @dune clean
-diff --git a/bundles/pcre/pcre-ocaml/src/config/discover.ml b/bundles/pcre/pcre-ocaml/src/config/discover.ml
-deleted file mode 100644
-index 01fbfab0a..000000000
---- a/bundles/pcre/pcre-ocaml/src/config/discover.ml
-+++ /dev/null
-@@ -1,15 +0,0 @@
--open Base
--
--let () =
-- let module C = Configurator.V1 in
-- C.main ~name:"pcre" (fun c ->
-- let default : C.Pkg_config.package_conf = {
-- libs = ["-lpcre"];
-- cflags = []
-- } in
-- let conf =
-- Option.value_map (C.Pkg_config.get c) ~default ~f:(fun pc ->
-- Option.value (C.Pkg_config.query pc ~package:"libpcre") ~default)
-- in
-- C.Flags.write_sexp "c_flags.sexp" conf.cflags;
-- C.Flags.write_sexp "c_library_flags.sexp" conf.libs)
-diff --git a/bundles/pcre/pcre-ocaml/src/config/dune b/bundles/pcre/pcre-ocaml/src/config/dune
-deleted file mode 100644
-index dbea8ff91..000000000
---- a/bundles/pcre/pcre-ocaml/src/config/dune
-+++ /dev/null
-@@ -1,4 +0,0 @@
--(executables
-- (names discover)
-- (libraries base dune.configurator)
--)
-diff --git a/bundles/pcre/pcre-ocaml/src/dune b/bundles/pcre/pcre-ocaml/src/dune
-deleted file mode 100644
-index a0bd636d7..000000000
---- a/bundles/pcre/pcre-ocaml/src/dune
-+++ /dev/null
-@@ -1,16 +0,0 @@
--(library
-- (public_name pcre)
-- (c_names pcre_stubs)
-- (c_flags (
-- (:include c_flags.sexp) -g -O2 -fPIC -DPIC
-- ; NOTE: for debugging before releases
-- ; -Wall -pedantic -Wextra -Wunused -Wno-long-long -Wno-keyword-macro
-- ))
-- (c_library_flags (:include c_library_flags.sexp))
--)
--
--(rule
-- (targets c_flags.sexp c_library_flags.sexp)
-- (deps (:discover config/discover.exe))
-- (action (run %{discover}))
--)
-diff --git a/bundles/pcre/pcre-ocaml/src/pcre.ml.in b/bundles/pcre/pcre-ocaml/src/pcre.ml.in
-deleted file mode 100644
-index 573460e4e..000000000
---- a/bundles/pcre/pcre-ocaml/src/pcre.ml.in
-+++ /dev/null
-@@ -1,1055 +0,0 @@
--(*
-- PCRE-OCAML - Perl Compatibility Regular Expressions for OCaml
--
-- Copyright (C) 1999- Markus Mottl
-- email: markus.mottl@gmail.com
-- WWW: http://www.ocaml.info
--
-- This library is free software; you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public
-- License as published by the Free Software Foundation; either
-- version 2.1 of the License, or (at your option) any later version.
--
-- This library is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- Lesser General Public License for more details.
--
-- You should have received a copy of the GNU Lesser General Public
-- License along with this library; if not, write to the Free Software
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--*)
--
--open Stdcompat
--
--(* Public exceptions and their registration with the C runtime *)
--
--type error =
-- | Partial
-- | BadPartial
-- | BadPattern of string * int
-- | BadUTF8
-- | BadUTF8Offset
-- | MatchLimit
-- | RecursionLimit
-- | InternalError of string
--
--exception Error of error
--exception Backtrack
--exception Regexp_or of string * error
--
--(* Puts exceptions into global C-variables for fast retrieval *)
--external pcre_ocaml_init : unit -> unit = "pcre_ocaml_init"
--
--(* Registers exceptions with the C runtime and caches polymorphic variants *)
--let () =
-- Callback.register_exception "Pcre.Error" (Error (InternalError ""));
-- Callback.register_exception "Pcre.Backtrack" Backtrack;
-- pcre_ocaml_init ()
--
--
--(* Compilation and runtime flags and their conversion functions *)
--
--type icflag = int
--type irflag = int
--
--(* Compilation flags *)
--
--type cflag =
-- [
-- | `CASELESS
-- | `MULTILINE
-- | `DOTALL
-- | `EXTENDED
-- | `ANCHORED
-- | `DOLLAR_ENDONLY
-- | `EXTRA
-- | `UNGREEDY
-- | `UTF8
-- | `NO_UTF8_CHECK
-- | `NO_AUTO_CAPTURE
-- | `AUTO_CALLOUT
-- | `FIRSTLINE
-- ]
--
--let int_of_cflag = function
-- | `CASELESS -> 0x0001
-- | `MULTILINE -> 0x0002
-- | `DOTALL -> 0x0004
-- | `EXTENDED -> 0x0008
-- | `ANCHORED -> 0x0010
-- | `DOLLAR_ENDONLY -> 0x0020
-- | `EXTRA -> 0x0040
-- | `UNGREEDY -> 0x0200
-- | `UTF8 -> 0x0800
-- | `NO_AUTO_CAPTURE -> 0x1000
-- | `NO_UTF8_CHECK -> 0x2000
-- | `AUTO_CALLOUT -> 0x4000
-- | `FIRSTLINE -> 0x40000
--
--let coll_icflag icflag flag = int_of_cflag flag lor icflag
--let cflags flags = List.fold_left coll_icflag 0 flags
--
--let cflag_of_int = function
-- | 0x0001 -> `CASELESS
-- | 0x0002 -> `MULTILINE
-- | 0x0004 -> `DOTALL
-- | 0x0008 -> `EXTENDED
-- | 0x0010 -> `ANCHORED
-- | 0x0020 -> `DOLLAR_ENDONLY
-- | 0x0040 -> `EXTRA
-- | 0x0200 -> `UNGREEDY
-- | 0x0800 -> `UTF8
-- | 0x1000 -> `NO_AUTO_CAPTURE
-- | 0x2000 -> `NO_UTF8_CHECK
-- | 0x4000 -> `AUTO_CALLOUT
-- | 0x40000 -> `FIRSTLINE
-- | _ -> failwith "Pcre.cflag_list: unknown compilation flag"
--
--let all_cflags =
-- [
-- 0x0001; 0x0002; 0x0004; 0x0008; 0x0010; 0x0020;
-- 0x0040; 0x0200; 0x0800; 0x1000; 0x2000; 0x4000; 0x40000;
-- ]
--
--let cflag_list icflags =
-- let coll flag_list flag =
-- if icflags land flag <> 0 then cflag_of_int flag :: flag_list
-- else flag_list in
-- List.fold_left coll [] all_cflags
--
--
--(* Runtime flags *)
--
--type rflag =
-- [
-- | `ANCHORED
-- | `NOTBOL
-- | `NOTEOL
-- | `NOTEMPTY
-- | `PARTIAL
-- ]
--
--let int_of_rflag = function
-- | `ANCHORED -> 0x0010
-- | `NOTBOL -> 0x0080
-- | `NOTEOL -> 0x0100
-- | `NOTEMPTY -> 0x0400
-- | `PARTIAL -> 0x8000
--
--let coll_irflag irflag flag = int_of_rflag flag lor irflag
--let rflags flags = List.fold_left coll_irflag 0 flags
--
--let rflag_of_int = function
-- | 0x0010 -> `ANCHORED
-- | 0x0080 -> `NOTBOL
-- | 0x0100 -> `NOTEOL
-- | 0x0400 -> `NOTEMPTY
-- | 0x8000 -> `PARTIAL
-- | _ -> failwith "Pcre.rflag_list: unknown runtime flag"
--
--let all_rflags = [0x0010; 0x0080; 0x0100; 0x0400; 0x8000]
--
--let rflag_list irflags =
-- let coll flag_list flag =
-- if irflags land flag <> 0 then rflag_of_int flag :: flag_list
-- else flag_list in
-- List.fold_left coll [] all_rflags
--
--
--(* Information on the PCRE-configuration (build-time options) *)
--
--external pcre_version : unit -> string = "pcre_version_stub"
--
--external pcre_config_utf8 : unit -> bool = "pcre_config_utf8_stub" @noalloc@
--
--external pcre_config_newline :
-- unit -> char = "pcre_config_newline_stub" @noalloc@
--
--external pcre_config_link_size : unit -> (int @untagged@)
-- = "pcre_config_link_size_stub_bc" "pcre_config_link_size_stub" @noalloc@
--
--external pcre_config_match_limit :
-- unit -> (int @untagged@)
-- = "pcre_config_match_limit_stub_bc" "pcre_config_match_limit_stub" @noalloc@
--
--external pcre_config_match_limit_recursion : unit -> (int @untagged@)
-- =
-- "pcre_config_match_limit_recursion_stub_bc"
-- "pcre_config_match_limit_recursion_stub"
-- @noalloc@
--
--external pcre_config_stackrecurse :
-- unit -> bool = "pcre_config_stackrecurse_stub" @noalloc@
--
--let version = pcre_version ()
--let config_utf8 = pcre_config_utf8 ()
--let config_newline = pcre_config_newline ()
--let config_link_size = pcre_config_link_size ()
--let config_match_limit = pcre_config_match_limit ()
--let config_match_limit_recursion = pcre_config_match_limit_recursion ()
--let config_stackrecurse = pcre_config_stackrecurse ()
--
--
--(* Information on patterns *)
--
--type firstbyte_info =
-- [ `Char of char
-- | `Start_only
-- | `ANCHORED ]
--
--type study_stat =
-- [ `Not_studied
-- | `Studied
-- | `Optimal ]
--
--type regexp
--
--external options : regexp -> (icflag @untagged@)
-- = "pcre_options_stub_bc" "pcre_options_stub"
--
--external size : regexp -> (int @untagged@)
-- = "pcre_size_stub_bc" "pcre_size_stub"
--
--external studysize : regexp -> (int @untagged@)
-- = "pcre_studysize_stub_bc" "pcre_studysize_stub"
--
--external capturecount : regexp -> (int @untagged@)
-- = "pcre_capturecount_stub_bc" "pcre_capturecount_stub"
--
--external backrefmax : regexp -> (int @untagged@)
-- = "pcre_backrefmax_stub_bc" "pcre_backrefmax_stub"
--
--external namecount : regexp -> (int @untagged@)
-- = "pcre_namecount_stub_bc" "pcre_namecount_stub"
--
--external nameentrysize : regexp -> (int @untagged@)
-- = "pcre_nameentrysize_stub_bc" "pcre_nameentrysize_stub"
--
--external names : regexp -> string array = "pcre_names_stub"
--external firstbyte : regexp -> firstbyte_info = "pcre_firstbyte_stub"
--external firsttable : regexp -> string option = "pcre_firsttable_stub"
--external lastliteral : regexp -> char option = "pcre_lastliteral_stub"
--external study_stat : regexp -> study_stat = "pcre_study_stat_stub" @noalloc@
--
--
--(* Compilation of patterns *)
--
--type chtables
--
--external maketables : unit -> chtables = "pcre_maketables_stub"
--
--(* Internal use only! *)
--external pcre_study : regexp -> unit = "pcre_study_stub"
--
--external compile : (icflag @untagged@) -> chtables option -> string -> regexp
-- = "pcre_compile_stub_bc" "pcre_compile_stub"
--
--external get_match_limit : regexp -> int option = "pcre_get_match_limit_stub"
--
--external get_match_limit_recursion : regexp -> int option
-- = "pcre_get_match_limit_recursion_stub"
--
--(* Internal use only! *)
--external set_imp_match_limit : regexp -> (int @untagged@) -> regexp
-- = "pcre_set_imp_match_limit_stub_bc" "pcre_set_imp_match_limit_stub"
-- @noalloc@
--
--(* Internal use only! *)
--external set_imp_match_limit_recursion : regexp -> (int @untagged@) -> regexp
-- =
-- "pcre_set_imp_match_limit_recursion_stub_bc"
-- "pcre_set_imp_match_limit_recursion_stub"
-- @noalloc@
--
--let regexp
-- ?(study = true) ?limit ?limit_recursion
-- ?(iflags = 0) ?flags ?chtables pat =
-- let rex =
-- match flags with
-- | Some flag_list -> compile (cflags flag_list) chtables pat
-- | _ -> compile iflags chtables pat
-- in
-- if study then pcre_study rex;
-- let rex =
-- match limit with
-- | None -> rex
-- | Some lim -> set_imp_match_limit rex lim
-- in
-- match limit_recursion with
-- | None -> rex
-- | Some lim -> set_imp_match_limit_recursion rex lim
--
--let regexp_or
-- ?study ?limit ?limit_recursion ?(iflags = 0) ?flags ?chtables pats =
-- let check pat =
-- try ignore (regexp ~study:false ~iflags ?flags ?chtables pat)
-- with Error error -> raise (Regexp_or (pat, error))
-- in
-- List.iter check pats;
-- let big_pat =
-- let cnv pat = "(?:" ^ pat ^ ")" in
-- String.concat "|" (List.rev (List.rev_map cnv pats))
-- in
-- regexp ?study ?limit ?limit_recursion ~iflags ?flags ?chtables big_pat
--
--let bytes_unsafe_blit_string str str_ofs bts bts_ofs len =
-- let str_bts = Bytes.unsafe_of_string str in
-- Bytes.unsafe_blit str_bts str_ofs bts bts_ofs len
--
--let string_unsafe_sub str ofs len =
-- let res = Bytes.create len in
-- bytes_unsafe_blit_string str ofs res 0 len;
-- Bytes.unsafe_to_string res
--
--let quote s =
-- let len = String.length s in
-- let buf = Bytes.create (len lsl 1) in
-- let pos = ref 0 in
-- for i = 0 to len - 1 do
-- match String.unsafe_get s i with
-- | '\\' | '^' | '$' | '.' | '[' | '|'
-- | '(' | ')' | '?' | '*' | '+' | '{' as c ->
-- Bytes.unsafe_set buf !pos '\\';
-- incr pos;
-- Bytes.unsafe_set buf !pos c;
-- incr pos
-- | c -> Bytes.unsafe_set buf !pos c; incr pos
-- done;
-- string_unsafe_sub (Bytes.unsafe_to_string buf) 0 !pos
--
--
--(* Matching of patterns and subpattern extraction *)
--
--(* Default regular expression when none is provided by the user *)
--let def_rex = regexp "\\s+"
--
--type substrings = string * int array
--
--type callout_data =
-- {
-- callout_number : int;
-- substrings : substrings;
-- start_match : int;
-- current_position : int;
-- capture_top : int;
-- capture_last : int;
-- pattern_position : int;
-- next_item_length : int;
-- }
--
--type callout = callout_data -> unit
--
--let get_subject (subj, _) = subj
--
--let num_of_subs (_, ovector) = Array.length ovector / 3
--
--let get_offset_start ovector str_num =
-- if str_num < 0 || str_num >= Array.length ovector / 3 then
-- invalid_arg "Pcre.get_offset_start: illegal offset";
-- let offset = str_num lsl 1 in
-- offset, Array.unsafe_get ovector offset
--
--let get_substring_aux (subj, ovector) offset start =
-- if start < 0 then raise Not_found
-- else
-- string_unsafe_sub subj start (Array.unsafe_get ovector (offset + 1) - start)
--
--let get_substring (_, ovector as substrings) str_num =
-- let offset, start = get_offset_start ovector str_num in
-- get_substring_aux substrings offset start
--
--let get_substring_ofs (_subj, ovector) str_num =
-- let offset, start = get_offset_start ovector str_num in
-- if start < 0 then raise Not_found
-- else start, Array.unsafe_get ovector (offset + 1)
--
--let unsafe_get_substring (_, ovector as substrings) str_num =
-- let offset = str_num lsl 1 in
-- try get_substring_aux substrings offset (Array.unsafe_get ovector offset)
-- with Not_found -> ""
--
--let get_substrings ?(full_match = true) (_, ovector as substrings) =
-- if full_match then
-- Array.init (Array.length ovector / 3) (unsafe_get_substring substrings)
-- else
-- let len = (Array.length ovector / 3) - 1 in
-- Array.init len (fun n -> unsafe_get_substring substrings (n + 1))
--
--let unsafe_get_opt_substring (_, ovector as substrings) str_num =
-- let offset = str_num lsl 1 in
-- try
-- let start = Array.unsafe_get ovector offset in
-- let str = get_substring_aux substrings offset start in
-- Some str
-- with Not_found -> None
--
--let get_opt_substrings ?(full_match = true) (_, ovector as substrings) =
-- if full_match then
-- Array.init (Array.length ovector / 3) (unsafe_get_opt_substring substrings)
-- else
-- let len = (Array.length ovector / 3) - 1 in
-- Array.init len (fun n -> unsafe_get_opt_substring substrings (n + 1))
--
--external get_stringnumber : regexp -> string -> (int @untagged@)
-- = "pcre_get_stringnumber_stub_bc" "pcre_get_stringnumber_stub"
--
--let get_named_substring rex name substrings =
-- get_substring substrings (get_stringnumber rex name)
--
--let get_named_substring_ofs rex name substrings =
-- get_substring_ofs substrings (get_stringnumber rex name)
--
--external unsafe_pcre_exec :
-- (irflag @untagged@) ->
-- regexp ->
-- pos : (int @untagged@) ->
-- subj_start : (int @untagged@) ->
-- subj : string ->
-- int array ->
-- callout option ->
-- unit = "pcre_exec_stub_bc" "pcre_exec_stub"
--
--let make_ovector rex =
-- let subgroups1 = capturecount rex + 1 in
-- let subgroups2 = subgroups1 lsl 1 in
-- subgroups2, Array.make (subgroups1 + subgroups2) 0
--
--let pcre_exec ?(iflags = 0) ?flags ?(rex = def_rex) ?pat ?(pos = 0)
-- ?callout subj =
-- let rex = match pat with Some str -> regexp str | _ -> rex in
-- let iflags = match flags with Some flags -> rflags flags | _ -> iflags in
-- let _, ovector = make_ovector rex in
-- unsafe_pcre_exec iflags rex ~pos ~subj_start:0 ~subj ovector callout;
-- ovector
--
--let exec ?iflags ?flags ?rex ?pat ?pos ?callout subj =
-- subj, pcre_exec ?iflags ?flags ?rex ?pat ?pos ?callout subj
--
--let next_match ?iflags ?flags ?rex ?pat ?(pos = 0) ?callout (subj, ovector) =
-- let pos = Array.unsafe_get ovector 1 + pos in
-- let subj_len = String.length subj in
-- if pos < 0 || pos > subj_len then
-- invalid_arg "Pcre.next_match: illegal offset";
-- subj, pcre_exec ?iflags ?flags ?rex ?pat ~pos ?callout subj
--
--let rec copy_lst ar n = function
-- | [] -> ar
-- | h :: t -> Array.unsafe_set ar n h; copy_lst ar (n - 1) t
--
--let exec_all ?(iflags = 0) ?flags ?(rex = def_rex) ?pat ?pos ?callout subj =
-- let rex = match pat with Some str -> regexp str | _ -> rex in
-- let iflags = match flags with Some flags -> rflags flags | _ -> iflags in
-- let (_, ovector as sstrs) = exec ~iflags ~rex ?pos ?callout subj in
-- let null_flags = iflags lor 0x0400 in
-- let subj_len = String.length subj in
-- let rec loop pos (subj, ovector as sstrs) n lst =
-- let maybe_ovector =
-- try
-- let first = Array.unsafe_get ovector 0 in
-- if first = pos && Array.unsafe_get ovector 1 = pos then
-- if pos = subj_len then None
-- else Some (pcre_exec ~iflags:null_flags ~rex ~pos ?callout subj)
-- else Some (pcre_exec ~iflags ~rex ~pos ?callout subj)
-- with Not_found -> None in
-- match maybe_ovector with
-- | Some ovector ->
-- let new_pos = Array.unsafe_get ovector 1 in
-- loop new_pos (subj, ovector) (n + 1) (sstrs :: lst)
-- | None -> copy_lst (Array.make (n + 1) sstrs) (n - 1) lst in
-- loop (Array.unsafe_get ovector 1) sstrs 0 []
--
--let extract ?iflags ?flags ?rex ?pat ?pos ?full_match ?callout subj =
-- get_substrings ?full_match (exec ?iflags ?flags ?rex ?pat ?pos ?callout subj)
--
--let extract_opt ?iflags ?flags ?rex ?pat ?pos ?full_match ?callout subj =
-- get_opt_substrings
-- ?full_match (exec ?iflags ?flags ?rex ?pat ?pos ?callout subj)
--
--let extract_all ?iflags ?flags ?rex ?pat ?pos ?full_match ?callout subj =
-- let many_sstrs = exec_all ?iflags ?flags ?rex ?pat ?pos ?callout subj in
-- Array.map (get_substrings ?full_match) many_sstrs
--
--let extract_all_opt ?iflags ?flags ?rex ?pat ?pos ?full_match ?callout subj =
-- let many_sstrs = exec_all ?iflags ?flags ?rex ?pat ?pos ?callout subj in
-- Array.map (get_opt_substrings ?full_match) many_sstrs
--
--let pmatch ?iflags ?flags ?rex ?pat ?pos ?callout subj =
-- try ignore (pcre_exec ?iflags ?flags ?rex ?pat ?pos ?callout subj); true
-- with Not_found -> false
--
--
--(* String substitution *)
--
--(* Elements of a substitution pattern *)
--type subst =
-- | SubstString of int * int (* Denotes a substring in the substitution *)
-- | Backref of int (* nth backreference ($0 is program name!) *)
-- | Match (* The whole matched string *)
-- | PreMatch (* The string before the match *)
-- | PostMatch (* The string after the match *)
-- | LastParenMatch (* The last matched group *)
--
--(* Information on substitution patterns *)
--type substitution = string (* The substitution string *)
-- * int (* Highest group number of backreferences *)
-- * bool (* Makes use of "LastParenMatch" *)
-- * subst list (* The list of substitution elements *)
--
--(* Only used internally in "subst" *)
--exception FoundAt of int
--
--let zero = Char.code '0'
--
--let subst str =
-- let max_br = ref 0 in
-- let with_lp = ref false in
-- let lix = String.length str - 1 in
-- let rec loop acc n =
-- if lix < n then acc
-- else
-- try
-- for i = n to lix do
-- if String.unsafe_get str i = '$' then raise (FoundAt i)
-- done;
-- SubstString (n, lix - n + 1) :: acc
-- with FoundAt i ->
-- if i = lix then SubstString (n, lix - n + 1) :: acc
-- else
-- let i1 = i + 1 in
-- let acc = if n = i then acc else SubstString (n, i - n) :: acc in
-- match String.unsafe_get str i1 with
-- | '0'..'9' as c ->
-- let subpat_nr = ref (Char.code c - zero) in
-- (try
-- for j = i1 + 1 to lix do
-- let c = String.unsafe_get str j in
-- if c >= '0' && c <= '9' then
-- subpat_nr := 10 * !subpat_nr + Char.code c - zero
-- else raise (FoundAt j)
-- done;
-- max_br := max !subpat_nr !max_br;
-- Backref !subpat_nr :: acc
-- with FoundAt j ->
-- max_br := max !subpat_nr !max_br;
-- loop (Backref !subpat_nr :: acc) j)
-- | '!' -> loop acc (i1 + 1)
-- | '$' -> loop (SubstString (i1, 1) :: acc) (i1 + 1)
-- | '&' -> loop (Match :: acc) (i1 + 1)
-- | '`' -> loop (PreMatch :: acc) (i1 + 1)
-- | '\'' -> loop (PostMatch :: acc) (i1 + 1)
-- | '+' ->
-- with_lp := true;
-- loop (LastParenMatch :: acc) (i1 + 1)
-- | _ -> loop acc i1 in
-- let subst_lst = loop [] 0 in
-- str, !max_br, !with_lp, subst_lst
--
--let def_subst = subst ""
--
--(* Calculates a list of tuples (str, offset, len) which contain
-- substrings to be copied on substitutions. Internal use only! *)
--let calc_trans_lst subgroups2 ovector subj templ subst_lst =
-- let prefix_len = Array.unsafe_get ovector 0 in
-- let last = Array.unsafe_get ovector 1 in
-- let coll (res_len, trans_lst as accu) =
-- let return_lst (_str, _ix, len as el) =
-- if len = 0 then accu else res_len + len, el :: trans_lst in
-- function
-- | SubstString (ix, len) -> return_lst (templ, ix, len)
-- | Backref 0 ->
-- let prog_name = Sys.argv.(0) in
-- return_lst (prog_name, 0, String.length prog_name)
-- | Backref n ->
-- let offset = n lsl 1 in
-- let start = Array.unsafe_get ovector offset in
-- let len = Array.unsafe_get ovector (offset + 1) - start in
-- return_lst (subj, start, len)
-- | Match -> return_lst (subj, prefix_len, last - prefix_len)
-- | PreMatch -> return_lst (subj, 0, prefix_len)
-- | PostMatch -> return_lst (subj, last, String.length subj - last)
-- | LastParenMatch ->
-- let subgroups2_2 = subgroups2 - 2 in
-- let pos = ref subgroups2_2 in
-- let ix = ref (Array.unsafe_get ovector subgroups2_2) in
-- while !ix < 0 do
-- let pos_2 = !pos - 2 in
-- pos := pos_2;
-- ix := Array.unsafe_get ovector pos_2
-- done;
-- return_lst (subj, !ix, Array.unsafe_get ovector (!pos + 1) - !ix) in
-- List.fold_left coll (0, []) subst_lst
--
--let replace ?(iflags = 0) ?flags ?(rex = def_rex) ?pat
-- ?(pos = 0) ?(itempl = def_subst) ?templ ?callout subj =
-- let rex = match pat with Some str -> regexp str | _ -> rex in
-- let iflags = match flags with Some flags -> rflags flags | _ -> iflags in
-- let templ, max_br, with_lp, subst_lst =
-- match templ with
-- | Some str -> subst str
-- | _ -> itempl in
-- let subj_len = String.length subj in
-- if pos < 0 || pos > subj_len then invalid_arg "Pcre.replace: illegal offset";
-- let subgroups2, ovector = make_ovector rex in
-- let nsubs = (subgroups2 lsr 1) - 1 in
-- if max_br > nsubs then
-- failwith "Pcre.replace: backreference denotes nonexistent subpattern";
-- if with_lp && nsubs = 0 then failwith "Pcre.replace: no backreferences";
-- let rec loop full_len trans_lsts cur_pos =
-- if
-- cur_pos > subj_len ||
-- try
-- unsafe_pcre_exec
-- iflags rex ~pos:cur_pos ~subj_start:0 ~subj
-- ovector callout;
-- false
-- with Not_found -> true
-- then
-- let postfix_len = max (subj_len - cur_pos) 0 in
-- let left = pos + full_len in
-- let res = Bytes.create (left + postfix_len) in
-- bytes_unsafe_blit_string subj 0 res 0 pos;
-- bytes_unsafe_blit_string subj cur_pos res left postfix_len;
-- let inner_coll ofs (templ, ix, len) =
-- bytes_unsafe_blit_string templ ix res ofs len; ofs + len in
-- let coll ofs (res_len, trans_lst) =
-- let new_ofs = ofs - res_len in
-- let _ = List.fold_left inner_coll new_ofs trans_lst in
-- new_ofs in
-- let _ = List.fold_left coll left trans_lsts in
-- Bytes.unsafe_to_string res
-- else
-- let first = Array.unsafe_get ovector 0 in
-- let len = first - cur_pos in
-- let res_len, _ as trans_lst_el =
-- calc_trans_lst subgroups2 ovector subj templ subst_lst in
-- let trans_lsts =
-- if len > 0 then
-- trans_lst_el :: (len, [(subj, cur_pos, len)]) :: trans_lsts
-- else trans_lst_el :: trans_lsts in
-- let full_len = full_len + len + res_len in
-- let next = first + 1 in
-- let last = Array.unsafe_get ovector 1 in
-- if last < next then
-- if first < subj_len then
-- let new_trans_lsts = (1, [(subj, cur_pos + len, 1)]) :: trans_lsts in
-- loop (full_len + 1) new_trans_lsts next
-- else loop full_len trans_lsts next
-- else loop full_len trans_lsts last in
-- loop 0 [] pos
--
--let qreplace ?(iflags = 0) ?flags ?(rex = def_rex) ?pat
-- ?(pos = 0) ?(templ = "") ?callout subj =
-- let rex = match pat with Some str -> regexp str | _ -> rex in
-- let iflags = match flags with Some flags -> rflags flags | _ -> iflags in
-- let subj_len = String.length subj in
-- if pos < 0 || pos > subj_len then invalid_arg "Pcre.qreplace: illegal offset";
-- let templ_len = String.length templ in
-- let _, ovector = make_ovector rex in
-- let rec loop full_len subst_lst cur_pos =
-- if
-- cur_pos > subj_len ||
-- try
-- unsafe_pcre_exec
-- iflags rex ~pos:cur_pos ~subj_start:0 ~subj ovector callout;
-- false
-- with Not_found -> true
-- then
-- let postfix_len = max (subj_len - cur_pos) 0 in
-- let left = pos + full_len in
-- let res = Bytes.create (left + postfix_len) in
-- bytes_unsafe_blit_string subj 0 res 0 pos;
-- bytes_unsafe_blit_string subj cur_pos res left postfix_len;
-- let coll ofs = function
-- | Some (substr, ix, len) ->
-- let new_ofs = ofs - len in
-- bytes_unsafe_blit_string substr ix res new_ofs len;
-- new_ofs
-- | None ->
-- let new_ofs = ofs - templ_len in
-- bytes_unsafe_blit_string templ 0 res new_ofs templ_len;
-- new_ofs in
-- let _ = List.fold_left coll left subst_lst in
-- Bytes.unsafe_to_string res
-- else
-- let first = Array.unsafe_get ovector 0 in
-- let len = first - cur_pos in
-- let subst_lst =
-- if len > 0 then None :: Some (subj, cur_pos, len) :: subst_lst
-- else None :: subst_lst in
-- let last = Array.unsafe_get ovector 1 in
-- let full_len = full_len + len + templ_len in
-- let next = first + 1 in
-- if last < next then
-- if first < subj_len then
-- loop (full_len + 1) (Some (subj, cur_pos + len, 1) :: subst_lst) next
-- else loop full_len subst_lst next
-- else loop full_len subst_lst last in
-- loop 0 [] pos
--
--let substitute_substrings ?(iflags = 0) ?flags ?(rex = def_rex) ?pat
-- ?(pos = 0) ?callout ~subst subj =
-- let rex = match pat with Some str -> regexp str | _ -> rex in
-- let iflags = match flags with Some flags -> rflags flags | _ -> iflags in
-- let subj_len = String.length subj in
-- if pos < 0 || pos > subj_len then invalid_arg "Pcre.substitute: illegal offset";
-- let _, ovector = make_ovector rex in
-- let rec loop full_len subst_lst cur_pos =
-- if
-- cur_pos > subj_len ||
-- try
-- unsafe_pcre_exec
-- iflags rex ~pos:cur_pos ~subj_start:0 ~subj ovector callout;
-- false
-- with Not_found -> true
-- then
-- let postfix_len = max (subj_len - cur_pos) 0 in
-- let left = pos + full_len in
-- let res = Bytes.create (left + postfix_len) in
-- bytes_unsafe_blit_string subj 0 res 0 pos;
-- bytes_unsafe_blit_string subj cur_pos res left postfix_len;
-- let coll ofs (templ, ix, len) =
-- let new_ofs = ofs - len in
-- bytes_unsafe_blit_string templ ix res new_ofs len;
-- new_ofs in
-- let _ = List.fold_left coll left subst_lst in
-- Bytes.unsafe_to_string res
-- else
-- let first = Array.unsafe_get ovector 0 in
-- let len = first - cur_pos in
-- let templ = subst (subj, ovector) in
-- let templ_len = String.length templ in
-- let subst_lst =
-- if len > 0 then
-- (templ, 0, templ_len) :: (subj, cur_pos, len) :: subst_lst
-- else (templ, 0, templ_len) :: subst_lst in
-- let last = Array.unsafe_get ovector 1 in
-- let full_len = full_len + len + templ_len in
-- let next = first + 1 in
-- if last < next then
-- if first < subj_len then
-- loop (full_len + 1) ((subj, cur_pos + len, 1) :: subst_lst) next
-- else loop full_len subst_lst next
-- else loop full_len subst_lst last in
-- loop 0 [] pos
--
--let substitute ?iflags ?flags ?rex ?pat ?pos ?callout ~subst:str_subst subj =
-- let subst (subj, ovector) =
-- let first = Array.unsafe_get ovector 0 in
-- let last = Array.unsafe_get ovector 1 in
-- str_subst (string_unsafe_sub subj first (last - first)) in
-- substitute_substrings ?iflags ?flags ?rex ?pat ?pos ?callout ~subst subj
--
--let replace_first ?(iflags = 0) ?flags ?(rex = def_rex) ?pat ?(pos = 0)
-- ?(itempl = def_subst) ?templ ?callout subj =
-- let rex = match pat with Some str -> regexp str | _ -> rex in
-- let iflags = match flags with Some flags -> rflags flags | _ -> iflags in
-- let templ, max_br, with_lp, subst_lst =
-- match templ with
-- | Some str -> subst str
-- | _ -> itempl in
-- let subgroups2, ovector = make_ovector rex in
-- let nsubs = (subgroups2 lsr 1) - 1 in
-- if max_br > nsubs then
-- failwith "Pcre.replace_first: backreference denotes nonexistent subpattern";
-- if with_lp && nsubs = 0 then failwith "Pcre.replace_first: no backreferences";
-- try
-- unsafe_pcre_exec iflags rex ~pos ~subj_start:0 ~subj ovector callout;
-- let res_len, trans_lst =
-- calc_trans_lst subgroups2 ovector subj templ subst_lst in
-- let first = Array.unsafe_get ovector 0 in
-- let last = Array.unsafe_get ovector 1 in
-- let rest = String.length subj - last in
-- let res = Bytes.create (first + res_len + rest) in
-- bytes_unsafe_blit_string subj 0 res 0 first;
-- let coll ofs (templ, ix, len) =
-- bytes_unsafe_blit_string templ ix res ofs len; ofs + len in
-- let ofs = List.fold_left coll first trans_lst in
-- bytes_unsafe_blit_string subj last res ofs rest;
-- Bytes.unsafe_to_string res
-- with Not_found -> subj
--
--let qreplace_first ?(iflags = 0) ?flags ?(rex = def_rex) ?pat
-- ?(pos = 0) ?(templ = "") ?callout subj =
-- let rex = match pat with Some str -> regexp str | _ -> rex in
-- let iflags = match flags with Some flags -> rflags flags | _ -> iflags in
-- let _, ovector = make_ovector rex in
-- try
-- unsafe_pcre_exec iflags rex ~pos ~subj_start:0 ~subj ovector callout;
-- let first = Array.unsafe_get ovector 0 in
-- let last = Array.unsafe_get ovector 1 in
-- let len = String.length templ in
-- let rest = String.length subj - last in
-- let postfix_start = first + len in
-- let res = Bytes.create (postfix_start + rest) in
-- bytes_unsafe_blit_string subj 0 res 0 first;
-- bytes_unsafe_blit_string templ 0 res first len;
-- bytes_unsafe_blit_string subj last res postfix_start rest;
-- Bytes.unsafe_to_string res
-- with Not_found -> subj
--
--let substitute_substrings_first ?(iflags = 0) ?flags ?(rex = def_rex) ?pat
-- ?(pos = 0) ?callout ~subst subj =
-- let rex = match pat with Some str -> regexp str | _ -> rex in
-- let iflags = match flags with Some flags -> rflags flags | _ -> iflags in
-- let _, ovector = make_ovector rex in
-- try
-- unsafe_pcre_exec iflags rex ~pos ~subj_start:0 ~subj ovector callout;
-- let subj_len = String.length subj in
-- let prefix_len = Array.unsafe_get ovector 0 in
-- let last = Array.unsafe_get ovector 1 in
-- let templ = subst (subj, ovector) in
-- let postfix_len = subj_len - last in
-- let templ_len = String.length templ in
-- let postfix_start = prefix_len + templ_len in
-- let res = Bytes.create (postfix_start + postfix_len) in
-- bytes_unsafe_blit_string subj 0 res 0 prefix_len;
-- bytes_unsafe_blit_string templ 0 res prefix_len templ_len;
-- bytes_unsafe_blit_string subj last res postfix_start postfix_len;
-- Bytes.unsafe_to_string res
-- with Not_found -> subj
--
--let substitute_first ?iflags ?flags ?rex ?pat ?pos
-- ?callout ~subst:str_subst subj =
-- let subst (subj, ovector) =
-- let first = Array.unsafe_get ovector 0 in
-- let last = Array.unsafe_get ovector 1 in
-- str_subst (string_unsafe_sub subj first (last - first)) in
-- substitute_substrings_first
-- ?iflags ?flags ?rex ?pat ?pos ?callout ~subst subj
--
--
--(* Splitting *)
--
--let internal_psplit flags rex max pos callout subj =
-- let subj_len = String.length subj in
-- if subj_len = 0 then []
-- else if max = 1 then [subj]
-- else
-- let subgroups2, ovector = make_ovector rex in
--
-- (* Adds contents of subgroups to the string accumulator *)
-- let handle_subgroups strs =
-- let strs = ref strs in
-- let i = ref 2 in
-- while !i < subgroups2 do
-- let first = Array.unsafe_get ovector !i in
-- incr i;
-- let last = Array.unsafe_get ovector !i in
-- let str =
-- if first < 0 then ""
-- else string_unsafe_sub subj first (last - first) in
-- strs := str :: !strs; incr i
-- done;
-- !strs in
--
-- (* Performs the recursive split *)
-- let rec loop strs cnt pos prematch =
-- let len = subj_len - pos in
-- if len < 0 then strs
-- else
-- (* Checks termination due to max restriction *)
-- if cnt = 0 then
-- if prematch &&
-- try
-- unsafe_pcre_exec
-- flags rex ~pos ~subj_start:pos ~subj ovector callout;
-- true
-- with Not_found -> false
-- then
-- let last = Array.unsafe_get ovector 1 in
-- let strs = handle_subgroups strs in
-- string_unsafe_sub subj last (subj_len - last) :: strs
-- else string_unsafe_sub subj pos len :: strs
--
-- (* Calculates next accumulator state for splitting *)
-- else
-- if
-- try
-- unsafe_pcre_exec
-- flags rex ~pos ~subj_start:pos ~subj ovector callout;
-- false
-- with Not_found -> true
-- then string_unsafe_sub subj pos len :: strs
-- else
-- let first = Array.unsafe_get ovector 0 in
-- let last = Array.unsafe_get ovector 1 in
-- if first = pos then
-- if last = pos then
-- let strs = if prematch then handle_subgroups strs else strs in
-- if len = 0 then "" :: strs
-- else if
-- try
-- unsafe_pcre_exec
-- (flags lor 0x0410) rex ~pos ~subj_start:pos ~subj
-- ovector callout;
-- true
-- with Not_found -> false
-- then
-- let new_strs = handle_subgroups ("" :: strs) in
-- loop new_strs (cnt - 1) (Array.unsafe_get ovector 1) false
-- else
-- let new_strs = string_unsafe_sub subj pos 1 :: strs in
-- loop new_strs (cnt - 1) (pos + 1) true
-- else
-- if prematch then loop (handle_subgroups strs) cnt last false
-- else loop (handle_subgroups ("" :: strs)) (cnt - 1) last false
-- else
-- let new_strs = string_unsafe_sub subj pos (first - pos) :: strs in
-- loop (handle_subgroups new_strs) (cnt - 1) last false in
-- loop [] (max - 1) pos false
--
--let rec strip_all_empty = function "" :: t -> strip_all_empty t | l -> l
--
--external isspace : char -> bool = "pcre_isspace_stub" @noalloc@
--
--let rec find_no_space ix len str =
-- if ix = len || not (isspace (String.unsafe_get str ix)) then ix
-- else find_no_space (ix + 1) len str
--
--let split ?(iflags = 0) ?flags ?rex ?pat ?(pos = 0) ?(max = 0) ?callout subj =
-- let iflags = match flags with Some flags -> rflags flags | _ -> iflags in
-- let res =
-- match pat, rex with
-- | Some str, _ -> internal_psplit iflags (regexp str) max pos callout subj
-- | _, Some rex -> internal_psplit iflags rex max pos callout subj
-- | _ ->
-- (* special case for Perl-splitting semantics *)
-- let len = String.length subj in
-- if pos > len || pos < 0 then failwith "Pcre.split: illegal offset";
-- let new_pos = find_no_space pos len subj in
-- internal_psplit iflags def_rex max new_pos callout subj in
-- List.rev (if max = 0 then strip_all_empty res else res)
--
--let asplit ?iflags ?flags ?rex ?pat ?pos ?max ?callout subj =
-- Array.of_list (split ?iflags ?flags ?rex ?pat ?pos ?max ?callout subj)
--
--
--(* Full splitting *)
--
--type split_result = Text of string
-- | Delim of string
-- | Group of int * string
-- | NoGroup
--
--let rec strip_all_empty_full = function
-- | Delim _ :: rest -> strip_all_empty_full rest
-- | l -> l
--
--let full_split ?(iflags = 0) ?flags ?(rex = def_rex) ?pat
-- ?(pos = 0) ?(max = 0) ?callout subj =
-- let rex = match pat with Some str -> regexp str | _ -> rex in
-- let iflags = match flags with Some flags -> rflags flags | _ -> iflags in
-- let subj_len = String.length subj in
-- if subj_len = 0 then []
-- else if max = 1 then [Text (subj)]
-- else
-- let subgroups2, ovector = make_ovector rex in
--
-- (* Adds contents of subgroups to the string accumulator *)
-- let handle_subgroups strs =
-- let strs = ref strs in
-- let i = ref 2 in
-- while !i < subgroups2 do
-- let group_nr = !i lsr 1 in
-- let first = Array.unsafe_get ovector !i in
-- incr i;
-- let last = Array.unsafe_get ovector !i in
-- let str =
-- if first < 0 then NoGroup
-- else
-- let group_str = string_unsafe_sub subj first (last - first) in
-- Group (group_nr, group_str) in
-- strs := str :: !strs; incr i
-- done;
-- !strs in
--
-- (* Performs the recursive split *)
-- let rec loop strs cnt pos prematch =
-- let len = subj_len - pos in
-- if len < 0 then strs
-- else
-- (* Checks termination due to max restriction *)
-- if cnt = 0 then
-- if prematch &&
-- try
-- unsafe_pcre_exec
-- iflags rex ~pos ~subj_start:pos ~subj ovector callout;
-- true
-- with Not_found -> false
-- then
-- let first = Array.unsafe_get ovector 0 in
-- let last = Array.unsafe_get ovector 1 in
-- let delim = Delim (string_unsafe_sub subj first (last - first)) in
-- Text (string_unsafe_sub subj last (subj_len - last))
-- :: handle_subgroups (delim :: strs)
-- else
-- if len = 0 then strs
-- else Text (string_unsafe_sub subj pos len) :: strs
--
-- (* Calculates next accumulator state for splitting *)
-- else
-- if
-- try
-- unsafe_pcre_exec
-- iflags rex ~pos ~subj_start:pos ~subj ovector callout;
-- false
-- with Not_found -> true
-- then
-- if len = 0 then strs
-- else Text (string_unsafe_sub subj pos len) :: strs
-- else
-- let first = Array.unsafe_get ovector 0 in
-- let last = Array.unsafe_get ovector 1 in
-- if first = pos then
-- if last = pos then
-- if len = 0 then handle_subgroups (Delim "" :: strs)
-- else
-- let empty_groups = handle_subgroups [] in
-- if
-- try
-- unsafe_pcre_exec
-- (iflags lor 0x0410) rex ~pos ~subj_start:pos ~subj
-- ovector callout;
-- true
-- with Not_found -> false
-- then
-- let first = Array.unsafe_get ovector 0 in
-- let last = Array.unsafe_get ovector 1 in
-- let delim =
-- Delim (string_unsafe_sub subj first (last - first)) in
-- let new_strs =
-- handle_subgroups (
-- delim :: (if prematch then strs
-- else empty_groups @ (Delim "" :: strs))) in
-- loop new_strs (cnt - 1) last false
-- else
-- let new_strs =
-- Text (string_unsafe_sub subj pos 1)
-- :: empty_groups @ Delim "" :: strs in
-- loop new_strs (cnt - 1) (pos + 1) true
-- else
-- let delim =
-- Delim (string_unsafe_sub subj first (last - first)) in
-- loop (handle_subgroups (delim :: strs)) cnt last false
-- else
-- let delim = Delim (string_unsafe_sub subj first (last - first)) in
-- let pre_strs =
-- Text (string_unsafe_sub subj pos (first - pos)) :: strs in
-- loop
-- (handle_subgroups (delim :: pre_strs)) (cnt - 1) last false in
-- let res = loop [] (max - 1) pos true in
-- List.rev (if max = 0 then strip_all_empty_full res else res)
--
--
--(* Additional convenience functions useful in combination with this library *)
--
--let foreach_line ?(ic = stdin) f =
-- try while true do f (input_line ic) done with End_of_file -> ()
--
--let foreach_file filenames f =
-- let do_with_file filename =
-- let file = open_in filename in
-- try f filename file; close_in file
-- with exn -> close_in file; raise exn in
-- List.iter do_with_file filenames
-diff --git a/bundles/pcre/pcre-ocaml/src/pcre.mli b/bundles/pcre/pcre-ocaml/src/pcre.mli
-deleted file mode 100644
-index 5047bb865..000000000
---- a/bundles/pcre/pcre-ocaml/src/pcre.mli
-+++ /dev/null
-@@ -1,930 +0,0 @@
--(*
-- PCRE-OCAML - Perl Compatibility Regular Expressions for OCaml
--
-- Copyright (C) 1999- Markus Mottl
-- email: markus.mottl@gmail.com
-- WWW: http://www.ocaml.info
--
-- This library is free software; you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public
-- License as published by the Free Software Foundation; either
-- version 2.1 of the License, or (at your option) any later version.
--
-- This library is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- Lesser General Public License for more details.
--
-- You should have received a copy of the GNU Lesser General Public
-- License along with this library; if not, write to the Free Software
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--*)
--
--(** Perl Compatibility Regular Expressions for OCaml
--
-- {e %%VERSION%% - {{:%%PKG_HOMEPAGE%%}homepage}}
--*)
--
--
--(** {6 Exceptions} *)
--
--type error =
-- | Partial (** String only matched the pattern partially *)
-- | BadPartial (** Pattern contains items that cannot be used together
-- with partial matching. *)
-- | BadPattern of string * int (** [BadPattern (msg, pos)] regular
-- expression is malformed. The reason
-- is in [msg], the position of the
-- error in the pattern in [pos]. *)
-- | BadUTF8 (** UTF8 string being matched is invalid *)
-- | BadUTF8Offset (** Gets raised when a UTF8 string being matched with
-- offset is invalid. *)
-- | MatchLimit (** Maximum allowed number of match attempts with
-- backtracking or recursion is reached during matching.
-- ALL FUNCTIONS CALLING THE MATCHING ENGINE MAY RAISE
-- IT!!! *)
-- | RecursionLimit
-- | InternalError of string
-- (** [InternalError msg] C-library exhibits unknown/undefined
-- behaviour. The reason is in [msg]. *)
--
--(** Exception indicating PCRE errors. *)
--exception Error of error
--
--(** [Backtrack] used in callout functions to force backtracking. *)
--exception Backtrack
--
--(** [Regexp_or (pat, error)] gets raised for sub-pattern [pat] by [regexp_or]
-- if it failed to compile. *)
--exception Regexp_or of string * error
--
--(** {6 Compilation and runtime flags and their conversion functions} *)
--
--(** Internal representation of compilation flags *)
--type icflag
--
--(** Internal representation of runtime flags *)
--and irflag
--
--(** Compilation flags *)
--and cflag =
-- [ `CASELESS (** Case insensitive matching *)
-- | `MULTILINE (** '^' and '$' match before/after newlines,
-- not just at the beginning/end of a string *)
-- | `DOTALL (** '.' matches all characters (newlines, too) *)
-- | `EXTENDED (** Ignores whitespace and PERL-comments. Behaves
-- like the '/x'-option in PERL *)
-- | `ANCHORED (** Pattern matches only at start of string *)
-- | `DOLLAR_ENDONLY (** '$' in pattern matches only at end of string *)
-- | `EXTRA (** Reserved for future extensions of PCRE *)
-- | `UNGREEDY (** Quantifiers not greedy anymore, only
-- if followed by '?' *)
-- | `UTF8 (** Treats patterns and strings as UTF8 characters. *)
-- | `NO_UTF8_CHECK (** Turns off validity checks on UTF8 strings for
-- efficiency reasons. WARNING: invalid UTF8
-- strings may cause a crash then! *)
-- | `NO_AUTO_CAPTURE (** Disables the use of numbered capturing parentheses *)
-- | `AUTO_CALLOUT (** Automatically inserts callouts with id 255
-- before each pattern item *)
-- | `FIRSTLINE (** Unanchored patterns must match before/at first NL *)
-- ]
--
--val cflags : cflag list -> icflag
--(** [cflags cflag_list] converts a list of compilation flags to
-- their internal representation. *)
--
--val cflag_list : icflag -> cflag list
--(** [cflag_list cflags] converts internal representation of
-- compilation flags to a list. *)
--
--(** Runtime flags *)
--type rflag =
-- [ `ANCHORED (** Treats pattern as if it were anchored *)
-- | `NOTBOL (** Beginning of string is not treated as beginning of line *)
-- | `NOTEOL (** End of string is not treated as end of line *)
-- | `NOTEMPTY (** Empty strings are not considered to be a valid match *)
-- | `PARTIAL (** Turns on partial matching *)
-- ]
--
--val rflags : rflag list -> irflag
--(** [rflags rflag_list] converts a list of runtime flags to
-- their internal representation. *)
--
--val rflag_list : irflag -> rflag list
--(** [rflag_list rflags] converts internal representation of
-- runtime flags to a list. *)
--
--
--(** {6 Information on the PCRE-configuration (build-time options)} *)
--
--(** Version information *)
--val version : string (** Version of the PCRE-C-library *)
--
--(** Indicates whether UTF8-support is enabled *)
--val config_utf8 : bool
--
--(** Character used as newline *)
--val config_newline : char
--
--(** Number of bytes used for internal linkage of regular expressions *)
--val config_link_size : int
--
--(** Default limit for calls to internal matching function *)
--val config_match_limit : int
--
--(** Default limit recursion for calls to internal matching function *)
--val config_match_limit_recursion : int
--
--(** Indicates use of stack recursion in matching function *)
--val config_stackrecurse : bool
--
--
--(** {6 Information on patterns} *)
--
--(** Information on matching of "first chars" in patterns *)
--type firstbyte_info =
-- [ `Char of char (** Fixed first character *)
-- | `Start_only (** Pattern matches at beginning and end of newlines *)
-- | `ANCHORED (** Pattern is anchored *)
-- ]
--
--(** Information on the study status of patterns *)
--type study_stat =
-- [ `Not_studied (** Pattern has not yet been studied *)
-- | `Studied (** Pattern has been studied successfully *)
-- | `Optimal (** Pattern could not be improved by studying *)
-- ]
--
--type regexp (** Compiled regular expressions *)
--
--(** [options regexp] @return compilation flags of [regexp]. *)
--val options : regexp -> icflag
--
--(** [size regexp] @return memory size of [regexp]. *)
--val size : regexp -> int
--
--(** [studysize regexp] @return memory size of study information of [regexp]. *)
--val studysize : regexp -> int
--
--(** [capturecount regexp] @return number of capturing subpatterns in
-- [regexp]. *)
--val capturecount : regexp -> int
--
--(** [backrefmax regexp] @return number of highest backreference in [regexp]. *)
--val backrefmax : regexp -> int
--
--(** [namecount regexp] @return number of named subpatterns in [regexp]. *)
--val namecount : regexp -> int
--
--(** [nameentrysize regexp] @return size of longest name of named
-- subpatterns in [regexp] + 3. *)
--val nameentrysize : regexp -> int
--
--(** [names regex] @return array of names of named substrings in [regexp]. *)
--val names : regexp -> string array
--
--(** [firstbyte regexp] @return firstbyte info on [regexp]. *)
--val firstbyte : regexp -> firstbyte_info
--
--(** [firsttable regexp] @return some 256-bit (32-byte) fixed set table in
-- form of a string for [regexp] if available, [None] otherwise. *)
--val firsttable : regexp -> string option
--
--(** [lastliteral regexp] @return some last matching character of [regexp]
-- if available, [None] otherwise. *)
--val lastliteral : regexp -> char option
--
--(** [study_stat regexp] @return study status of [regexp]. *)
--val study_stat : regexp -> study_stat
--
--val get_stringnumber : regexp -> string -> int
--(** [get_stringnumber rex name] @return the index of the named substring
-- [name] in regular expression [rex]. This index can then be used with
-- [get_substring].
--
-- @raise Invalid_arg if there is no such named substring. *)
--
--val get_match_limit : regexp -> int option
--(** [get_match_limit rex] @return some match limit of regular expression
-- [rex] or [None]. *)
--
--val get_match_limit_recursion : regexp -> int option
--(** [get_match_limit_recursion rex] @return some recursion match limit
-- of regular expression [rex] or [None]. *)
--
--
--(** {6 Compilation of patterns} *)
--
--type chtables (** Alternative set of char tables for pattern matching *)
--
--val maketables : unit -> chtables
--(** Generates new set of char tables for the current locale. *)
--
--val regexp :
-- ?study : bool ->
-- ?limit : int ->
-- ?limit_recursion : int ->
-- ?iflags : icflag ->
-- ?flags : cflag list ->
-- ?chtables : chtables ->
-- string -> regexp
--(** [regexp ?study ?limit ?limit_recursion ?iflags ?flags ?chtables pattern]
-- compiles [pattern] with [flags] when given, with [iflags] otherwise, and
-- with char tables [chtables]. If [study] is true, then the resulting regular
-- expression will be studied. If [limit] is specified, this sets a limit to
-- the amount of recursion and backtracking (only lower than the builtin
-- default!). If this limit is exceeded, [MatchLimit] will be raised during
-- matching.
--
-- @param study default = true
-- @param limit default = no extra limit other than default
-- @param limit_recursion default = no extra limit_recursion other than default
-- @param iflags default = no extra flags
-- @param flags default = ignored
-- @param chtables default = builtin char tables
--
-- @return the regular expression.
--
-- For detailed documentation on how you can specify PERL-style regular
-- expressions (= patterns), please consult the PCRE-documentation
-- ("man pcrepattern") or PERL-manuals.
-- @see <http://www.perl.com> www.perl.com *)
--
--val regexp_or :
-- ?study : bool ->
-- ?limit : int ->
-- ?limit_recursion : int ->
-- ?iflags : icflag ->
-- ?flags : cflag list ->
-- ?chtables : chtables ->
-- string list -> regexp
--(** [regexp_or ?study ?limit ?limit_recursion ?iflags ?flags ?chtables patterns]
-- like {!regexp}, but combines [patterns] as alternatives (or-patterns) into
-- one regular expression. *)
--
--val quote : string -> string
--(** [quote str] @return the quoted string of [str]. *)
--
--
--(** {6 Subpattern extraction} *)
--
--type substrings (** Information on substrings after pattern matching *)
--
--val get_subject : substrings -> string
--(** [get_subject substrings] @return the subject string of [substrings]. *)
--
--val num_of_subs : substrings -> int
--(** [num_of_subs substrings] @return number of strings in [substrings]
-- (whole match inclusive). *)
--
--val get_substring : substrings -> int -> string
--(** [get_substring substrings n] @return the [n]th substring
-- (0 is whole match) of [substrings].
--
-- @raise Invalid_argument if [n] is not in the range of the number of
-- substrings.
-- @raise Not_found if the corresponding subpattern did not capture
-- a substring. *)
--
--val get_substring_ofs : substrings -> int -> int * int
--(** [get_substring_ofs substrings n] @return the offset tuple of the
-- [n]th substring of [substrings] (0 is whole match).
--
-- @raise Invalid_argument if [n] is not in the range of the number
-- of substrings.
-- @raise Not_found if the corresponding subpattern did not capture
-- a substring. *)
--
--val get_substrings :
-- ?full_match : bool ->
-- substrings -> string array
--(** [get_substrings ?full_match substrings] @return the array of
-- substrings in [substrings]. It includes the full match at index 0
-- when [full_match] is [true], the captured substrings only when it
-- is [false]. If a subpattern did not capture a substring, the empty
-- string is returned in the corresponding position instead.
--
-- @param full_match default = true *)
--
--val get_opt_substrings :
-- ?full_match : bool ->
-- substrings -> string option array
--(** [get_opt_substrings ?full_match substrings] @return the array of
-- optional substrings in [substrings]. It includes [Some full_match_str]
-- at index 0 when [full_match] is [true], [Some captured_substrings]
-- only when it is [false]. If a subpattern did not capture a substring,
-- [None] is returned in the corresponding position instead.
--
-- @param full_match default = true *)
--
--val get_named_substring : regexp -> string -> substrings -> string
--(** [get_named_substring rex name substrings] @return the named substring
-- [name] in regular expression [rex] and [substrings].
--
-- @raise Invalid_argument if there is no such named substring.
-- @raise Not_found if the corresponding subpattern did not capture
-- a substring. *)
--
--val get_named_substring_ofs : regexp -> string -> substrings -> int * int
--(** [get_named_substring_ofs rex name substrings] @return the offset
-- tuple of the named substring [name] in regular expression [rex] and
-- [substrings].
--
-- @raise Invalid_argument if there is no such named substring.
-- @raise Not_found if the corresponding subpattern did not capture
-- a substring. *)
--
--
--(** {6 Callouts} *)
--
--type callout_data =
-- {
-- callout_number : int; (** Callout number *)
-- substrings : substrings; (** Substrings matched so far *)
-- start_match : int; (** Subject start offset of current match attempt *)
-- current_position : int; (** Subject offset of current match pointer *)
-- capture_top : int; (** Number of the highest captured substring so far *)
-- capture_last : int; (** Number of the most recently captured substring *)
-- pattern_position : int; (** Offset of next match item in pattern string *)
-- next_item_length : int; (** Length of next match item in pattern string *)
-- }
--
--(** Type of callout functions *)
--type callout = callout_data -> unit
--(** Callouts are referred to in patterns as "(?Cn)" where "n" is a
-- [callout_number] ranging from 0 to 255. Substrings captured so far
-- are accessible as usual via [substrings]. You will have to consider
-- [capture_top] and [capture_last] to know about the current state of
-- valid substrings.
--
-- By raising exception [Backtrack] within a callout function, the user
-- can force the pattern matching engine to backtrack to other possible
-- solutions. Other exceptions will terminate matching immediately
-- and return control to OCaml.
--*)
--
--
--(** {6 Matching of patterns and subpattern extraction} *)
--
--val pcre_exec :
-- ?iflags : irflag ->
-- ?flags : rflag list ->
-- ?rex : regexp ->
-- ?pat : string ->
-- ?pos : int ->
-- ?callout : callout ->
-- string -> int array
--(** [pcre_exec ?iflags ?flags ?rex ?pat ?pos ?callout subj] @return an
-- array of offsets that describe the position of matched subpatterns in
-- the string [subj] starting at position [pos] with pattern [pat] when
-- given, regular expression [rex] otherwise. The array also contains
-- additional workspace needed by the match engine. Uses [flags] when
-- given, the precompiled [iflags] otherwise. Callouts are handled by
-- [callout].
--
-- @param iflags default = no extra flags
-- @param flags default = ignored
-- @param rex default = matches whitespace
-- @param pat default = ignored
-- @param pos default = 0
-- @param callout default = ignore callouts
--
-- @raise Not_found if pattern does not match. *)
--
--val exec :
-- ?iflags : irflag ->
-- ?flags : rflag list ->
-- ?rex : regexp ->
-- ?pat : string ->
-- ?pos : int ->
-- ?callout : callout ->
-- string -> substrings
--(** [exec ?iflags ?flags ?rex ?pat ?pos ?callout subj] @return substring
-- information on string [subj] starting at position [pos] with pattern
-- [pat] when given, regular expression [rex] otherwise. Uses [flags]
-- when given, the precompiled [iflags] otherwise. Callouts are handled
-- by [callout].
--
-- @param iflags default = no extra flags
-- @param flags default = ignored
-- @param rex default = matches whitespace
-- @param pat default = ignored
-- @param pos default = 0
-- @param callout default = ignore callouts
--
-- @raise Not_found if pattern does not match. *)
--
--val exec_all :
-- ?iflags : irflag ->
-- ?flags : rflag list ->
-- ?rex : regexp ->
-- ?pat : string ->
-- ?pos : int ->
-- ?callout : callout ->
-- string -> substrings array
--(** [exec_all ?iflags ?flags ?rex ?pat ?pos ?callout subj] @return
-- an array of substring information of all matching substrings in
-- string [subj] starting at position [pos] with pattern [pat] when
-- given, regular expression [rex] otherwise. Uses [flags] when given,
-- the precompiled [iflags] otherwise. Callouts are handled by [callout].
--
-- @param iflags default = no extra flags
-- @param flags default = ignored
-- @param rex default = matches whitespace
-- @param pat default = ignored
-- @param pos default = 0
-- @param callout default = ignore callouts
--
-- @raise Not_found if pattern does not match. *)
--
--val next_match :
-- ?iflags : irflag ->
-- ?flags : rflag list ->
-- ?rex : regexp ->
-- ?pat : string ->
-- ?pos : int ->
-- ?callout : callout ->
-- substrings -> substrings
--(** [next_match ?iflags ?flags ?rex ?pat ?pos ?callout substrs] @return
-- substring information on the match that follows on the last
-- match denoted by [substrs], jumping over [pos] characters (also
-- backwards!), using pattern [pat] when given, regular expression
-- [rex] otherwise. Uses [flags] when given, the precompiled [iflags]
-- otherwise. Callouts are handled by [callout].
--
-- @param iflags default = no extra flags
-- @param flags default = ignored
-- @param rex default = matches whitespace
-- @param pat default = ignored
-- @param pos default = 0
-- @param callout default = ignore callouts
--
-- @raise Not_found if pattern does not match.
-- @raise Invalid_arg if [pos] let matching start outside of
-- the subject string. *)
--
--val extract :
-- ?iflags : irflag ->
-- ?flags : rflag list ->
-- ?rex : regexp ->
-- ?pat : string ->
-- ?pos : int ->
-- ?full_match : bool ->
-- ?callout : callout ->
-- string -> string array
--(** [extract ?iflags ?flags ?rex ?pat ?pos ?full_match ?callout subj]
-- @return the array of substrings that match [subj] starting at
-- position [pos], using pattern [pat] when given, regular expression
-- [rex] otherwise. Uses [flags] when given, the precompiled [iflags]
-- otherwise. It includes the full match at index 0 when [full_match] is
-- [true], the captured substrings only when it is [false]. Callouts are
-- handled by [callout]. If a subpattern did not capture a substring,
-- the empty string is returned in the corresponding position instead.
--
-- @param iflags default = no extra flags
-- @param flags default = ignored
-- @param rex default = matches whitespace
-- @param pat default = ignored
-- @param pos default = 0
-- @param full_match default = true
-- @param callout default = ignore callouts
--
-- @raise Not_found if pattern does not match. *)
--
--val extract_opt :
-- ?iflags : irflag ->
-- ?flags : rflag list ->
-- ?rex : regexp ->
-- ?pat : string ->
-- ?pos : int ->
-- ?full_match : bool ->
-- ?callout : callout ->
-- string -> string option array
--(** [extract_opt ?iflags ?flags ?rex ?pat ?pos ?full_match ?callout subj]
-- @return the array of optional substrings that match [subj] starting
-- at position [pos], using pattern [pat] when given, regular expression
-- [rex] otherwise. Uses [flags] when given, the precompiled [iflags]
-- otherwise. It includes [Some full_match_str] at index 0 when
-- [full_match] is [true], [Some captured-substrings] only when it is
-- [false]. Callouts are handled by [callout]. If a subpattern did
-- not capture a substring, [None] is returned in the corresponding
-- position instead.
--
-- @param iflags default = no extra flags
-- @param flags default = ignored
-- @param rex default = matches whitespace
-- @param pat default = ignored
-- @param pos default = 0
-- @param full_match default = true
-- @param callout default = ignore callouts
--
-- @raise Not_found if pattern does not match. *)
--
--val extract_all :
-- ?iflags : irflag ->
-- ?flags : rflag list ->
-- ?rex : regexp ->
-- ?pat : string ->
-- ?pos : int ->
-- ?full_match : bool ->
-- ?callout : callout ->
-- string -> string array array
--(** [extract_all ?iflags ?flags ?rex ?pat ?pos ?full_match ?callout subj]
-- @return an array of arrays of all matching substrings that match
-- [subj] starting at position [pos], using pattern [pat] when given,
-- regular expression [rex] otherwise. Uses [flags] when given, the
-- precompiled [iflags] otherwise. It includes the full match at index
-- 0 of the extracted string arrays when [full_match] is [true], the
-- captured substrings only when it is [false]. Callouts are handled by
-- [callout].
--
-- @param iflags default = no extra flags
-- @param flags default = ignored
-- @param rex default = matches whitespace
-- @param pat default = ignored
-- @param pos default = 0
-- @param full_match default = true
-- @param callout default = ignore callouts
--
-- @raise Not_found if pattern does not match. *)
--
--val extract_all_opt :
-- ?iflags : irflag ->
-- ?flags : rflag list ->
-- ?rex : regexp ->
-- ?pat : string ->
-- ?pos : int ->
-- ?full_match : bool ->
-- ?callout : callout ->
-- string -> string option array array
--(** [extract_all_opt
-- ?iflags ?flags ?rex ?pat ?pos ?full_match ?callout subj]
-- @return an array of arrays of all optional matching substrings that
-- match [subj] starting at position [pos], using pattern [pat] when
-- given, regular expression [rex] otherwise. Uses [flags] when given,
-- the precompiled [iflags] otherwise. It includes [Some full_match_str]
-- at index 0 of the extracted string arrays when [full_match] is [true],
-- [Some captured_substrings] only when it is [false]. Callouts are
-- handled by [callout]. If a subpattern did not capture a substring,
-- [None] is returned in the corresponding position instead.
--
-- @param iflags default = no extra flags
-- @param flags default = ignored
-- @param rex default = matches whitespace
-- @param pat default = ignored
-- @param pos default = 0
-- @param full_match default = true
-- @param callout default = ignore callouts
--
-- @raise Not_found if pattern does not match. *)
--
--val pmatch :
-- ?iflags : irflag ->
-- ?flags : rflag list ->
-- ?rex : regexp ->
-- ?pat : string ->
-- ?pos : int ->
-- ?callout : callout ->
-- string -> bool
--(** [pmatch ?iflags ?flags ?rex ?pat ?pos ?callout subj] @return [true]
-- if [subj] is matched by pattern [pat] when given, regular expression
-- [rex] otherwise, starting at position [pos]. Uses [flags] when given,
-- the precompiled [iflags] otherwise. Callouts are handled by [callout].
--
-- @param iflags default = no extra flags
-- @param flags default = ignored
-- @param rex default = matches whitespace
-- @param pat default = ignored
-- @param pos default = 0
-- @param callout default = ignore callouts *)
--
--
--(** {6 String substitution} *)
--
--(** Information on substitution patterns *)
--type substitution
--
--val subst : string -> substitution
--(** [subst str] converts the string [str] representing a
-- substitution pattern to the internal representation
--
-- The contents of the substitution string [str] can be normal text
-- mixed with any of the following (mostly as in PERL):
--
-- - {e $\[0-9\]+} - a "$" immediately followed by an arbitrary number.
-- "$0" stands for the name of the executable,
-- any other number for the n-th backreference.
-- - {e $&} - the whole matched pattern
-- - {e $`} - the text before the match
-- - {e $'} - the text after the match
-- - {e $+} - the last group that matched
-- - {e $$} - a single "$"
-- - {e $!} - delimiter which does not appear in the substitution.
-- Can be used to part "$[0-9]+" from an immediately
-- following other number. *)
--
--val replace :
-- ?iflags : irflag ->
-- ?flags : rflag list ->
-- ?rex : regexp ->
-- ?pat : string ->
-- ?pos : int ->
-- ?itempl : substitution ->
-- ?templ : string ->
-- ?callout : callout ->
-- string -> string
--(** [replace ?iflags ?flags ?rex ?pat ?pos ?itempl ?templ ?callout subj]
-- replaces all substrings of [subj] matching pattern [pat] when given,
-- regular expression [rex] otherwise, starting at position [pos] with
-- the substitution string [templ] when given, [itempl] otherwise. Uses
-- [flags] when given, the precompiled [iflags] otherwise. Callouts
-- are handled by [callout].
--
-- @param iflags default = no extra flags
-- @param flags default = ignored
-- @param rex default = matches whitespace
-- @param pat default = ignored
-- @param pos default = 0
-- @param itempl default = empty string
-- @param templ default = ignored
-- @param callout default = ignore callouts
--
-- @raise Failure if there are backreferences to nonexistent subpatterns. *)
--
--val qreplace :
-- ?iflags : irflag ->
-- ?flags : rflag list ->
-- ?rex : regexp ->
-- ?pat : string ->
-- ?pos : int ->
-- ?templ : string ->
-- ?callout : callout ->
-- string -> string
--(** [qreplace ?iflags ?flags ?rex ?pat ?pos ?templ ?callout subj]
-- replaces all substrings of [subj] matching pattern [pat] when given,
-- regular expression [rex] otherwise, starting at position [pos]
-- with the string [templ]. Uses [flags] when given, the precompiled
-- [iflags] otherwise. Callouts are handled by [callout].
--
-- @param iflags default = no extra flags
-- @param flags default = ignored
-- @param rex default = matches whitespace
-- @param pat default = ignored
-- @param pos default = 0
-- @param templ default = ignored
-- @param callout default = ignore callouts *)
--
--val substitute_substrings :
-- ?iflags : irflag ->
-- ?flags : rflag list ->
-- ?rex : regexp ->
-- ?pat : string ->
-- ?pos : int ->
-- ?callout : callout ->
-- subst : (substrings -> string) ->
-- string -> string
--(** [substitute_substrings ?iflags ?flags ?rex ?pat ?pos ?callout ~subst subj]
-- replaces all substrings of [subj] matching pattern [pat] when given,
-- regular expression [rex] otherwise, starting at position [pos]
-- with the result of function [subst] applied to the substrings
-- of the match. Uses [flags] when given, the precompiled [iflags]
-- otherwise. Callouts are handled by [callout].
--
-- @param iflags default = no extra flags
-- @param flags default = ignored
-- @param rex default = matches whitespace
-- @param pat default = ignored
-- @param pos default = 0
-- @param callout default = ignore callouts *)
--
--val substitute :
-- ?iflags : irflag ->
-- ?flags : rflag list ->
-- ?rex : regexp ->
-- ?pat : string ->
-- ?pos : int ->
-- ?callout : callout ->
-- subst : (string -> string) ->
-- string -> string
--(** [substitute ?iflags ?flags ?rex ?pat ?pos ?callout ~subst subj]
-- replaces all substrings of [subj] matching pattern [pat] when given,
-- regular expression [rex] otherwise, starting at position [pos] with
-- the result of function [subst] applied to the match. Uses [flags]
-- when given, the precompiled [iflags] otherwise. Callouts are handled
-- by [callout].
--
-- @param iflags default = no extra flags
-- @param flags default = ignored
-- @param rex default = matches whitespace
-- @param pat default = ignored
-- @param pos default = 0
-- @param callout default = ignore callouts *)
--
--val replace_first :
-- ?iflags : irflag ->
-- ?flags : rflag list ->
-- ?rex : regexp ->
-- ?pat : string ->
-- ?pos : int ->
-- ?itempl : substitution ->
-- ?templ : string ->
-- ?callout : callout ->
-- string -> string
--(** [replace_first ?iflags ?flags ?rex ?pat ?pos ?itempl ?templ ?callout subj]
-- replaces the first substring of [subj] matching pattern [pat] when
-- given, regular expression [rex] otherwise, starting at position
-- [pos] with the substitution string [templ] when given, [itempl]
-- otherwise. Uses [flags] when given, the precompiled [iflags]
-- otherwise. Callouts are handled by [callout].
--
-- @param iflags default = no extra flags
-- @param flags default = ignored
-- @param rex default = matches whitespace
-- @param pat default = ignored
-- @param pos default = 0
-- @param itempl default = empty string
-- @param templ default = ignored
-- @param callout default = ignore callouts
--
-- @raise Failure if there are backreferences to nonexistent subpatterns. *)
--
--val qreplace_first :
-- ?iflags : irflag ->
-- ?flags : rflag list ->
-- ?rex : regexp ->
-- ?pat : string ->
-- ?pos : int ->
-- ?templ : string ->
-- ?callout : callout ->
-- string -> string
--(** [qreplace_first ?iflags ?flags ?rex ?pat ?pos ?templ ?callout subj]
-- replaces the first substring of [subj] matching pattern [pat] when
-- given, regular expression [rex] otherwise, starting at position [pos]
-- with the string [templ]. Uses [flags] when given, the precompiled
-- [iflags] otherwise. Callouts are handled by [callout].
--
-- @param iflags default = no extra flags
-- @param flags default = ignored
-- @param rex default = matches whitespace
-- @param pat default = ignored
-- @param pos default = 0
-- @param templ default = ignored
-- @param callout default = ignore callouts *)
--
--val substitute_substrings_first :
-- ?iflags : irflag ->
-- ?flags : rflag list ->
-- ?rex : regexp ->
-- ?pat : string ->
-- ?pos : int ->
-- ?callout : callout ->
-- subst : (substrings -> string) ->
-- string -> string
--(** [substitute_substrings_first
-- ?iflags ?flags ?rex ?pat ?pos ?callout ~subst subj]
-- replaces the first substring of [subj] matching pattern [pat] when
-- given, regular expression [rex] otherwise, starting at position
-- [pos] with the result of function [subst] applied to the substrings
-- of the match. Uses [flags] when given, the precompiled [iflags]
-- otherwise. Callouts are handled by [callout].
--
-- @param iflags default = no extra flags
-- @param flags default = ignored
-- @param rex default = matches whitespace
-- @param pat default = ignored
-- @param pos default = 0
-- @param callout default = ignore callouts *)
--
--val substitute_first :
-- ?iflags : irflag ->
-- ?flags : rflag list ->
-- ?rex : regexp ->
-- ?pat : string ->
-- ?pos : int ->
-- ?callout : callout ->
-- subst : (string -> string) ->
-- string -> string
--(** [substitute_first ?iflags ?flags ?rex ?pat ?pos ?callout ~subst subj]
-- replaces the first substring of [subj] matching pattern [pat] when
-- given, regular expression [rex] otherwise, starting at position
-- [pos] with the result of function [subst] applied to the match. Uses
-- [flags] when given, the precompiled [iflags] otherwise. Callouts
-- are handled by [callout].
--
-- @param iflags default = no extra flags
-- @param flags default = ignored
-- @param rex default = matches whitespace
-- @param pat default = ignored
-- @param pos default = 0
-- @param callout default = ignore callouts *)
--
--
--(** {6 Splitting} *)
--
--val split :
-- ?iflags : irflag ->
-- ?flags : rflag list ->
-- ?rex : regexp ->
-- ?pat : string ->
-- ?pos : int ->
-- ?max : int ->
-- ?callout : callout ->
-- string -> string list
--(** [split ?iflags ?flags ?rex ?pat ?pos ?max ?callout subj] splits [subj]
-- into a list of at most [max] strings, using as delimiter pattern
-- [pat] when given, regular expression [rex] otherwise, starting at
-- position [pos]. Uses [flags] when given, the precompiled [iflags]
-- otherwise. If [max] is zero, trailing empty fields are stripped. If
-- it is negative, it is treated as arbitrarily large. If neither [pat]
-- nor [rex] are specified, leading whitespace will be stripped! Should
-- behave exactly as in PERL. Callouts are handled by [callout].
--
-- @param iflags default = no extra flags
-- @param flags default = ignored
-- @param rex default = matches whitespace
-- @param pat default = ignored
-- @param pos default = 0
-- @param max default = 0
-- @param callout default = ignore callouts *)
--
--val asplit :
-- ?iflags : irflag ->
-- ?flags : rflag list ->
-- ?rex : regexp ->
-- ?pat : string ->
-- ?pos : int ->
-- ?max : int ->
-- ?callout : callout ->
-- string -> string array
--(** [asplit ?iflags ?flags ?rex ?pat ?pos ?max ?callout subj] same as
-- {!Pcre.split} but @return an array instead of a list. *)
--
--(** Result of a {!Pcre.full_split} *)
--type split_result = Text of string (** Text part of split string *)
-- | Delim of string (** Delimiter part of split string *)
-- | Group of int * string (** Subgroup of matched delimiter
-- (subgroup_nr, subgroup_str) *)
-- | NoGroup (** Unmatched subgroup *)
--
--val full_split :
-- ?iflags : irflag ->
-- ?flags : rflag list ->
-- ?rex : regexp ->
-- ?pat : string ->
-- ?pos : int ->
-- ?max : int ->
-- ?callout : callout ->
-- string -> split_result list
--(** [full_split ?iflags ?flags ?rex ?pat ?pos ?max ?callout subj] splits
-- [subj] into a list of at most [max] elements of type "split_result",
-- using as delimiter pattern [pat] when given, regular expression
-- [rex] otherwise, starting at position [pos]. Uses [flags] when given,
-- the precompiled [iflags] otherwise. If [max] is zero, trailing empty
-- fields are stripped. If it is negative, it is treated as arbitrarily
-- large. Should behave exactly as in PERL. Callouts are handled by
-- [callout].
--
-- @param iflags default = no extra flags
-- @param flags default = ignored
-- @param rex default = matches whitespace
-- @param pat default = ignored
-- @param pos default = 0
-- @param max default = 0
-- @param callout default = ignore callouts *)
--
--
--(** {6 Additional convenience functions} *)
--
--val foreach_line :
-- ?ic : in_channel ->
-- (string -> unit) -> unit
--(** [foreach_line ?ic f] applies [f] to each line in inchannel [ic] until
-- the end-of-file is reached.
--
-- @param ic default = stdin *)
--
--val foreach_file : string list -> (string -> in_channel -> unit) -> unit
--(** [foreach_file filenames f] opens each file in the list [filenames]
-- for input and applies [f] to each filename and the corresponding
-- channel. Channels are closed after each operation (even when
-- exceptions occur - they get reraised afterwards!). *)
--
--
--(** {6 {b UNSAFE STUFF - USE WITH CAUTION!}} *)
--
--val unsafe_pcre_exec :
-- irflag ->
-- regexp ->
-- pos : int ->
-- subj_start : int ->
-- subj : string ->
-- int array ->
-- callout option ->
-- unit
--(** [unsafe_pcre_exec flags rex ~pos ~subj_start ~subj offset_vector].
-- You should read the C-source to know what happens.
-- If you do not understand it - {b don't use this function!} *)
--
--val make_ovector : regexp -> int * int array
--(** [make_ovector regexp] calculates the tuple (subgroups2, ovector)
-- which is the number of subgroup offsets and the offset array. *)
-diff --git a/bundles/pcre/pcre-ocaml/src/pcre_stubs.c.in b/bundles/pcre/pcre-ocaml/src/pcre_stubs.c.in
-deleted file mode 100644
-index 66dfb7b0d..000000000
---- a/bundles/pcre/pcre-ocaml/src/pcre_stubs.c.in
-+++ /dev/null
-@@ -1,862 +0,0 @@
--/*
-- PCRE-OCAML - Perl Compatibility Regular Expressions for OCaml
--
-- Copyright (C) 1999- Markus Mottl
-- email: markus.mottl@gmail.com
-- WWW: http://www.ocaml.info
--
-- This library is free software; you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public
-- License as published by the Free Software Foundation; either
-- version 2.1 of the License, or (at your option) any later version.
--
-- This library is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- Lesser General Public License for more details.
--
-- You should have received a copy of the GNU Lesser General Public
-- License along with this library; if not, write to the Free Software
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--*/
--
--#if defined(_WIN32)
--# define snprintf _snprintf
--# if defined(_DLL)
--# define PCREextern __declspec(dllexport)
--# else
--# define PCREextern
--# endif
--#endif
--
--#if _WIN64
-- typedef long long *ovec_dst_ptr;
--#else
-- typedef long *ovec_dst_ptr;
--#endif
--
--#if __GNUC__ >= 3
--# define inline inline __attribute__ ((always_inline))
--# define __unused __attribute__ ((unused))
--#else
--# define __unused
--# define inline
--#endif
--
--#include <ctype.h>
--#include <string.h>
--#include <stdio.h>
--
--#include <caml/mlvalues.h>
--#include <caml/alloc.h>
--#include <caml/memory.h>
--#include <caml/fail.h>
--#include <caml/callback.h>
--#include <caml/custom.h>
--
--#include <pcre.h>
--
--/* Error codes as defined for pcre 7.9, undefined in pcre 4.5 */
--#ifndef PCRE_ERROR_PARTIAL
--#define PCRE_ERROR_PARTIAL (-12)
--#endif
--#ifndef PCRE_ERROR_BADPARTIAL
--#define PCRE_ERROR_BADPARTIAL (-13)
--#endif
--#ifndef PCRE_ERROR_RECURSIONLIMIT
--#define PCRE_ERROR_RECURSIONLIMIT (-21)
--#endif
--
--typedef const unsigned char *chartables; /* Type of chartable sets */
--
--/* Contents of callout data */
--struct cod {
-- long subj_start; /* Start of subject string */
-- value *v_substrings_p; /* Pointer to substrings matched so far */
-- value *v_cof_p; /* Pointer to callout function */
-- value v_exn; /* Possible exception raised by callout function */
--};
--
--/* Cache for exceptions */
--static value *pcre_exc_Error = NULL; /* Exception [Error] */
--static value *pcre_exc_Backtrack = NULL; /* Exception [Backtrack] */
--
--/* Cache for polymorphic variants */
--static value var_Start_only; /* Variant [`Start_only] */
--static value var_ANCHORED; /* Variant [`ANCHORED] */
--static value var_Char; /* Variant [`Char char] */
--static value var_Not_studied; /* Variant [`Not_studied] */
--static value var_Studied; /* Variant [`Studied] */
--static value var_Optimal; /* Variant [`Optimal] */
--
--static value None = Val_int(0);
--
--/* Data associated with OCaml values of PCRE regular expression */
--struct pcre_ocaml_regexp { pcre *rex; pcre_extra *extra; int studied; };
--
--#define Pcre_ocaml_regexp_val(v) \
-- ((struct pcre_ocaml_regexp *) Data_custom_val(v))
--
--#define get_rex(v) Pcre_ocaml_regexp_val(v)->rex
--#define get_extra(v) Pcre_ocaml_regexp_val(v)->extra
--#define get_studied(v) Pcre_ocaml_regexp_val(v)->studied
--
--#define set_rex(v, r) Pcre_ocaml_regexp_val(v)->rex = r
--#define set_extra(v, e) Pcre_ocaml_regexp_val(v)->extra = e
--#define set_studied(v, s) Pcre_ocaml_regexp_val(v)->studied = s
--
--/* Data associated with OCaml values of PCRE tables */
--struct pcre_ocaml_tables { chartables tables; };
--
--#define Pcre_ocaml_tables_val(v) \
-- ((struct pcre_ocaml_tables *) Data_custom_val(v))
--
--#define get_tables(v) Pcre_ocaml_tables_val(v)->tables
--#define set_tables(v, t) Pcre_ocaml_tables_val(v)->tables = t
--
--/* Converts subject offsets from C-integers to OCaml-Integers.
--
-- This is a bit tricky, because there are 32- and 64-bit platforms around
-- and OCaml chooses the larger possibility for representing integers when
-- available (also in arrays) - not so the PCRE!
--*/
--static inline void copy_ovector(
-- long subj_start, const int *ovec_src, ovec_dst_ptr ovec_dst, int subgroups2)
--{
-- if (subj_start == 0)
-- while (subgroups2--) {
-- *ovec_dst = Val_int(*ovec_src);
-- --ovec_src; --ovec_dst;
-- }
-- else
-- while (subgroups2--) {
-- *ovec_dst = Val_long(*ovec_src + subj_start);
-- --ovec_src; --ovec_dst;
-- }
--}
--
--/* Callout handler */
--static int pcre_callout_handler(pcre_callout_block* cb)
--{
-- struct cod *cod = (struct cod *) cb->callout_data;
--
-- if (cod != NULL) {
-- /* Callout is available */
-- value v_res;
--
-- /* Set up parameter array */
-- value v_callout_data = caml_alloc_small(8, 0);
--
-- const value v_substrings = *cod->v_substrings_p;
--
-- const int capture_top = cb->capture_top;
-- int subgroups2 = capture_top << 1;
-- const int subgroups2_1 = subgroups2 - 1;
--
-- const int *ovec_src = cb->offset_vector + subgroups2_1;
-- ovec_dst_ptr ovec_dst = &Field(Field(v_substrings, 1), 0) + subgroups2_1;
-- long subj_start = cod->subj_start;
--
-- copy_ovector(subj_start, ovec_src, ovec_dst, subgroups2);
--
-- Field(v_callout_data, 0) = Val_int(cb->callout_number);
-- Field(v_callout_data, 1) = v_substrings;
-- Field(v_callout_data, 2) = Val_int(cb->start_match + subj_start);
-- Field(v_callout_data, 3) = Val_int(cb->current_position + subj_start);
-- Field(v_callout_data, 4) = Val_int(capture_top);
-- Field(v_callout_data, 5) = Val_int(cb->capture_last);
-- Field(v_callout_data, 6) = Val_int(cb->pattern_position);
-- Field(v_callout_data, 7) = Val_int(cb->next_item_length);
--
-- /* Perform callout */
-- v_res = caml_callback_exn(*cod->v_cof_p, v_callout_data);
--
-- if (Is_exception_result(v_res)) {
-- /* Callout raised an exception */
-- const value v_exn = Extract_exception(v_res);
-- if (Field(v_exn, 0) == *pcre_exc_Backtrack) return 1;
-- cod->v_exn = v_exn;
-- return PCRE_ERROR_CALLOUT;
-- }
-- }
--
-- return 0;
--}
--
--/* Fetchs the named OCaml-values + caches them and
-- calculates + caches the variant hash values */
--CAMLprim value pcre_ocaml_init(value __unused v_unit)
--{
-- pcre_exc_Error = caml_named_value("Pcre.Error");
-- pcre_exc_Backtrack = caml_named_value("Pcre.Backtrack");
--
-- var_Start_only = caml_hash_variant("Start_only");
-- var_ANCHORED = caml_hash_variant("ANCHORED");
-- var_Char = caml_hash_variant("Char");
-- var_Not_studied = caml_hash_variant("Not_studied");
-- var_Studied = caml_hash_variant("Studied");
-- var_Optimal = caml_hash_variant("Optimal");
--
-- pcre_callout = &pcre_callout_handler;
--
-- return Val_unit;
--}
--
--/* Finalizing deallocation function for chartable sets */
--static void pcre_dealloc_tables(value v_tables)
--{ (pcre_free)((void *) get_tables(v_tables)); }
--
--/* Finalizing deallocation function for compiled regular expressions */
--static void pcre_dealloc_regexp(value v_rex)
--{
-- void *extra = get_extra(v_rex);
-- if (extra != NULL)
--#ifdef PCRE_STUDY_JIT_COMPILE
-- pcre_free_study(extra);
--#else
-- pcre_free(extra);
--#endif
-- (pcre_free)(get_rex(v_rex));
--}
--
--
--/* Raising exceptions */
--
--@CAMLnoreturn_start@
--static inline void raise_pcre_error(value v_arg)
--@CAMLnoreturn_end@;
--
--@CAMLnoreturn_start@
--static inline void raise_partial()
--@CAMLnoreturn_end@;
--
--@CAMLnoreturn_start@
--static inline void raise_bad_partial()
--@CAMLnoreturn_end@;
--
--@CAMLnoreturn_start@
--static inline void raise_bad_utf8()
--@CAMLnoreturn_end@;
--
--@CAMLnoreturn_start@
--static inline void raise_bad_utf8_offset()
--@CAMLnoreturn_end@;
--
--@CAMLnoreturn_start@
--static inline void raise_match_limit()
--@CAMLnoreturn_end@;
--
--@CAMLnoreturn_start@
--static inline void raise_recursion_limit()
--@CAMLnoreturn_end@;
--
--@CAMLnoreturn_start@
--static inline void raise_bad_pattern(const char *msg, int pos)
--@CAMLnoreturn_end@;
--
--@CAMLnoreturn_start@
--static inline void raise_internal_error(char *msg)
--@CAMLnoreturn_end@;
--
--static inline void raise_pcre_error(value v_arg)
--{ caml_raise_with_arg(*pcre_exc_Error, v_arg); }
--
--static inline void raise_partial() { raise_pcre_error(Val_int(0)); }
--static inline void raise_bad_partial() { raise_pcre_error(Val_int(1)); }
--static inline void raise_bad_utf8() { raise_pcre_error(Val_int(2)); }
--static inline void raise_bad_utf8_offset() { raise_pcre_error(Val_int(3)); }
--static inline void raise_match_limit() { raise_pcre_error(Val_int(4)); }
--static inline void raise_recursion_limit() { raise_pcre_error(Val_int(5)); }
--
--static inline void raise_bad_pattern(const char *msg, int pos)
--{
-- CAMLparam0();
-- CAMLlocal1(v_msg);
-- value v_arg;
-- v_msg = caml_copy_string(msg);
-- v_arg = caml_alloc_small(2, 0);
-- Field(v_arg, 0) = v_msg;
-- Field(v_arg, 1) = Val_int(pos);
-- raise_pcre_error(v_arg);
-- CAMLnoreturn;
--}
--
--static inline void raise_internal_error(char *msg)
--{
-- CAMLparam0();
-- CAMLlocal1(v_msg);
-- value v_arg;
-- v_msg = caml_copy_string(msg);
-- v_arg = caml_alloc_small(1, 1);
-- Field(v_arg, 0) = v_msg;
-- raise_pcre_error(v_arg);
-- CAMLnoreturn;
--}
--
--/* PCRE pattern compilation */
--
--static struct custom_operations regexp_ops = {
-- "pcre_ocaml_regexp",
-- pcre_dealloc_regexp,
-- custom_compare_default,
-- custom_hash_default,
-- custom_serialize_default,
-- custom_deserialize_default,
-- custom_compare_ext_default
--};
--
--/* Makes compiled regular expression from compilation options, an optional
-- value of chartables and the pattern string */
--
--CAMLprim value pcre_compile_stub(@intnat@ v_opt, value v_tables, value v_pat)
--{
-- value v_rex; /* Final result -> value of type [regexp] */
-- const char *error = NULL; /* pointer to possible error message */
-- int error_ofs = 0; /* offset in the pattern at which error occurred */
--
-- /* If v_tables = [None], then pointer to tables is NULL, otherwise
-- set it to the appropriate value */
-- chartables tables =
-- (v_tables == None) ? NULL : get_tables(Field(v_tables, 0));
--
-- /* Compiles the pattern */
-- pcre *regexp = pcre_compile(String_val(v_pat), @Int_val@(v_opt), &error,
-- &error_ofs, tables);
--
-- /* Raises appropriate exception with [BadPattern] if the pattern
-- could not be compiled */
-- if (regexp == NULL) raise_bad_pattern(error, error_ofs);
--
-- /* GC will do a full cycle every 1_000_000 regexp allocations (a typical
-- regexp probably consumes less than 100 bytes -> maximum of 100_000_000
-- bytes unreclaimed regexps) */
-- v_rex =
-- caml_alloc_custom(®exp_ops,
-- sizeof(struct pcre_ocaml_regexp), 1, 1000000);
--
-- set_rex(v_rex, regexp);
-- set_extra(v_rex, NULL);
-- set_studied(v_rex, 0);
--
-- return v_rex;
--}
--
--CAMLprim value pcre_compile_stub_bc(value v_opt, value v_tables, value v_pat)
--{
-- return pcre_compile_stub(@Int_val_val@(v_opt), v_tables, v_pat);
--}
--
--
--/* Studies a regexp */
--CAMLprim value pcre_study_stub(value v_rex)
--{
-- /* If it has not yet been studied */
-- if (! get_studied(v_rex)) {
-- const char *error = NULL;
-- pcre_extra *extra = pcre_study(get_rex(v_rex), 0, &error);
-- if (error != NULL) caml_invalid_argument((char *) error);
-- set_extra(v_rex, extra);
-- set_studied(v_rex, 1);
-- }
-- return v_rex;
--}
--
--
--/* Gets the match limit recursion of a regular expression if it exists */
--CAMLprim value pcre_get_match_limit_recursion_stub(value v_rex)
--{
-- pcre_extra *extra = get_extra(v_rex);
-- if (extra == NULL) return None;
-- if (extra->flags & PCRE_EXTRA_MATCH_LIMIT_RECURSION) {
-- value v_lim = Val_int(extra->match_limit_recursion);
-- value v_res = caml_alloc_small(1, 0);
-- Field(v_res, 0) = v_lim;
-- return v_res;
-- }
-- return None;
--}
--
--/* Gets the match limit of a regular expression if it exists */
--CAMLprim value pcre_get_match_limit_stub(value v_rex)
--{
-- pcre_extra *extra = get_extra(v_rex);
-- if (extra == NULL) return None;
-- if (extra->flags & PCRE_EXTRA_MATCH_LIMIT) {
-- value v_lim = Val_int(extra->match_limit);
-- value v_res = caml_alloc_small(1, 0);
-- Field(v_res, 0) = v_lim;
-- return v_res;
-- }
-- return None;
--}
--
--
--/* Sets a match limit for a regular expression imperatively */
--
--CAMLprim value pcre_set_imp_match_limit_stub(value v_rex, @intnat@ v_lim)
--{
-- pcre_extra *extra = get_extra(v_rex);
-- if (extra == NULL) {
-- extra = pcre_malloc(sizeof(pcre_extra));
-- extra->flags = PCRE_EXTRA_MATCH_LIMIT;
-- set_extra(v_rex, extra);
-- } else {
-- unsigned long *flags_ptr = &extra->flags;
-- *flags_ptr = PCRE_EXTRA_MATCH_LIMIT | *flags_ptr;
-- }
-- extra->match_limit = @Int_val@(v_lim);
-- return v_rex;
--}
--
--CAMLprim value pcre_set_imp_match_limit_stub_bc(value v_rex, value v_lim)
--{
-- return pcre_set_imp_match_limit_stub(v_rex, @Int_val_val@(v_lim));
--}
--
--
--/* Sets a match limit recursion for a regular expression imperatively */
--
--CAMLprim value pcre_set_imp_match_limit_recursion_stub(
-- value v_rex, @intnat@ v_lim)
--{
-- pcre_extra *extra = get_extra(v_rex);
-- if (extra == NULL) {
-- extra = pcre_malloc(sizeof(pcre_extra));
-- extra->flags = PCRE_EXTRA_MATCH_LIMIT_RECURSION;
-- set_extra(v_rex, extra);
-- } else {
-- unsigned long *flags_ptr = &extra->flags;
-- *flags_ptr = PCRE_EXTRA_MATCH_LIMIT_RECURSION | *flags_ptr;
-- }
-- extra->match_limit_recursion = @Int_val@(v_lim);
-- return v_rex;
--}
--
--CAMLprim value pcre_set_imp_match_limit_recursion_stub_bc(
-- value v_rex, value v_lim)
--{
-- return pcre_set_imp_match_limit_recursion_stub(v_rex, @Int_val_val@(v_lim));
--}
--
--
--/* Performs the call to the pcre_fullinfo function */
--static inline int pcre_fullinfo_stub(value v_rex, int what, void *where)
--{
-- return pcre_fullinfo(get_rex(v_rex), get_extra(v_rex), what, where);
--}
--
--/* Some stubs for info-functions */
--
--/* Generic macro for getting integer results from pcre_fullinfo */
--#define make_intnat_info(tp, name, option) \
-- CAMLprim @intnat@ pcre_##name##_stub(value v_rex) \
-- { \
-- tp options; \
-- const int ret = pcre_fullinfo_stub(v_rex, PCRE_INFO_##option, &options); \
-- if (ret != 0) raise_internal_error("pcre_##name##_stub"); \
-- return @Val_int@(options); \
-- } \
-- \
-- CAMLprim value pcre_##name##_stub_bc(value v_rex) \
-- { return Val_int(pcre_##name##_stub(v_rex)); }
--
--make_intnat_info(unsigned long, options, OPTIONS)
--make_intnat_info(size_t, size, SIZE)
--make_intnat_info(size_t, studysize, STUDYSIZE)
--make_intnat_info(int, capturecount, CAPTURECOUNT)
--make_intnat_info(int, backrefmax, BACKREFMAX)
--make_intnat_info(int, namecount, NAMECOUNT)
--make_intnat_info(int, nameentrysize, NAMEENTRYSIZE)
--
--CAMLprim value pcre_firstbyte_stub(value v_rex)
--{
-- int firstbyte;
-- const int ret = pcre_fullinfo_stub(v_rex, PCRE_INFO_FIRSTBYTE, &firstbyte);
--
-- if (ret != 0) raise_internal_error("pcre_firstbyte_stub");
--
-- switch (firstbyte) {
-- case -1 : return var_Start_only; break; /* [`Start_only] */
-- case -2 : return var_ANCHORED; break; /* [`ANCHORED] */
-- default :
-- if (firstbyte < 0 ) /* Should not happen */
-- raise_internal_error("pcre_firstbyte_stub");
-- else {
-- value v_firstbyte;
-- /* Allocates the non-constant constructor [`Char of char] and fills
-- in the appropriate value */
-- v_firstbyte = caml_alloc_small(2, 0);
-- Field(v_firstbyte, 0) = var_Char;
-- Field(v_firstbyte, 1) = Val_int(firstbyte);
-- return v_firstbyte;
-- }
-- }
--}
--
--CAMLprim value pcre_firsttable_stub(value v_rex)
--{
-- const unsigned char *ftable;
--
-- int ret =
-- pcre_fullinfo_stub(v_rex, PCRE_INFO_FIRSTTABLE, (void *) &ftable);
--
-- if (ret != 0) raise_internal_error("pcre_firsttable_stub");
--
-- if (ftable == NULL) return None;
-- else {
-- value v_res, v_res_str;
-- char *ptr;
-- int i;
--
-- Begin_roots1(v_rex);
-- v_res_str = caml_alloc_string(32);
-- End_roots();
--
-- ptr = String_val(v_res_str);
-- for (i = 0; i <= 31; ++i) { *ptr = *ftable; ++ptr; ++ftable; }
--
-- Begin_roots1(v_res_str);
-- /* Allocates [Some string] from firsttable */
-- v_res = caml_alloc_small(1, 0);
-- End_roots();
--
-- Field(v_res, 0) = v_res_str;
--
-- return v_res;
-- }
--}
--
--CAMLprim value pcre_lastliteral_stub(value v_rex)
--{
-- int lastliteral;
-- const int ret = pcre_fullinfo_stub(v_rex, PCRE_INFO_LASTLITERAL,
-- &lastliteral);
--
-- if (ret != 0) raise_internal_error("pcre_lastliteral_stub");
--
-- if (lastliteral == -1) return None;
-- if (lastliteral < 0) raise_internal_error("pcre_lastliteral_stub");
-- else {
-- /* Allocates [Some char] */
-- value v_res = caml_alloc_small(1, 0);
-- Field(v_res, 0) = Val_int(lastliteral);
-- return v_res;
-- }
--}
--
--CAMLprim value pcre_study_stat_stub(value v_rex)
--{
-- /* Generates the appropriate constant constructor [`Optimal] or
-- [`Studied] if regexp has already been studied */
-- if (get_studied(v_rex))
-- return (get_extra(v_rex) == NULL) ? var_Optimal : var_Studied;
--
-- return var_Not_studied; /* otherwise [`Not_studied] */
--}
--
--@CAMLnoreturn_start@
--static inline void handle_exec_error(char *loc, const int ret)
--@CAMLnoreturn_end@;
--
--static inline void handle_exec_error(char *loc, const int ret)
--{
-- switch (ret) {
-- /* Dedicated exceptions */
-- case PCRE_ERROR_NOMATCH : caml_raise_not_found();
-- case PCRE_ERROR_PARTIAL : raise_partial();
-- case PCRE_ERROR_MATCHLIMIT : raise_match_limit();
-- case PCRE_ERROR_BADPARTIAL : raise_bad_partial();
-- case PCRE_ERROR_BADUTF8 : raise_bad_utf8();
-- case PCRE_ERROR_BADUTF8_OFFSET : raise_bad_utf8_offset();
-- case PCRE_ERROR_RECURSIONLIMIT : raise_recursion_limit();
-- /* Unknown error */
-- default : {
-- char err_buf[100];
-- snprintf(err_buf, 100, "%s: unhandled PCRE error code: %d", loc, ret);
-- raise_internal_error(err_buf);
-- }
-- }
--}
--
--static inline void handle_pcre_exec_result(
-- int *ovec, value v_ovec, long ovec_len, long subj_start, int ret)
--{
-- ovec_dst_ptr ocaml_ovec = (ovec_dst_ptr) &Field(v_ovec, 0);
-- const int subgroups2 = ret * 2;
-- const int subgroups2_1 = subgroups2 - 1;
-- const int *ovec_src = ovec + subgroups2_1;
-- ovec_dst_ptr ovec_clear_stop = ocaml_ovec + (ovec_len * 2) / 3;
-- ovec_dst_ptr ovec_dst = ocaml_ovec + subgroups2_1;
-- copy_ovector(subj_start, ovec_src, ovec_dst, subgroups2);
-- while (++ovec_dst < ovec_clear_stop) *ovec_dst = -1;
--}
--
--
--/* Executes a pattern match with runtime options, a regular expression, a
-- matching position, the start of the the subject string, a subject string,
-- a number of subgroup offsets, an offset vector and an optional callout
-- function */
--
--CAMLprim value pcre_exec_stub(
-- @intnat@ v_opt, value v_rex, @intnat@ v_pos, @intnat@ v_subj_start, value v_subj,
-- value v_ovec, value v_maybe_cof)
--{
-- int ret;
-- long
-- pos = @Int_val@(v_pos),
-- len = caml_string_length(v_subj),
-- subj_start = @Int_val@(v_subj_start);
-- long ovec_len = Wosize_val(v_ovec);
--
-- if (pos > len || pos < subj_start)
-- caml_invalid_argument("Pcre.pcre_exec_stub: illegal position");
--
-- if (subj_start > len || subj_start < 0)
-- caml_invalid_argument("Pcre.pcre_exec_stub: illegal subject start");
--
-- pos -= subj_start;
-- len -= subj_start;
--
-- {
-- const pcre *code = get_rex(v_rex); /* Compiled pattern */
-- const pcre_extra *extra = get_extra(v_rex); /* Extra info */
-- const char *ocaml_subj =
-- String_val(v_subj) + subj_start; /* Subject string */
-- const int opt = @Int_val@(v_opt); /* Runtime options */
--
-- /* Special case when no callout functions specified */
-- if (v_maybe_cof == None) {
-- int *ovec = (int *) &Field(v_ovec, 0);
--
-- /* Performs the match */
-- ret = pcre_exec(code, extra, ocaml_subj, len, pos, opt, ovec, ovec_len);
--
-- if (ret < 0) handle_exec_error("pcre_exec_stub", ret);
-- else handle_pcre_exec_result(ovec, v_ovec, ovec_len, subj_start, ret);
-- }
--
-- /* There are callout functions */
-- else {
-- value v_cof = Field(v_maybe_cof, 0);
-- value v_substrings;
-- char *subj = caml_stat_alloc(sizeof(char) * len);
-- int *ovec = caml_stat_alloc(sizeof(int) * ovec_len);
-- struct cod cod = { 0, (value *) NULL, (value *) NULL, (value) NULL };
-- struct pcre_extra new_extra =
--#ifdef PCRE_EXTRA_MATCH_LIMIT_RECURSION
--# ifdef PCRE_EXTRA_MARK
--# ifdef PCRE_EXTRA_EXECUTABLE_JIT
-- { PCRE_EXTRA_CALLOUT_DATA, NULL, 0, NULL, NULL, 0, NULL, NULL };
--# else
-- { PCRE_EXTRA_CALLOUT_DATA, NULL, 0, NULL, NULL, 0, NULL };
--# endif
--# else
-- { PCRE_EXTRA_CALLOUT_DATA, NULL, 0, NULL, NULL, 0 };
--# endif
--#else
-- { PCRE_EXTRA_CALLOUT_DATA, NULL, 0, NULL, NULL };
--#endif
--
-- cod.subj_start = subj_start;
-- memcpy(subj, ocaml_subj, len);
--
-- Begin_roots4(v_rex, v_cof, v_substrings, v_ovec);
-- Begin_roots1(v_subj);
-- v_substrings = caml_alloc_small(2, 0);
-- End_roots();
--
-- Field(v_substrings, 0) = v_subj;
-- Field(v_substrings, 1) = v_ovec;
--
-- cod.v_substrings_p = &v_substrings;
-- cod.v_cof_p = &v_cof;
-- new_extra.callout_data = &cod;
--
-- if (extra == NULL) {
-- ret = pcre_exec(code, &new_extra, subj, len, pos, opt, ovec,
-- ovec_len);
-- }
-- else {
-- new_extra.flags = PCRE_EXTRA_CALLOUT_DATA | extra->flags;
-- new_extra.study_data = extra->study_data;
-- new_extra.match_limit = extra->match_limit;
-- new_extra.tables = extra->tables;
--#ifdef PCRE_EXTRA_MATCH_LIMIT_RECURSION
-- new_extra.match_limit_recursion = extra->match_limit_recursion;
--#endif
--
-- ret = pcre_exec(code, &new_extra, subj, len, pos, opt, ovec,
-- ovec_len);
-- }
--
-- caml_stat_free(subj);
-- End_roots();
--
-- if (ret < 0) {
-- caml_stat_free(ovec);
-- if (ret == PCRE_ERROR_CALLOUT) caml_raise(cod.v_exn);
-- else handle_exec_error("pcre_exec_stub(callout)", ret);
-- } else {
-- handle_pcre_exec_result(ovec, v_ovec, ovec_len, subj_start, ret);
-- caml_stat_free(ovec);
-- }
-- }
-- }
--
-- return Val_unit;
--}
--
--/* Byte-code hook for pcre_exec_stub
-- Needed, because there are more than 5 arguments */
--CAMLprim value pcre_exec_stub_bc(value *argv, int __unused argn)
--{
-- return
-- pcre_exec_stub(
-- @Int_val_val@(argv[0]), argv[1], @Int_val_val@(argv[2]), @Int_val_val@(argv[3]),
-- argv[4], argv[5], argv[6]);
--}
--
--static struct custom_operations tables_ops = {
-- "pcre_ocaml_tables",
-- pcre_dealloc_tables,
-- custom_compare_default,
-- custom_hash_default,
-- custom_serialize_default,
-- custom_deserialize_default,
-- custom_compare_ext_default
--};
--
--/* Generates a new set of chartables for the current locale (see man
-- page of PCRE */
--CAMLprim value pcre_maketables_stub(value __unused v_unit)
--{
-- /* GC will do a full cycle every 1_000_000 table set allocations (one
-- table set consumes 864 bytes -> maximum of 864_000_000 bytes unreclaimed
-- table sets) */
-- const value v_tables =
-- caml_alloc_custom(
-- &tables_ops, sizeof(struct pcre_ocaml_tables), 1, 1000000);
-- set_tables(v_tables, pcre_maketables());
-- return v_tables;
--}
--
--/* Wraps around the isspace-function */
--CAMLprim value pcre_isspace_stub(value v_c)
--{
-- return Val_bool(isspace(Int_val(v_c)));
--}
--
--
--/* Returns number of substring associated with a name */
--
--CAMLprim @intnat@ pcre_get_stringnumber_stub(value v_rex, value v_name)
--{
-- const int ret = pcre_get_stringnumber(get_rex(v_rex), String_val(v_name));
-- if (ret == PCRE_ERROR_NOSUBSTRING)
-- caml_invalid_argument("Named string not found");
--
-- return @Val_int@(ret);
--}
--
--CAMLprim value pcre_get_stringnumber_stub_bc(value v_rex, value v_name)
--{
-- return @Val_Val_int@(pcre_get_stringnumber_stub(v_rex, v_name));
--}
--
--
--/* Returns array of names of named substrings in a regexp */
--CAMLprim value pcre_names_stub(value v_rex)
--{
-- CAMLparam0();
-- CAMLlocal1(v_res);
-- int name_count;
-- int entry_size;
-- const char *tbl_ptr;
-- int i;
--
-- int ret = pcre_fullinfo_stub(v_rex, PCRE_INFO_NAMECOUNT, &name_count);
-- if (ret != 0) raise_internal_error("pcre_names_stub: namecount");
--
-- ret = pcre_fullinfo_stub(v_rex, PCRE_INFO_NAMEENTRYSIZE, &entry_size);
-- if (ret != 0) raise_internal_error("pcre_names_stub: nameentrysize");
--
-- ret = pcre_fullinfo_stub(v_rex, PCRE_INFO_NAMETABLE, &tbl_ptr);
-- if (ret != 0) raise_internal_error("pcre_names_stub: nametable");
--
-- v_res = caml_alloc(name_count, 0);
--
-- for (i = 0; i < name_count; ++i) {
-- value v_name = caml_copy_string(tbl_ptr + 2);
-- Store_field(v_res, i, v_name);
-- tbl_ptr += entry_size;
-- }
--
-- CAMLreturn(v_res);
--}
--
--/* Generic stub for getting integer results from pcre_config */
--static inline int pcre_config_int(int what)
--{
-- int ret;
-- pcre_config(what, (void *) &ret);
-- return ret;
--}
--
--/* Generic stub for getting long integer results from pcre_config */
--static inline int pcre_config_long(int what)
--{
-- long ret;
-- pcre_config(what, (void *) &ret);
-- return ret;
--}
--
--
--/* Some stubs for config-functions */
--
--/* Makes OCaml-string from PCRE-version */
--CAMLprim value pcre_version_stub(value __unused v_unit)
--{
-- return caml_copy_string((char *) pcre_version());
--}
--
--/* Returns boolean indicating UTF8-support */
--CAMLprim value pcre_config_utf8_stub(value __unused v_unit)
--{ return Val_bool(pcre_config_int(PCRE_CONFIG_UTF8)); }
--
--
--/* Returns character used as newline */
--CAMLprim value pcre_config_newline_stub(value __unused v_unit)
--{ return Val_int(pcre_config_int(PCRE_CONFIG_NEWLINE)); }
--
--
--/* Returns number of bytes used for internal linkage of regular expressions */
--
--CAMLprim @intnat@ pcre_config_link_size_stub(value __unused v_unit)
--{ return @Val_int@(pcre_config_int(PCRE_CONFIG_LINK_SIZE)); }
--
--CAMLprim value pcre_config_link_size_stub_bc(value v_unit)
--{ return @Val_Val_int@(pcre_config_link_size_stub(v_unit)); }
--
--
--/* Returns default limit for calls to internal matching function */
--
--CAMLprim @intnat@ pcre_config_match_limit_stub(value __unused v_unit)
--{ return @Val_int@(pcre_config_long(PCRE_CONFIG_MATCH_LIMIT)); }
--
--
--CAMLprim value pcre_config_match_limit_stub_bc(value v_unit)
--{ return @Val_Val_int@(pcre_config_match_limit_stub(v_unit)); }
--
--
--/* Returns default limit for recursive calls to internal matching function */
--
--CAMLprim @intnat@ pcre_config_match_limit_recursion_stub(value __unused v_unit)
--{ return @Val_int@(pcre_config_long(PCRE_CONFIG_MATCH_LIMIT_RECURSION)); }
--
--CAMLprim value pcre_config_match_limit_recursion_stub_bc(value v_unit)
--{ return @Val_Val_int@(pcre_config_match_limit_recursion_stub(v_unit)); }
--
--
--/* Returns boolean indicating use of stack recursion */
--CAMLprim value pcre_config_stackrecurse_stub(value __unused v_unit)
--{ return Val_bool(pcre_config_int(PCRE_CONFIG_STACKRECURSE)); }
-diff --git a/bundles/pcre/pcre-ocaml/.gitignore b/bundles/pcre2/pcre2-ocaml/.gitignore
-similarity index 100%
-rename from bundles/pcre/pcre-ocaml/.gitignore
-rename to bundles/pcre2/pcre2-ocaml/.gitignore
-diff --git a/bundles/pcre2/pcre2-ocaml/CHANGELOG.md b/bundles/pcre2/pcre2-ocaml/CHANGELOG.md
-new file mode 100644
-index 000000000..da11eae34
---- /dev/null
-+++ b/bundles/pcre2/pcre2-ocaml/CHANGELOG.md
-@@ -0,0 +1,69 @@
-+# Changelog
-+
-+## [8.0.4] - 2025-10-19
-+
-+### Added
-+
-+- Provide a `make test` convenience target and generate
-+ `lib/compile_commands.json` to streamline running the suite and IDE
-+ integration.
-+- Introduce GitHub automation (Dependabot updates plus linting, formatting, and
-+ pre-commit workflows) mirroring the original `pcre-ocaml` project.
-+
-+### Changed
-+
-+- Reorganize the repository to match the upstream layout, moving library sources
-+ to `lib/`, refreshing documentation, and updating example descriptions.
-+
-+### Fixed
-+
-+- Ensure the `Pcre2.BadPattern` exception allocates short OCaml strings to avoid
-+ trailing garbage or embedded NUL bytes in error messages.
-+- Correct the offset-vector pointer cast in `pcre2_stubs.c` to remove undefined
-+ behavior when copying match offsets.
-+
-+## [8.0.3] - 2025-02-15
-+
-+### Fixed
-+
-+- Make `caml_alloc_some` static to prevent clashes with the `pcre` package when
-+ targeting OCaml 4.08-4.11.
-+
-+## [8.0.2] - 2024-12-26
-+
-+### Added
-+
-+- Restore compatibility with OCaml 4.08 through 4.11. Thanks to @nojb.
-+
-+## [8.0.1] - 2024-12-20
-+
-+### Changed
-+
-+- Merge the legacy `pcre-ocaml` changes into `pcre2-ocaml`.
-+
-+### Fixed
-+
-+- Correct `full_split` so that non-capturing groups are identified properly.
-+
-+## [7.5.3] - 2024-12-23
-+
-+### Fixed
-+
-+- Address the `full_split` regression. Thanks to @mmottl.
-+
-+## [7.5.2] - 2023-09-06
-+
-+### Added
-+
-+- Introduce the initial unit test that exercises `full_split`.
-+
-+### Fixed
-+
-+- Resolve the `full_split` bug affecting split classification.
-+
-+## [7.5.1] - 2023-09-01
-+
-+### Added
-+
-+- Create the initial `pcre2-ocaml` bindings derived from the original
-+ `pcre-ocaml` project.
-diff --git a/bundles/pcre/pcre-ocaml/LICENSE.md b/bundles/pcre2/pcre2-ocaml/LICENSE.md
-similarity index 99%
-rename from bundles/pcre/pcre-ocaml/LICENSE.md
-rename to bundles/pcre2/pcre2-ocaml/LICENSE.md
-index c35c24daa..4481e3e68 100644
---- a/bundles/pcre/pcre-ocaml/LICENSE.md
-+++ b/bundles/pcre2/pcre2-ocaml/LICENSE.md
-@@ -12,7 +12,7 @@ requirements listed in clause 6 of the GNU Lesser General Public License.
- By "a publicly distributed version of the Library", we mean either the
- unmodified Library as distributed by the authors, or a modified version
- of the Library that is distributed under the conditions defined in clause
--3 of the GNU Lesser General Public License. This exception does not
-+2 of the GNU Lesser General Public License. This exception does not
- however invalidate any other reasons why the executable file might be
- covered by the GNU Lesser General Public License.
-
-@@ -24,7 +24,7 @@ Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--
-+
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-diff --git a/bundles/pcre2/pcre2-ocaml/Makefile b/bundles/pcre2/pcre2-ocaml/Makefile
-new file mode 100644
-index 000000000..cf2ee6e51
---- /dev/null
-+++ b/bundles/pcre2/pcre2-ocaml/Makefile
-@@ -0,0 +1,15 @@
-+.PHONY: all clean doc
-+
-+all:
-+ @dune build @install
-+ @make -C lib compile_commands.json
-+
-+test: all
-+ @dune build @install @runtest
-+
-+clean:
-+ @dune clean
-+ @make -C lib clean-compile-commands
-+
-+doc:
-+ @dune build @doc
-diff --git a/bundles/pcre2/pcre2-ocaml/README.md b/bundles/pcre2/pcre2-ocaml/README.md
-new file mode 100644
-index 000000000..a679fb4eb
---- /dev/null
-+++ b/bundles/pcre2/pcre2-ocaml/README.md
-@@ -0,0 +1,138 @@
-+# PCRE2-OCaml - Perl Compatibility Regular Expressions for OCaml
-+
-+Fork of the original [pcre-ocaml project](https://github.com/mmottl/pcre-ocaml)
-+for PCRE2 support.
-+
-+These are the bindings as needed by the
-+[Haxe compiler](https://github.com/HaxeFoundation/haxe). I do not plan on
-+maintaining this repository.
-+
-+This [OCaml](http://www.ocaml.org) library interfaces with the C library
-+[PCRE2](http://www.pcre.org), providing Perl-compatible regular expressions for
-+string matching.
-+
-+## Features
-+
-+PCRE2-OCaml offers:
-+
-+- Pattern searching
-+- Subpattern extraction
-+- String splitting by patterns
-+- Pattern substitution
-+
-+Reasons to choose PCRE2-OCaml:
-+
-+- The PCRE2 library by Philip Hazel is mature and stable, implementing nearly
-+ all Perl regular expression features. High-level OCaml functions (split,
-+ replace, etc.) are compatible with Perl functions, as much as OCaml allows.
-+ Some developers find Perl-style regex syntax more intuitive and powerful than
-+ the Emacs-style regex used in OCaml's `Str` module.
-+
-+- PCRE2-OCaml is reentrant and thread-safe, unlike the `Str` module. This
-+ reentrancy offers convenience, eliminating concerns about library state.
-+
-+- High-level replacement and substitution functions in OCaml are faster than
-+ those in the `Str` module. When compiled to native code, they can even
-+ outperform Perl's C-based functions.
-+
-+- Returned data is unique, allowing safe destructive updates without side
-+ effects.
-+
-+- The library interface uses labels and default arguments for enhanced
-+ programming comfort.
-+
-+## Usage
-+
-+Please run:
-+
-+```sh
-+odig odoc pcre2
-+```
-+
-+Or (maybe?):
-+
-+```sh
-+dune build @doc
-+```
-+
-+Functions support two flag types:
-+
-+1. **Convenience flags**: Readable and concise, translated internally on each
-+ call. Example:
-+
-+ ```ocaml
-+ let rex = Pcre2.regexp ~flags:[`ANCHORED; `CASELESS] "some pattern" in
-+ (* ... *)
-+ ```
-+
-+ These are easy to use but may incur overhead in loops. For performance
-+ optimization, consider the next approach.
-+
-+2. **Internal flags**: Predefined and translated from convenience flags for
-+ optimal loop performance. Example:
-+
-+ ```ocaml
-+ let iflags = Pcre2.cflags [`ANCHORED; `CASELESS] in
-+ for i = 1 to 1000 do
-+ let rex = Pcre2.regexp ~iflags "some pattern constructed at runtime" in
-+ (* ... *)
-+ done
-+ ```
-+
-+ Translating flags outside loops saves cycles. Avoid creating regex in loops:
-+
-+ ```ocaml
-+ for i = 1 to 1000 do
-+ let chunks = Pcre2.split ~pat:"[ \t]+" "foo bar" in
-+ (* ... *)
-+ done
-+ ```
-+
-+ Instead, predefine the regex:
-+
-+ ```ocaml
-+ let rex = Pcre2.regexp "[ \t]+" in
-+ for i = 1 to 1000 do
-+ let chunks = Pcre2.split ~rex "foo bar" in
-+ (* ... *)
-+ done
-+ ```
-+
-+Functions use optional arguments with intuitive defaults. For instance,
-+`Pcre2.split` defaults to whitespace as the pattern. The `examples` directory
-+contains applications demonstrating PCRE2-OCaml's functionality.
-+
-+## Restartable (Partial) Pattern Matching
-+
-+PCRE2 includes a DFA match function for restarting partial matches with new
-+input, exposed via `pcre2_dfa_exec`. While not suitable for extracting
-+submatches or splitting strings, it's useful for streaming and search tasks.
-+
-+Example of a partial match restarted:
-+
-+```ocaml
-+utop # open Pcre2;;
-+utop # let rex = regexp "12+3";;
-+val rex : regexp = <abstr>
-+utop # let workspace = Array.make 40 0;;
-+val workspace : int array =
-+ [| ... |]
-+utop # pcre2_dfa_match ~rex ~flags:[`PARTIAL_SOFT] ~workspace "12222";;
-+Exception: Pcre2.Error Partial.
-+utop # pcre2_dfa_match ~rex ~flags:[`PARTIAL_SOFT; `DFA_RESTART] ~workspace "2222222";;
-+Exception: Pcre2.Error Partial.
-+utop # pcre2_dfa_exec ~rex ~flags:[`PARTIAL_SOFT; `DFA_RESTART] ~workspace "2222222";;
-+Exception: Pcre2.Error Partial.
-+utop # pcre2_dfa_exec ~rex ~flags:[`PARTIAL_SOFT; `DFA_RESTART] ~workspace "223xxxx";;
-+- : int array = [|0; 3; 0|]
-+```
-+
-+Refer to the `pcre2_dfa_exec` documentation and the `dfa_restart` example for
-+more information.
-+
-+## Contact Information and Contributing
-+
-+Submit bug reports, feature requests, and contributions via the
-+[GitHub issue tracker](https://github.com/camlp5/pcre2-ocaml/issues).
-+
-+For the latest information, visit: <https://github.com/camlp5/pcre2-ocaml>
-diff --git a/bundles/pcre2/pcre2-ocaml/dune b/bundles/pcre2/pcre2-ocaml/dune
-new file mode 100644
-index 000000000..3edaa082b
---- /dev/null
-+++ b/bundles/pcre2/pcre2-ocaml/dune
-@@ -0,0 +1,9 @@
-+(env
-+ (dev
-+ (flags
-+ (:standard -w -9 -principal))
-+ (c_flags
-+ (:standard -Wall -pedantic -Wextra -Wunused)))
-+ (release
-+ (ocamlopt_flags
-+ (:standard -O3))))
-diff --git a/bundles/pcre2/pcre2-ocaml/dune-project b/bundles/pcre2/pcre2-ocaml/dune-project
-new file mode 100644
-index 000000000..2635a66a2
---- /dev/null
-+++ b/bundles/pcre2/pcre2-ocaml/dune-project
-@@ -0,0 +1,32 @@
-+(lang dune 2.7)
-+
-+(name pcre2)
-+
-+(version 8.0.4)
-+
-+(generate_opam_files true)
-+
-+(source
-+ (github camlp5/pcre2-ocaml))
-+
-+(license "LGPL-2.1-or-later WITH OCaml-LGPL-linking-exception")
-+
-+(homepage "https://github.com/camlp5/pcre2-ocaml")
-+
-+(maintainers "Chet Murthy <chetsky@gmail.com>")
-+
-+(authors "Markus Mottl <markus.mottl@gmail.com>")
-+
-+(package
-+ (name pcre2)
-+ (synopsis
-+ "Bindings to the Perl Compatibility Regular Expressions library (version 2)")
-+ (description
-+ "pcre2-ocaml offers library functions for string pattern matching and\nsubstitution, similar to the functionality offered by the Perl language.")
-+ (depends
-+ (ocaml
-+ (>= 4.08))
-+ dune-compiledb
-+ dune-configurator
-+ (conf-libpcre2-8 :build)
-+ (ounit2 :with-test)))
-diff --git a/bundles/pcre2/pcre2-ocaml/examples/Makefile b/bundles/pcre2/pcre2-ocaml/examples/Makefile
-new file mode 100644
-index 000000000..29dbbf0a4
---- /dev/null
-+++ b/bundles/pcre2/pcre2-ocaml/examples/Makefile
-@@ -0,0 +1,9 @@
-+TARGETS = $(addsuffix .bc, cloc count_hash dfa_restart pcre2grep subst)
-+
-+.PHONY: all clean
-+
-+all:
-+ @dune build $(TARGETS)
-+
-+clean:
-+ @dune clean
-diff --git a/bundles/pcre2/pcre2-ocaml/examples/README.md b/bundles/pcre2/pcre2-ocaml/examples/README.md
-new file mode 100644
-index 000000000..d832f042f
---- /dev/null
-+++ b/bundles/pcre2/pcre2-ocaml/examples/README.md
-@@ -0,0 +1,48 @@
-+# Examples
-+
-+## `cloc`
-+
-+This program reads C source code from `stdin` and outputs it to `stdout` with
-+comments and empty lines removed. It's useful for counting lines of code.
-+
-+## `count_hash`
-+
-+This program reads text from `stdin`, counts occurrences of identical words
-+separated by whitespace, and prints the result to `stdout`.
-+
-+## `pcre2grep`
-+
-+A grep-like program using Perl-compatible regular expressions. Start the program
-+with the `-help` argument to see its functionality.
-+
-+## `subst`
-+
-+Substitutes text in files using Perl-compatible regular expressions and
-+substitution patterns. Start the program with the `-help` argument to see its
-+functionality.
-+
-+Example invocation:
-+
-+```sh
-+subst '([Tt])ermcap' '$1ermCap' < /etc/termcap
-+```
-+
-+## `dfa_restart`
-+
-+Tests the DFA matching function and its partial match restart capability. Given
-+a pattern, it accepts input incrementally, restarting the prior partial match
-+until the pattern either succeeds or fails.
-+
-+Example interaction:
-+
-+```sh
-+$ dfa_restart.exe 'abc12+3'
-+> abc
-+partial match, provide more input:
-+> 122222
-+partial match, provide more input:
-+> 222
-+partial match, provide more input:
-+> 3
-+match completed: "[|0;1;0|]"
-+```
-diff --git a/bundles/pcre/pcre-ocaml/examples/cloc.ml b/bundles/pcre2/pcre2-ocaml/examples/cloc.ml
-similarity index 97%
-rename from bundles/pcre/pcre-ocaml/examples/cloc.ml
-rename to bundles/pcre2/pcre2-ocaml/examples/cloc.ml
-index 27c7fd3a8..f48376250 100644
---- a/bundles/pcre/pcre-ocaml/examples/cloc.ml
-+++ b/bundles/pcre2/pcre2-ocaml/examples/cloc.ml
-@@ -1,4 +1,4 @@
--open Pcre
-+open Pcre2
-
- let read_whole_channel ch =
- let size = 4096 in
-diff --git a/bundles/pcre/pcre-ocaml/examples/count_hash.ml b/bundles/pcre2/pcre2-ocaml/examples/count_hash.ml
-similarity index 62%
-rename from bundles/pcre/pcre-ocaml/examples/count_hash.ml
-rename to bundles/pcre2/pcre2-ocaml/examples/count_hash.ml
-index 98d16bc50..47118b684 100644
---- a/bundles/pcre/pcre-ocaml/examples/count_hash.ml
-+++ b/bundles/pcre2/pcre2-ocaml/examples/count_hash.ml
-@@ -1,6 +1,8 @@
- open Hashtbl
-
- let hash = create 1973
--let add_string s = try incr (find hash s) with Not_found -> add hash s (ref 1);;
--Pcre.foreach_line (fun line -> List.iter add_string (Pcre.split line));
-+let add_string s = try incr (find hash s) with Not_found -> add hash s (ref 1)
-+;;
-+
-+Pcre2.foreach_line (fun line -> List.iter add_string (Pcre2.split line));
- iter (fun k v -> Printf.printf "%4d\t%s\n" !v k) hash
-diff --git a/bundles/pcre2/pcre2-ocaml/examples/dfa_restart.ml b/bundles/pcre2/pcre2-ocaml/examples/dfa_restart.ml
-new file mode 100644
-index 000000000..882a1f355
---- /dev/null
-+++ b/bundles/pcre2/pcre2-ocaml/examples/dfa_restart.ml
-@@ -0,0 +1,40 @@
-+open Pcre2
-+open Printf
-+
-+let show_array arr =
-+ Array.map string_of_int arr
-+ |> Array.to_list |> String.concat ";" |> sprintf "[|%s|]"
-+
-+let new_workspace () = Array.make 50 0
-+
-+let () =
-+ let pat =
-+ if Array.length Sys.argv > 1 then Sys.argv.(1)
-+ else (
-+ eprintf "%s: expected pattern argument\n" Sys.argv.(0);
-+ exit 1)
-+ in
-+ let rex = regexp pat in
-+ let rec find_match flags workspace =
-+ print_string "> ";
-+ let line, eof =
-+ try (read_line (), false) with End_of_file -> ("", true)
-+ in
-+ match pcre2_dfa_match ~rex ~flags ~workspace line with
-+ | res ->
-+ printf "match completed: %S\n" (show_array res);
-+ if not eof then (
-+ printf "\n *input & workspace reset*\n";
-+ find_match [ `PARTIAL_SOFT ] (new_workspace ()))
-+ | exception Error Partial ->
-+ printf "partial match, provide more input:\n";
-+ find_match [ `DFA_RESTART; `PARTIAL_SOFT ] workspace
-+ | exception exn ->
-+ (match exn with
-+ | Not_found -> eprintf "pattern match failed\n"
-+ | Error WorkspaceSize -> eprintf "need larger workspace vector\n"
-+ | Error (InternalError s) -> eprintf "internal error: %s\n" s
-+ | exn -> raise exn);
-+ exit 1
-+ in
-+ find_match [ `PARTIAL_SOFT ] (new_workspace ())
-diff --git a/bundles/pcre2/pcre2-ocaml/examples/dune b/bundles/pcre2/pcre2-ocaml/examples/dune
-new file mode 100644
-index 000000000..612c60c04
---- /dev/null
-+++ b/bundles/pcre2/pcre2-ocaml/examples/dune
-@@ -0,0 +1,4 @@
-+(executables
-+ (names cloc count_hash pcre2grep subst dfa_restart)
-+ (libraries pcre2)
-+ (modes byte exe))
-diff --git a/bundles/pcre2/pcre2-ocaml/examples/pcre2grep.ml b/bundles/pcre2/pcre2-ocaml/examples/pcre2grep.ml
-new file mode 100644
-index 000000000..5a8e02e41
---- /dev/null
-+++ b/bundles/pcre2/pcre2-ocaml/examples/pcre2grep.ml
-@@ -0,0 +1,128 @@
-+open Pcre2
-+open Printf
-+
-+let filenames = ref true
-+and filenames_only = ref false
-+and count_only = ref false
-+and invert = ref false
-+and number = ref false
-+and silent = ref false
-+and whole_lines = ref false
-+
-+let parse_args () =
-+ let ignore_case = ref false and pat = ref None and files = ref [] in
-+
-+ let c = ("-c", Arg.Set count_only, "Count lines only.")
-+ and h =
-+ ( "-h",
-+ Arg.Clear filenames,
-+ "Suppress printing of filenames when searching multiple files." )
-+ and i = ("-i", Arg.Set ignore_case, "Ignore case.")
-+ and l =
-+ ( "-l",
-+ Arg.Set filenames_only,
-+ "Only print names of files containing matching lines (once)." )
-+ and n =
-+ ("-n", Arg.Set number, "Precede each line by its line number in the file.")
-+ and s =
-+ ( "-s",
-+ Arg.Set silent,
-+ "Display nothing but error messages. Exit status indicates match." )
-+ and v =
-+ ("-v", Arg.Set invert, "Invert sense of the match: finds nonmatching lines.")
-+ and x =
-+ ( "-x",
-+ Arg.Set whole_lines,
-+ "Force the pattern to be anchored and to match the entire line." )
-+ and usage =
-+ "Usage: pcre2grep [options] pattern [file] ...\n\n\
-+ Searches files for character patterns.\n"
-+ and anon_arg arg =
-+ if !pat = None then pat := Some arg else files := arg :: !files
-+ in
-+
-+ let args = [ c; h; i; l; n; s; v; x ] in
-+ Arg.parse args anon_arg usage;
-+
-+ let flags =
-+ let flag_list = if !ignore_case then [ `CASELESS ] else [] in
-+ if !whole_lines then `ANCHORED :: flag_list else flag_list
-+ in
-+
-+ let rex =
-+ match !pat with
-+ | Some pat -> regexp ~flags pat
-+ | None ->
-+ eprintf "%s: not enough arguments!\n" Sys.argv.(0);
-+ Arg.usage args usage;
-+ exit 2
-+ in
-+ (rex, List.rev !files)
-+
-+let _ =
-+ let rex, files = parse_args () and rfl = rflags [] in
-+
-+ let _, ovector = make_ovector rex in
-+
-+ let pcre2grep file name =
-+ let ret_code = ref 1
-+ and linenumber = ref 0
-+ and count = ref 0
-+ and stdin_print_name () =
-+ match name with
-+ | Some filename -> print_endline filename
-+ | None -> print_endline "<stdin>"
-+ and print_name () =
-+ match name with Some name -> printf "%s:" name | None -> ()
-+ in
-+
-+ let try_match line =
-+ let matched =
-+ try
-+ unsafe_pcre2_match rfl rex ~pos:0 ~subj_start:0 ~subj:line ovector
-+ None;
-+ if !whole_lines && ovector.(1) <> String.length line then false
-+ else true
-+ with Not_found -> false
-+ in
-+
-+ incr linenumber;
-+
-+ if matched <> !invert then (
-+ if !count_only then incr count
-+ else if !filenames_only then (
-+ stdin_print_name ();
-+ raise Exit)
-+ else if !silent then raise Exit
-+ else (
-+ print_name ();
-+ if !number then printf "%d:" !linenumber;
-+ print_endline line);
-+ ret_code := 0)
-+ in
-+
-+ try
-+ foreach_line ~ic:file try_match;
-+ if !count_only then (
-+ print_name ();
-+ printf "%d\n" !count);
-+ !ret_code
-+ with Exit -> 0
-+ in
-+
-+ if files = [] then exit (pcre2grep stdin None);
-+
-+ if List.length files = 1 then filenames := false;
-+ if !filenames_only then filenames := true;
-+
-+ let collect ret_code filename =
-+ try
-+ let file = open_in filename in
-+ let frc = pcre2grep file (if !filenames then Some filename else None) in
-+ close_in file;
-+ if frc = 0 && ret_code = 1 then 0 else ret_code
-+ with Sys_error msg ->
-+ prerr_endline msg;
-+ 2
-+ in
-+ exit (List.fold_left collect 1 files)
-diff --git a/bundles/pcre2/pcre2-ocaml/examples/subst.ml b/bundles/pcre2/pcre2-ocaml/examples/subst.ml
-new file mode 100644
-index 000000000..d9ec61c7a
---- /dev/null
-+++ b/bundles/pcre2/pcre2-ocaml/examples/subst.ml
-@@ -0,0 +1,57 @@
-+open Pcre2
-+
-+let parse_args () =
-+ let quick = ref false
-+ and first = ref false
-+ and ignore_case = ref false
-+ and offset = ref 0
-+ and pat = ref None
-+ and substr = ref None in
-+
-+ let q =
-+ ( "-q",
-+ Arg.Set quick,
-+ "Quick replacement. Interpretes substitution as plain text." )
-+ and f = ("-f", Arg.Set first, "Replace first occurrence in line only.")
-+ and i = ("-i", Arg.Set ignore_case, "Ignore case.")
-+ and ofs =
-+ ("-ofs", Arg.Int (fun n -> offset := n), "Start matching at column n.")
-+ and usage =
-+ "Usage: subst [-q] [-f] [-i] [-ofs offset] pattern substitution\n\n\
-+ Reads lines from standard input and replaces occurrences of\n\
-+ the PERL-style regular expression \"pattern\" with \"substitution\",\n\
-+ printing the result to standard output.\n\
-+ In default mode the contents of \"substitution\" will be interpreted\n\
-+ similarly to its equivalent in PERL.\n"
-+ and anon_arg arg =
-+ match (!pat, !substr) with
-+ | None, _ -> pat := Some arg
-+ | _, None -> substr := Some arg
-+ | _ -> raise (Arg.Bad "too many arguments!")
-+ in
-+
-+ let args = [ q; f; i; ofs ] in
-+ Arg.parse args anon_arg usage;
-+
-+ let flags = if !ignore_case then [ `CASELESS ] else [] in
-+
-+ let rex, sstr =
-+ match (!pat, !substr) with
-+ | Some rex, Some sstr -> (regexp ~flags rex, sstr)
-+ | _ ->
-+ prerr_endline (Sys.argv.(0) ^ ": not enough arguments!");
-+ Arg.usage args usage;
-+ exit 1
-+ in
-+
-+ match (!quick, !first) with
-+ | false, false -> fun s -> replace ~rex ~pos:!offset ~templ:sstr s
-+ | true, false -> fun s -> qreplace ~rex ~pos:!offset ~templ:sstr s
-+ | false, true -> fun s -> replace_first ~rex ~pos:!offset ~templ:sstr s
-+ | true, true -> fun s -> qreplace_first ~rex ~pos:!offset ~templ:sstr s
-+
-+let _ =
-+ let substitute = parse_args () in
-+ foreach_line (fun line ->
-+ try print_endline (substitute line)
-+ with Invalid_argument _ -> print_endline line)
-diff --git a/bundles/pcre2/pcre2-ocaml/lib/Makefile b/bundles/pcre2/pcre2-ocaml/lib/Makefile
-new file mode 100644
-index 000000000..ef5f07cfe
---- /dev/null
-+++ b/bundles/pcre2/pcre2-ocaml/lib/Makefile
-@@ -0,0 +1,15 @@
-+TARGETS = pcre2.cma libpcre2_stubs.a
-+
-+.PHONY: all clean clean-compile-commands
-+
-+all: compile_commands.json
-+ @dune build $(TARGETS)
-+
-+clean: clean-compile-commands
-+ @dune clean
-+
-+compile_commands.json: config/dune config/discover.ml $(wildcard *.c *.h)
-+ @dune rules | dune-compiledb
-+
-+clean-compile-commands:
-+ @rm -f compile_commands.json
-diff --git a/bundles/pcre/pcre-ocaml/src/config/Makefile b/bundles/pcre2/pcre2-ocaml/lib/config/Makefile
-similarity index 100%
-rename from bundles/pcre/pcre-ocaml/src/config/Makefile
-rename to bundles/pcre2/pcre2-ocaml/lib/config/Makefile
-diff --git a/bundles/pcre2/pcre2-ocaml/lib/config/discover.ml b/bundles/pcre2/pcre2-ocaml/lib/config/discover.ml
-new file mode 100644
-index 000000000..94524c65c
---- /dev/null
-+++ b/bundles/pcre2/pcre2-ocaml/lib/config/discover.ml
-@@ -0,0 +1,14 @@
-+let () =
-+ let module C = Configurator.V1 in
-+ C.main ~name:"pcre2" (fun c ->
-+ let default : C.Pkg_config.package_conf =
-+ { libs = [ "-lpcre2-8" ]; cflags = [] }
-+ in
-+ let conf =
-+ match C.Pkg_config.get c with
-+ | None -> default
-+ | Some pc ->
-+ Option.value (C.Pkg_config.query pc ~package:"libpcre2-8") ~default
-+ in
-+ C.Flags.write_sexp "c_flags.sexp" conf.cflags;
-+ C.Flags.write_sexp "c_library_flags.sexp" conf.libs)
-diff --git a/bundles/pcre2/pcre2-ocaml/lib/config/dune b/bundles/pcre2/pcre2-ocaml/lib/config/dune
-new file mode 100644
-index 000000000..ec1eb67f6
---- /dev/null
-+++ b/bundles/pcre2/pcre2-ocaml/lib/config/dune
-@@ -0,0 +1,4 @@
-+(executables
-+ (names discover)
-+ (libraries dune.configurator)
-+ (modes byte exe))
-diff --git a/bundles/pcre2/pcre2-ocaml/lib/dune b/bundles/pcre2/pcre2-ocaml/lib/dune
-new file mode 100644
-index 000000000..22e570f07
---- /dev/null
-+++ b/bundles/pcre2/pcre2-ocaml/lib/dune
-@@ -0,0 +1,18 @@
-+(library
-+ (public_name pcre2)
-+ (foreign_stubs
-+ (language c)
-+ (names pcre2_stubs)
-+ (flags
-+ (:standard)
-+ (:include c_flags.sexp)
-+ -O2
-+ -fPIC
-+ -DPIC))
-+ (c_library_flags
-+ (:include c_library_flags.sexp)))
-+
-+(rule
-+ (targets c_flags.sexp c_library_flags.sexp)
-+ (action
-+ (run ./config/discover.exe)))
-diff --git a/bundles/pcre2/pcre2-ocaml/lib/pcre2.ml b/bundles/pcre2/pcre2-ocaml/lib/pcre2.ml
-new file mode 100644
-index 000000000..b8e2c3c41
---- /dev/null
-+++ b/bundles/pcre2/pcre2-ocaml/lib/pcre2.ml
-@@ -0,0 +1,1231 @@
-+(* PCRE2-OCAML - Perl Compatibility Regular Expressions for OCaml
-+
-+ Copyright © 1999- Markus Mottl <markus.mottl@gmail.com>
-+
-+ This library is free software; you can redistribute it and/or modify it under
-+ the terms of the GNU Lesser General Public License as published by the Free
-+ Software Foundation; either version 2.1 of the License, or (at your option)
-+ any later version.
-+
-+ This library is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-+ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-+ details.
-+
-+ You should have received a copy of the GNU Lesser General Public License
-+ along with this library; if not, write to the Free Software Foundation, Inc.,
-+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *)
-+
-+(* Public exceptions and their registration with the C runtime *)
-+
-+open Printf
-+
-+type error =
-+ | Partial
-+ | BadPattern of string * int
-+ | BadUTF
-+ | BadUTFOffset
-+ | MatchLimit
-+ | DepthLimit
-+ | WorkspaceSize
-+ | InternalError of string
-+
-+let string_of_error = function
-+ | Partial -> "Partial"
-+ | BadPattern (msg, pos) -> sprintf "Pcre2.BadPattern(%S, pos=%i)" msg pos
-+ | BadUTF -> "BadUTF"
-+ | BadUTFOffset -> "BadUTFOffset"
-+ | MatchLimit -> "MatchLimit"
-+ | DepthLimit -> "DepthLimit"
-+ | WorkspaceSize -> "WorkspaceSize"
-+ | InternalError msg -> sprintf "InternalError(%S)" msg
-+
-+exception Error of error
-+exception Backtrack
-+exception Regexp_or of string * error
-+
-+let string_of_exn = function
-+ | Error error -> Some (sprintf "Pcre2.Error(%s)" (string_of_error error))
-+ | Backtrack -> Some "Pcre2.Backtrack"
-+ | Regexp_or (pat, error) ->
-+ Some (sprintf "Pcre2.Regexp_or(pat=%S, %s)" pat (string_of_error error))
-+ | _not_from_pcre -> None
-+
-+let () = Printexc.register_printer string_of_exn
-+
-+(* Puts exceptions into global C-variables for fast retrieval *)
-+external pcre2_ocaml_init : unit -> unit = "pcre2_ocaml_init"
-+
-+(* Registers exceptions with the C runtime and caches polymorphic variants *)
-+let () =
-+ Callback.register_exception "Pcre2.Error" (Error (InternalError ""));
-+ Callback.register_exception "Pcre2.Backtrack" Backtrack;
-+ pcre2_ocaml_init ()
-+
-+(* Compilation and runtime flags and their conversion functions *)
-+
-+type icflag = int64
-+type irflag = int64
-+
-+(* Compilation flags *)
-+
-+type cflag =
-+ [ `ALLOW_EMPTY_CLASS
-+ | `ALT_BSUX
-+ | `ALT_CIRCUMFLEX
-+ | `ALT_VERBNAMES
-+ | `ANCHORED
-+ | `AUTO_CALLOUT
-+ | `CASELESS
-+ | `DOLLAR_ENDONLY
-+ | `DOTALL
-+ | `DUPNAMES
-+ | `ENDANCHORED
-+ | `EXTENDED
-+ | `EXTENDED_MORE
-+ | `FIRSTLINE
-+ | `LITERAL
-+ | `MATCH_INVALID_UTF
-+ | `MATCH_UNSET_BACKREF
-+ | `MULTILINE
-+ | `NEVER_BACKSLASH_C
-+ | `NEVER_UCP
-+ | `NEVER_UTF
-+ | `NO_AUTO_CAPTURE
-+ | `NO_AUTO_POSSESS
-+ | `NO_DOTSTAR_ANCHOR
-+ | `NO_START_OPTIMIZE
-+ | `NO_UTF_CHECK
-+ | `UCP
-+ | `UNGREEDY
-+ | `USE_OFFSET_LIMIT
-+ | `UTF ]
-+
-+let int_of_cflag = function
-+ | `ALLOW_EMPTY_CLASS -> 0x00000001L
-+ | `ALT_BSUX -> 0x00000002L
-+ | `AUTO_CALLOUT -> 0x00000004L
-+ | `CASELESS -> 0x00000008L
-+ | `DOLLAR_ENDONLY -> 0x00000010L
-+ | `DOTALL -> 0x00000020L
-+ | `DUPNAMES -> 0x00000040L
-+ | `EXTENDED -> 0x00000080L
-+ | `FIRSTLINE -> 0x00000100L
-+ | `MATCH_UNSET_BACKREF -> 0x00000200L
-+ | `MULTILINE -> 0x00000400L
-+ | `NEVER_UCP -> 0x00000800L
-+ | `NEVER_UTF -> 0x00001000L
-+ | `NO_AUTO_CAPTURE -> 0x00002000L
-+ | `NO_AUTO_POSSESS -> 0x00004000L
-+ | `NO_DOTSTAR_ANCHOR -> 0x00008000L
-+ | `NO_START_OPTIMIZE -> 0x00010000L
-+ | `UCP -> 0x00020000L
-+ | `UNGREEDY -> 0x00040000L
-+ | `UTF -> 0x00080000L
-+ | `NEVER_BACKSLASH_C -> 0x00100000L
-+ | `ALT_CIRCUMFLEX -> 0x00200000L
-+ | `ALT_VERBNAMES -> 0x00400000L
-+ | `USE_OFFSET_LIMIT -> 0x00800000L
-+ | `EXTENDED_MORE -> 0x01000000L
-+ | `LITERAL -> 0x02000000L
-+ | `MATCH_INVALID_UTF -> 0x04000000L
-+ | `ENDANCHORED -> 0x20000000L
-+ | `NO_UTF_CHECK -> 0x40000000L
-+ | `ANCHORED -> 0x80000000L
-+
-+let coll_icflag icflag flag = Int64.logor (int_of_cflag flag) icflag
-+let cflags flags = List.fold_left coll_icflag 0L flags
-+
-+let cflag_of_int = function
-+ | 0x00000001L -> `ALLOW_EMPTY_CLASS
-+ | 0x00000002L -> `ALT_BSUX
-+ | 0x00000004L -> `AUTO_CALLOUT
-+ | 0x00000008L -> `CASELESS
-+ | 0x00000010L -> `DOLLAR_ENDONLY
-+ | 0x00000020L -> `DOTALL
-+ | 0x00000040L -> `DUPNAMES
-+ | 0x00000080L -> `EXTENDED
-+ | 0x00000100L -> `FIRSTLINE
-+ | 0x00000200L -> `MATCH_UNSET_BACKREF
-+ | 0x00000400L -> `MULTILINE
-+ | 0x00000800L -> `NEVER_UCP
-+ | 0x00001000L -> `NEVER_UTF
-+ | 0x00002000L -> `NO_AUTO_CAPTURE
-+ | 0x00004000L -> `NO_AUTO_POSSESS
-+ | 0x00008000L -> `NO_DOTSTAR_ANCHOR
-+ | 0x00010000L -> `NO_START_OPTIMIZE
-+ | 0x00020000L -> `UCP
-+ | 0x00040000L -> `UNGREEDY
-+ | 0x00080000L -> `UTF
-+ | 0x00100000L -> `NEVER_BACKSLASH_C
-+ | 0x00200000L -> `ALT_CIRCUMFLEX
-+ | 0x00400000L -> `ALT_VERBNAMES
-+ | 0x00800000L -> `USE_OFFSET_LIMIT
-+ | 0x01000000L -> `EXTENDED_MORE
-+ | 0x02000000L -> `LITERAL
-+ | 0x04000000L -> `MATCH_INVALID_UTF
-+ | 0x20000000L -> `ENDANCHORED
-+ | 0x40000000L -> `NO_UTF_CHECK
-+ | 0x80000000L -> `ANCHORED
-+ | _ -> failwith "Pcre2.cflag_list: unknown compilation flag"
-+
-+let all_cflags =
-+ [
-+ 0x00000001L;
-+ 0x00000002L;
-+ 0x00000004L;
-+ 0x00000008L;
-+ 0x00000010L;
-+ 0x00000020L;
-+ 0x00000040L;
-+ 0x00000080L;
-+ 0x00000100L;
-+ 0x00000200L;
-+ 0x00000400L;
-+ 0x00000800L;
-+ 0x00001000L;
-+ 0x00002000L;
-+ 0x00004000L;
-+ 0x00008000L;
-+ 0x00010000L;
-+ 0x00020000L;
-+ 0x00040000L;
-+ 0x00080000L;
-+ 0x00100000L;
-+ 0x00200000L;
-+ 0x00400000L;
-+ 0x00800000L;
-+ 0x01000000L;
-+ 0x02000000L;
-+ 0x04000000L;
-+ 0x20000000L;
-+ 0x40000000L;
-+ 0x80000000L;
-+ ]
-+
-+let cflag_list icflags =
-+ let coll flag_list flag =
-+ if Int64.equal (Int64.logand icflags flag) 0L then flag_list
-+ else cflag_of_int flag :: flag_list
-+ in
-+ List.fold_left coll [] all_cflags
-+
-+(* Runtime flags *)
-+
-+type rflag =
-+ [ `ANCHORED
-+ | `COPY_MATCHED_SUBJECT
-+ | `DFA_RESTART
-+ | `DFA_SHORTEST
-+ | `ENDANCHORED
-+ | `NOTBOL
-+ | `NOTEOL
-+ | `NOTEMPTY
-+ | `NOTEMPTY_ATSTART
-+ | `NO_JIT
-+ | `NO_UTF_CHECK
-+ | `PARTIAL_HARD
-+ | `PARTIAL_SOFT ]
-+
-+let int_of_rflag = function
-+ | `NOTBOL -> 0x00000001L
-+ | `NOTEOL -> 0x00000002L
-+ | `NOTEMPTY -> 0x00000004L
-+ | `NOTEMPTY_ATSTART -> 0x00000008L
-+ | `PARTIAL_SOFT -> 0x00000010L
-+ | `PARTIAL_HARD -> 0x00000020L
-+ | `DFA_RESTART -> 0x00000040L
-+ | `DFA_SHORTEST -> 0x00000080L
-+ | `NO_JIT -> 0x00002000L
-+ | `COPY_MATCHED_SUBJECT -> 0x00004000L
-+ | `ENDANCHORED -> 0x20000000L
-+ | `NO_UTF_CHECK -> 0x40000000L
-+ | `ANCHORED -> 0x80000000L
-+
-+let coll_irflag irflag flag = Int64.logor (int_of_rflag flag) irflag
-+let rflags flags = List.fold_left coll_irflag 0L flags
-+
-+let rflag_of_int = function
-+ | 0x00000001L -> `NOTBOL
-+ | 0x00000002L -> `NOTEOL
-+ | 0x00000004L -> `NOTEMPTY
-+ | 0x00000008L -> `NOTEMPTY_ATSTART
-+ | 0x00000010L -> `PARTIAL_SOFT
-+ | 0x00000020L -> `PARTIAL_HARD
-+ | 0x00000040L -> `DFA_RESTART
-+ | 0x00000080L -> `DFA_SHORTEST
-+ | 0x00002000L -> `NO_JIT
-+ | 0x00004000L -> `COPY_MATCHED_SUBJECT
-+ | 0x20000000L -> `ENDANCHORED
-+ | 0x40000000L -> `NO_UTF_CHECK
-+ | 0x80000000L -> `ANCHORED
-+ | _ -> failwith "Pcre2.rflag_list: unknown runtime flag"
-+
-+let all_rflags =
-+ [
-+ 0x00000001L;
-+ 0x00000002L;
-+ 0x00000004L;
-+ 0x00000008L;
-+ 0x00000010L;
-+ 0x00000020L;
-+ 0x00000040L;
-+ 0x00000080L;
-+ 0x00002000L;
-+ 0x00004000L;
-+ 0x20000000L;
-+ 0x40000000L;
-+ 0x80000000L;
-+ ]
-+
-+let rflag_list irflags =
-+ let coll flag_list flag =
-+ if Int64.equal (Int64.logand irflags flag) 0L then flag_list
-+ else rflag_of_int flag :: flag_list
-+ in
-+ List.fold_left coll [] all_rflags
-+
-+(* Information on the PCRE2-configuration (build-time options) *)
-+
-+external pcre2_version : unit -> string = "pcre2_version_stub"
-+
-+external pcre2_config_unicode : unit -> bool = "pcre2_config_unicode_stub"
-+[@@noalloc]
-+
-+external pcre2_config_newline : unit -> char = "pcre2_config_newline_stub"
-+[@@noalloc]
-+
-+external pcre2_config_link_size : unit -> (int[@untagged])
-+ = "pcre2_config_link_size_stub_bc" "pcre2_config_link_size_stub"
-+[@@noalloc]
-+
-+external pcre2_config_match_limit : unit -> (int[@untagged])
-+ = "pcre2_config_match_limit_stub_bc" "pcre2_config_match_limit_stub"
-+[@@noalloc]
-+
-+external pcre2_config_depth_limit : unit -> (int[@untagged])
-+ = "pcre2_config_depth_limit_stub_bc" "pcre2_config_depth_limit_stub"
-+[@@noalloc]
-+
-+external pcre2_config_stackrecurse : unit -> bool
-+ = "pcre2_config_stackrecurse_stub"
-+[@@noalloc]
-+
-+let version = pcre2_version ()
-+let config_unicode = pcre2_config_unicode ()
-+let config_newline = pcre2_config_newline ()
-+let config_link_size = pcre2_config_link_size ()
-+let config_match_limit = pcre2_config_match_limit ()
-+let config_depth_limit = pcre2_config_depth_limit ()
-+let config_stackrecurse = pcre2_config_stackrecurse ()
-+
-+(* Information on patterns *)
-+
-+type firstcodeunit_info = [ `Char of char | `Start_only | `ANCHORED ]
-+type regexp
-+
-+external options : regexp -> (icflag[@unboxed])
-+ = "pcre2_argoptions_stub_bc" "pcre2_argoptions_stub"
-+
-+external size : regexp -> (int[@untagged])
-+ = "pcre2_size_stub_bc" "pcre2_size_stub"
-+
-+external capturecount : regexp -> (int[@untagged])
-+ = "pcre2_capturecount_stub_bc" "pcre2_capturecount_stub"
-+
-+external backrefmax : regexp -> (int[@untagged])
-+ = "pcre2_backrefmax_stub_bc" "pcre2_backrefmax_stub"
-+
-+external namecount : regexp -> (int[@untagged])
-+ = "pcre2_namecount_stub_bc" "pcre2_namecount_stub"
-+
-+external nameentrysize : regexp -> (int[@untagged])
-+ = "pcre2_nameentrysize_stub_bc" "pcre2_nameentrysize_stub"
-+
-+external names : regexp -> string array = "pcre2_names_stub"
-+
-+external firstcodeunit : regexp -> firstcodeunit_info
-+ = "pcre2_firstcodeunit_stub"
-+
-+external lastcodeunit : regexp -> char option = "pcre2_lastcodeunit_stub"
-+
-+(* Compilation of patterns *)
-+
-+type chtables
-+
-+external maketables : unit -> chtables = "pcre2_maketables_stub"
-+
-+external compile : (icflag[@unboxed]) -> chtables option -> string -> regexp
-+ = "pcre2_compile_stub_bc" "pcre2_compile_stub"
-+
-+(* external get_match_limit : regexp -> int option =
-+ "pcre2_get_match_limit_stub" *)
-+
-+(* Internal use only! *)
-+external set_imp_match_limit : regexp -> (int[@untagged]) -> regexp
-+ = "pcre2_set_imp_match_limit_stub_bc" "pcre2_set_imp_match_limit_stub"
-+[@@noalloc]
-+
-+(* external get_depth_limit : regexp -> int option =
-+ "pcre2_get_depth_limit_stub" *)
-+
-+(* Internal use only! *)
-+external set_imp_depth_limit : regexp -> (int[@untagged]) -> regexp
-+ = "pcre2_set_imp_depth_limit_stub_bc" "pcre2_set_imp_depth_limit_stub"
-+[@@noalloc]
-+
-+(* TODO implement jit using new pcre2_jit_compile api *)
-+let regexp
-+ (* ?(jit_compile = false) *)
-+ ?limit ?depth_limit ?(iflags = 0L) ?flags ?chtables pat =
-+ let rex =
-+ match flags with
-+ | Some flag_list -> compile (cflags flag_list) chtables pat
-+ | _ -> compile iflags chtables pat
-+ in
-+ let rex =
-+ match limit with None -> rex | Some lim -> set_imp_match_limit rex lim
-+ in
-+ match depth_limit with None -> rex | Some lim -> set_imp_depth_limit rex lim
-+
-+let regexp_or (* ?jit_compile *) ?limit ?depth_limit ?(iflags = 0L) ?flags
-+ ?chtables pats =
-+ let check pat =
-+ try ignore (regexp ~iflags ?flags ?chtables pat)
-+ with Error error -> raise (Regexp_or (pat, error))
-+ in
-+ List.iter check pats;
-+ let big_pat =
-+ let cnv pat = "(?:" ^ pat ^ ")" in
-+ String.concat "|" (List.rev (List.rev_map cnv pats))
-+ in
-+ regexp (* ?jit_compile *) ?limit ?depth_limit ~iflags ?flags ?chtables big_pat
-+
-+let bytes_unsafe_blit_string str str_ofs bts bts_ofs len =
-+ let str_bts = Bytes.unsafe_of_string str in
-+ Bytes.unsafe_blit str_bts str_ofs bts bts_ofs len
-+
-+let string_unsafe_sub str ofs len =
-+ let res = Bytes.create len in
-+ bytes_unsafe_blit_string str ofs res 0 len;
-+ Bytes.unsafe_to_string res
-+
-+let quote s =
-+ let len = String.length s in
-+ let buf = Bytes.create (len lsl 1) in
-+ let pos = ref 0 in
-+ for i = 0 to len - 1 do
-+ match String.unsafe_get s i with
-+ | ('\\' | '^' | '$' | '.' | '[' | '|' | '(' | ')' | '?' | '*' | '+' | '{')
-+ as c ->
-+ Bytes.unsafe_set buf !pos '\\';
-+ incr pos;
-+ Bytes.unsafe_set buf !pos c;
-+ incr pos
-+ | c ->
-+ Bytes.unsafe_set buf !pos c;
-+ incr pos
-+ done;
-+ string_unsafe_sub (Bytes.unsafe_to_string buf) 0 !pos
-+
-+(* Matching of patterns and subpattern extraction *)
-+
-+(* Default regular expression when none is provided by the user *)
-+let def_rex = regexp (* ~jit_compile:true *) "\\s+"
-+
-+type substrings = string * int array
-+
-+type callout_data = {
-+ callout_number : int;
-+ substrings : substrings;
-+ start_match : int;
-+ current_position : int;
-+ capture_top : int;
-+ capture_last : int;
-+ pattern_position : int;
-+ next_item_length : int;
-+}
-+
-+type callout = callout_data -> unit
-+
-+let get_subject (subj, _) = subj
-+let num_of_subs (_, ovector) = Array.length ovector / 3
-+
-+let get_offset_start ovector str_num =
-+ if str_num < 0 || str_num >= Array.length ovector / 3 then
-+ invalid_arg "Pcre2.get_offset_start: illegal offset";
-+ let offset = str_num lsl 1 in
-+ (offset, Array.unsafe_get ovector offset)
-+
-+let get_substring_aux (subj, ovector) offset start =
-+ if start < 0 then raise Not_found
-+ else
-+ string_unsafe_sub subj start (Array.unsafe_get ovector (offset + 1) - start)
-+
-+let get_substring ((_, ovector) as substrings) str_num =
-+ let offset, start = get_offset_start ovector str_num in
-+ get_substring_aux substrings offset start
-+
-+let get_substring_ofs (_subj, ovector) str_num =
-+ let offset, start = get_offset_start ovector str_num in
-+ if start < 0 then raise Not_found
-+ else (start, Array.unsafe_get ovector (offset + 1))
-+
-+let unsafe_get_substring ((_, ovector) as substrings) str_num =
-+ let offset = str_num lsl 1 in
-+ try get_substring_aux substrings offset (Array.unsafe_get ovector offset)
-+ with Not_found -> ""
-+
-+let get_substrings ?(full_match = true) ((_, ovector) as substrings) =
-+ if full_match then
-+ Array.init (Array.length ovector / 3) (unsafe_get_substring substrings)
-+ else
-+ let len = (Array.length ovector / 3) - 1 in
-+ Array.init len (fun n -> unsafe_get_substring substrings (n + 1))
-+
-+let unsafe_get_opt_substring ((_, ovector) as substrings) str_num =
-+ let offset = str_num lsl 1 in
-+ try
-+ let start = Array.unsafe_get ovector offset in
-+ let str = get_substring_aux substrings offset start in
-+ Some str
-+ with Not_found -> None
-+
-+let get_opt_substrings ?(full_match = true) ((_, ovector) as substrings) =
-+ if full_match then
-+ Array.init (Array.length ovector / 3) (unsafe_get_opt_substring substrings)
-+ else
-+ let len = (Array.length ovector / 3) - 1 in
-+ Array.init len (fun n -> unsafe_get_opt_substring substrings (n + 1))
-+
-+external get_stringnumber : regexp -> string -> (int[@untagged])
-+ = "pcre2_substring_number_from_name_stub_bc"
-+ "pcre2_substring_number_from_name_stub"
-+
-+let get_named_substring rex name substrings =
-+ get_substring substrings (get_stringnumber rex name)
-+
-+let get_named_substring_ofs rex name substrings =
-+ get_substring_ofs substrings (get_stringnumber rex name)
-+
-+external unsafe_pcre2_match :
-+ (irflag[@unboxed]) ->
-+ regexp ->
-+ pos:(int[@untagged]) ->
-+ subj_start:(int[@untagged]) ->
-+ subj:string ->
-+ int array ->
-+ callout option ->
-+ unit = "pcre2_match_stub_bc" "pcre2_match_stub"
-+
-+let make_ovector rex =
-+ let subgroups1 = capturecount rex + 1 in
-+ let subgroups2 = subgroups1 lsl 1 in
-+ (subgroups2, Array.make (subgroups1 + subgroups2) 0)
-+
-+external unsafe_pcre2_dfa_match :
-+ (irflag[@unboxed]) ->
-+ regexp ->
-+ pos:(int[@untagged]) ->
-+ subj_start:(int[@untagged]) ->
-+ subj:string ->
-+ int array ->
-+ callout option ->
-+ workspace:int array ->
-+ unit = "pcre2_dfa_match_stub_bc" "pcre2_match_stub0"
-+
-+let pcre2_dfa_match ?(iflags = 0L) ?flags ?(rex = def_rex) ?pat ?(pos = 0)
-+ ?callout ?(workspace = Array.make 20 0) subj =
-+ let rex = match pat with Some str -> regexp str | _ -> rex in
-+ let iflags = match flags with Some flags -> rflags flags | _ -> iflags in
-+ let _, ovector = make_ovector rex in
-+ unsafe_pcre2_dfa_match iflags rex ~pos ~subj_start:0 ~subj ovector callout
-+ ~workspace;
-+ ovector
-+
-+let pcre2_match ?(iflags = 0L) ?flags ?(rex = def_rex) ?pat ?(pos = 0) ?callout
-+ subj =
-+ let rex = match pat with Some str -> regexp str | _ -> rex in
-+ let iflags = match flags with Some flags -> rflags flags | _ -> iflags in
-+ let _, ovector = make_ovector rex in
-+ unsafe_pcre2_match iflags rex ~pos ~subj_start:0 ~subj ovector callout;
-+ ovector
-+
-+let exec ?iflags ?flags ?rex ?pat ?pos ?callout subj =
-+ (subj, pcre2_match ?iflags ?flags ?rex ?pat ?pos ?callout subj)
-+
-+let next_match ?iflags ?flags ?rex ?pat ?(pos = 0) ?callout (subj, ovector) =
-+ let pos = Array.unsafe_get ovector 1 + pos in
-+ let subj_len = String.length subj in
-+ if pos < 0 || pos > subj_len then
-+ invalid_arg "Pcre2.next_match: illegal offset";
-+ (subj, pcre2_match ?iflags ?flags ?rex ?pat ~pos ?callout subj)
-+
-+let rec copy_lst ar n = function
-+ | [] -> ar
-+ | h :: t ->
-+ Array.unsafe_set ar n h;
-+ copy_lst ar (n - 1) t
-+
-+let exec_all ?(iflags = 0L) ?flags ?(rex = def_rex) ?pat ?pos ?callout subj =
-+ let rex = match pat with Some str -> regexp str | _ -> rex in
-+ let iflags = match flags with Some flags -> rflags flags | _ -> iflags in
-+ let ((_, ovector) as sstrs) = exec ~iflags ~rex ?pos ?callout subj in
-+ let null_flags = Int64.logor iflags 0x00000004L in
-+ (* `NOTEMPTY *)
-+ let subj_len = String.length subj in
-+ let rec loop pos ((subj, ovector) as sstrs) n lst =
-+ let maybe_ovector =
-+ try
-+ let first = Array.unsafe_get ovector 0 in
-+ if first = pos && Array.unsafe_get ovector 1 = pos then
-+ if pos = subj_len then None
-+ else Some (pcre2_match ~iflags:null_flags ~rex ~pos ?callout subj)
-+ else Some (pcre2_match ~iflags ~rex ~pos ?callout subj)
-+ with Not_found -> None
-+ in
-+ match maybe_ovector with
-+ | Some ovector ->
-+ let new_pos = Array.unsafe_get ovector 1 in
-+ loop new_pos (subj, ovector) (n + 1) (sstrs :: lst)
-+ | None -> copy_lst (Array.make (n + 1) sstrs) (n - 1) lst
-+ in
-+ loop (Array.unsafe_get ovector 1) sstrs 0 []
-+
-+let extract ?iflags ?flags ?rex ?pat ?pos ?full_match ?callout subj =
-+ get_substrings ?full_match (exec ?iflags ?flags ?rex ?pat ?pos ?callout subj)
-+
-+let extract_opt ?iflags ?flags ?rex ?pat ?pos ?full_match ?callout subj =
-+ get_opt_substrings ?full_match
-+ (exec ?iflags ?flags ?rex ?pat ?pos ?callout subj)
-+
-+let extract_all ?iflags ?flags ?rex ?pat ?pos ?full_match ?callout subj =
-+ let many_sstrs = exec_all ?iflags ?flags ?rex ?pat ?pos ?callout subj in
-+ Array.map (get_substrings ?full_match) many_sstrs
-+
-+let extract_all_opt ?iflags ?flags ?rex ?pat ?pos ?full_match ?callout subj =
-+ let many_sstrs = exec_all ?iflags ?flags ?rex ?pat ?pos ?callout subj in
-+ Array.map (get_opt_substrings ?full_match) many_sstrs
-+
-+let pmatch ?iflags ?flags ?rex ?pat ?pos ?callout subj =
-+ try
-+ ignore (pcre2_match ?iflags ?flags ?rex ?pat ?pos ?callout subj);
-+ true
-+ with Not_found -> false
-+
-+(* String substitution *)
-+
-+(* Elements of a substitution pattern *)
-+type subst =
-+ | SubstString of int * int (* Denotes a substring in the substitution *)
-+ | Backref of int (* nth backreference ($0 is program name!) *)
-+ | Match (* The whole matched string *)
-+ | PreMatch (* The string before the match *)
-+ | PostMatch (* The string after the match *)
-+ | LastParenMatch (* The last matched group *)
-+
-+(* Information on substitution patterns *)
-+type substitution =
-+ string (* The substitution string *)
-+ * int (* Highest group number of backreferences *)
-+ * bool (* Makes use of "LastParenMatch" *)
-+ * subst list (* The list of substitution elements *)
-+
-+(* Only used internally in "subst" *)
-+exception FoundAt of int
-+
-+let zero = Char.code '0'
-+
-+let subst str =
-+ let max_br = ref 0 in
-+ let with_lp = ref false in
-+ let lix = String.length str - 1 in
-+ let rec loop acc n =
-+ if lix < n then acc
-+ else
-+ try
-+ for i = n to lix do
-+ if String.unsafe_get str i = '$' then raise (FoundAt i)
-+ done;
-+ SubstString (n, lix - n + 1) :: acc
-+ with FoundAt i -> (
-+ if i = lix then SubstString (n, lix - n + 1) :: acc
-+ else
-+ let i1 = i + 1 in
-+ let acc = if n = i then acc else SubstString (n, i - n) :: acc in
-+ match String.unsafe_get str i1 with
-+ | '0' .. '9' as c -> (
-+ let subpat_nr = ref (Char.code c - zero) in
-+ try
-+ for j = i1 + 1 to lix do
-+ let c = String.unsafe_get str j in
-+ if c >= '0' && c <= '9' then
-+ subpat_nr := (10 * !subpat_nr) + Char.code c - zero
-+ else raise (FoundAt j)
-+ done;
-+ max_br := max !subpat_nr !max_br;
-+ Backref !subpat_nr :: acc
-+ with FoundAt j ->
-+ max_br := max !subpat_nr !max_br;
-+ loop (Backref !subpat_nr :: acc) j)
-+ | '!' -> loop acc (i1 + 1)
-+ | '$' -> loop (SubstString (i1, 1) :: acc) (i1 + 1)
-+ | '&' -> loop (Match :: acc) (i1 + 1)
-+ | '`' -> loop (PreMatch :: acc) (i1 + 1)
-+ | '\'' -> loop (PostMatch :: acc) (i1 + 1)
-+ | '+' ->
-+ with_lp := true;
-+ loop (LastParenMatch :: acc) (i1 + 1)
-+ | _ -> loop acc i1)
-+ in
-+ let subst_lst = loop [] 0 in
-+ (str, !max_br, !with_lp, subst_lst)
-+
-+let def_subst = subst ""
-+
-+(* Calculates a list of tuples (str, offset, len) which contain substrings to be
-+ copied on substitutions. Internal use only! *)
-+let calc_trans_lst subgroups2 ovector subj templ subst_lst =
-+ let prefix_len = Array.unsafe_get ovector 0 in
-+ let last = Array.unsafe_get ovector 1 in
-+ let coll ((res_len, trans_lst) as accu) =
-+ let return_lst ((_str, _ix, len) as el) =
-+ if len = 0 then accu else (res_len + len, el :: trans_lst)
-+ in
-+ function
-+ | SubstString (ix, len) -> return_lst (templ, ix, len)
-+ | Backref 0 ->
-+ let prog_name = Sys.argv.(0) in
-+ return_lst (prog_name, 0, String.length prog_name)
-+ | Backref n ->
-+ let offset = n lsl 1 in
-+ let start = Array.unsafe_get ovector offset in
-+ let len = Array.unsafe_get ovector (offset + 1) - start in
-+ return_lst (subj, start, len)
-+ | Match -> return_lst (subj, prefix_len, last - prefix_len)
-+ | PreMatch -> return_lst (subj, 0, prefix_len)
-+ | PostMatch -> return_lst (subj, last, String.length subj - last)
-+ | LastParenMatch ->
-+ let subgroups2_2 = subgroups2 - 2 in
-+ let pos = ref subgroups2_2 in
-+ let ix = ref (Array.unsafe_get ovector subgroups2_2) in
-+ while !ix < 0 do
-+ let pos_2 = !pos - 2 in
-+ pos := pos_2;
-+ ix := Array.unsafe_get ovector pos_2
-+ done;
-+ return_lst (subj, !ix, Array.unsafe_get ovector (!pos + 1) - !ix)
-+ in
-+ List.fold_left coll (0, []) subst_lst
-+
-+let replace ?(iflags = 0L) ?flags ?(rex = def_rex) ?pat ?(pos = 0)
-+ ?(itempl = def_subst) ?templ ?callout subj =
-+ let rex = match pat with Some str -> regexp str | _ -> rex in
-+ let iflags = match flags with Some flags -> rflags flags | _ -> iflags in
-+ let templ, max_br, with_lp, subst_lst =
-+ match templ with Some str -> subst str | _ -> itempl
-+ in
-+ let subj_len = String.length subj in
-+ if pos < 0 || pos > subj_len then invalid_arg "Pcre2.replace: illegal offset";
-+ let subgroups2, ovector = make_ovector rex in
-+ let nsubs = (subgroups2 lsr 1) - 1 in
-+ if max_br > nsubs then
-+ failwith "Pcre2.replace: backreference denotes nonexistent subpattern";
-+ if with_lp && nsubs = 0 then failwith "Pcre2.replace: no backreferences";
-+ let rec loop full_len trans_lsts cur_pos =
-+ if
-+ cur_pos > subj_len
-+ ||
-+ try
-+ unsafe_pcre2_match iflags rex ~pos:cur_pos ~subj_start:0 ~subj ovector
-+ callout;
-+ false
-+ with Not_found -> true
-+ then (
-+ let postfix_len = max (subj_len - cur_pos) 0 in
-+ let left = pos + full_len in
-+ let res = Bytes.create (left + postfix_len) in
-+ bytes_unsafe_blit_string subj 0 res 0 pos;
-+ bytes_unsafe_blit_string subj cur_pos res left postfix_len;
-+ let inner_coll ofs (templ, ix, len) =
-+ bytes_unsafe_blit_string templ ix res ofs len;
-+ ofs + len
-+ in
-+ let coll ofs (res_len, trans_lst) =
-+ let new_ofs = ofs - res_len in
-+ let _ = List.fold_left inner_coll new_ofs trans_lst in
-+ new_ofs
-+ in
-+ let _ = List.fold_left coll left trans_lsts in
-+ Bytes.unsafe_to_string res)
-+ else
-+ let first = Array.unsafe_get ovector 0 in
-+ let len = first - cur_pos in
-+ let ((res_len, _) as trans_lst_el) =
-+ calc_trans_lst subgroups2 ovector subj templ subst_lst
-+ in
-+ let trans_lsts =
-+ if len > 0 then
-+ trans_lst_el :: (len, [ (subj, cur_pos, len) ]) :: trans_lsts
-+ else trans_lst_el :: trans_lsts
-+ in
-+ let full_len = full_len + len + res_len in
-+ let next = first + 1 in
-+ let last = Array.unsafe_get ovector 1 in
-+ if last < next then
-+ if first < subj_len then
-+ let new_trans_lsts =
-+ (1, [ (subj, cur_pos + len, 1) ]) :: trans_lsts
-+ in
-+ loop (full_len + 1) new_trans_lsts next
-+ else loop full_len trans_lsts next
-+ else loop full_len trans_lsts last
-+ in
-+ loop 0 [] pos
-+
-+let qreplace ?(iflags = 0L) ?flags ?(rex = def_rex) ?pat ?(pos = 0)
-+ ?(templ = "") ?callout subj =
-+ let rex = match pat with Some str -> regexp str | _ -> rex in
-+ let iflags = match flags with Some flags -> rflags flags | _ -> iflags in
-+ let subj_len = String.length subj in
-+ if pos < 0 || pos > subj_len then invalid_arg "Pcre2.qreplace: illegal offset";
-+ let templ_len = String.length templ in
-+ let _, ovector = make_ovector rex in
-+ let rec loop full_len subst_lst cur_pos =
-+ if
-+ cur_pos > subj_len
-+ ||
-+ try
-+ unsafe_pcre2_match iflags rex ~pos:cur_pos ~subj_start:0 ~subj ovector
-+ callout;
-+ false
-+ with Not_found -> true
-+ then (
-+ let postfix_len = max (subj_len - cur_pos) 0 in
-+ let left = pos + full_len in
-+ let res = Bytes.create (left + postfix_len) in
-+ bytes_unsafe_blit_string subj 0 res 0 pos;
-+ bytes_unsafe_blit_string subj cur_pos res left postfix_len;
-+ let coll ofs = function
-+ | Some (substr, ix, len) ->
-+ let new_ofs = ofs - len in
-+ bytes_unsafe_blit_string substr ix res new_ofs len;
-+ new_ofs
-+ | None ->
-+ let new_ofs = ofs - templ_len in
-+ bytes_unsafe_blit_string templ 0 res new_ofs templ_len;
-+ new_ofs
-+ in
-+ let _ = List.fold_left coll left subst_lst in
-+ Bytes.unsafe_to_string res)
-+ else
-+ let first = Array.unsafe_get ovector 0 in
-+ let len = first - cur_pos in
-+ let subst_lst =
-+ if len > 0 then None :: Some (subj, cur_pos, len) :: subst_lst
-+ else None :: subst_lst
-+ in
-+ let last = Array.unsafe_get ovector 1 in
-+ let full_len = full_len + len + templ_len in
-+ let next = first + 1 in
-+ if last < next then
-+ if first < subj_len then
-+ loop (full_len + 1) (Some (subj, cur_pos + len, 1) :: subst_lst) next
-+ else loop full_len subst_lst next
-+ else loop full_len subst_lst last
-+ in
-+ loop 0 [] pos
-+
-+let substitute_substrings ?(iflags = 0L) ?flags ?(rex = def_rex) ?pat ?(pos = 0)
-+ ?callout ~subst subj =
-+ let rex = match pat with Some str -> regexp str | _ -> rex in
-+ let iflags = match flags with Some flags -> rflags flags | _ -> iflags in
-+ let subj_len = String.length subj in
-+ if pos < 0 || pos > subj_len then
-+ invalid_arg "Pcre2.substitute: illegal offset";
-+ let _, ovector = make_ovector rex in
-+ let rec loop full_len subst_lst cur_pos =
-+ if
-+ cur_pos > subj_len
-+ ||
-+ try
-+ unsafe_pcre2_match iflags rex ~pos:cur_pos ~subj_start:0 ~subj ovector
-+ callout;
-+ false
-+ with Not_found -> true
-+ then (
-+ let postfix_len = max (subj_len - cur_pos) 0 in
-+ let left = pos + full_len in
-+ let res = Bytes.create (left + postfix_len) in
-+ bytes_unsafe_blit_string subj 0 res 0 pos;
-+ bytes_unsafe_blit_string subj cur_pos res left postfix_len;
-+ let coll ofs (templ, ix, len) =
-+ let new_ofs = ofs - len in
-+ bytes_unsafe_blit_string templ ix res new_ofs len;
-+ new_ofs
-+ in
-+ let _ = List.fold_left coll left subst_lst in
-+ Bytes.unsafe_to_string res)
-+ else
-+ let first = Array.unsafe_get ovector 0 in
-+ let len = first - cur_pos in
-+ let templ = subst (subj, ovector) in
-+ let templ_len = String.length templ in
-+ let subst_lst =
-+ if len > 0 then
-+ (templ, 0, templ_len) :: (subj, cur_pos, len) :: subst_lst
-+ else (templ, 0, templ_len) :: subst_lst
-+ in
-+ let last = Array.unsafe_get ovector 1 in
-+ let full_len = full_len + len + templ_len in
-+ let next = first + 1 in
-+ if last < next then
-+ if first < subj_len then
-+ loop (full_len + 1) ((subj, cur_pos + len, 1) :: subst_lst) next
-+ else loop full_len subst_lst next
-+ else loop full_len subst_lst last
-+ in
-+ loop 0 [] pos
-+
-+let substitute ?iflags ?flags ?rex ?pat ?pos ?callout ~subst:str_subst subj =
-+ let subst (subj, ovector) =
-+ let first = Array.unsafe_get ovector 0 in
-+ let last = Array.unsafe_get ovector 1 in
-+ str_subst (string_unsafe_sub subj first (last - first))
-+ in
-+ substitute_substrings ?iflags ?flags ?rex ?pat ?pos ?callout ~subst subj
-+
-+let replace_first ?(iflags = 0L) ?flags ?(rex = def_rex) ?pat ?(pos = 0)
-+ ?(itempl = def_subst) ?templ ?callout subj =
-+ let rex = match pat with Some str -> regexp str | _ -> rex in
-+ let iflags = match flags with Some flags -> rflags flags | _ -> iflags in
-+ let templ, max_br, with_lp, subst_lst =
-+ match templ with Some str -> subst str | _ -> itempl
-+ in
-+ let subgroups2, ovector = make_ovector rex in
-+ let nsubs = (subgroups2 lsr 1) - 1 in
-+ if max_br > nsubs then
-+ failwith "Pcre2.replace_first: backreference denotes nonexistent subpattern";
-+ if with_lp && nsubs = 0 then failwith "Pcre2.replace_first: no backreferences";
-+ try
-+ unsafe_pcre2_match iflags rex ~pos ~subj_start:0 ~subj ovector callout;
-+ let res_len, trans_lst =
-+ calc_trans_lst subgroups2 ovector subj templ subst_lst
-+ in
-+ let first = Array.unsafe_get ovector 0 in
-+ let last = Array.unsafe_get ovector 1 in
-+ let rest = String.length subj - last in
-+ let res = Bytes.create (first + res_len + rest) in
-+ bytes_unsafe_blit_string subj 0 res 0 first;
-+ let coll ofs (templ, ix, len) =
-+ bytes_unsafe_blit_string templ ix res ofs len;
-+ ofs + len
-+ in
-+ let ofs = List.fold_left coll first trans_lst in
-+ bytes_unsafe_blit_string subj last res ofs rest;
-+ Bytes.unsafe_to_string res
-+ with Not_found -> subj
-+
-+let qreplace_first ?(iflags = 0L) ?flags ?(rex = def_rex) ?pat ?(pos = 0)
-+ ?(templ = "") ?callout subj =
-+ let rex = match pat with Some str -> regexp str | _ -> rex in
-+ let iflags = match flags with Some flags -> rflags flags | _ -> iflags in
-+ let _, ovector = make_ovector rex in
-+ try
-+ unsafe_pcre2_match iflags rex ~pos ~subj_start:0 ~subj ovector callout;
-+ let first = Array.unsafe_get ovector 0 in
-+ let last = Array.unsafe_get ovector 1 in
-+ let len = String.length templ in
-+ let rest = String.length subj - last in
-+ let postfix_start = first + len in
-+ let res = Bytes.create (postfix_start + rest) in
-+ bytes_unsafe_blit_string subj 0 res 0 first;
-+ bytes_unsafe_blit_string templ 0 res first len;
-+ bytes_unsafe_blit_string subj last res postfix_start rest;
-+ Bytes.unsafe_to_string res
-+ with Not_found -> subj
-+
-+let substitute_substrings_first ?(iflags = 0L) ?flags ?(rex = def_rex) ?pat
-+ ?(pos = 0) ?callout ~subst subj =
-+ let rex = match pat with Some str -> regexp str | _ -> rex in
-+ let iflags = match flags with Some flags -> rflags flags | _ -> iflags in
-+ let _, ovector = make_ovector rex in
-+ try
-+ unsafe_pcre2_match iflags rex ~pos ~subj_start:0 ~subj ovector callout;
-+ let subj_len = String.length subj in
-+ let prefix_len = Array.unsafe_get ovector 0 in
-+ let last = Array.unsafe_get ovector 1 in
-+ let templ = subst (subj, ovector) in
-+ let postfix_len = subj_len - last in
-+ let templ_len = String.length templ in
-+ let postfix_start = prefix_len + templ_len in
-+ let res = Bytes.create (postfix_start + postfix_len) in
-+ bytes_unsafe_blit_string subj 0 res 0 prefix_len;
-+ bytes_unsafe_blit_string templ 0 res prefix_len templ_len;
-+ bytes_unsafe_blit_string subj last res postfix_start postfix_len;
-+ Bytes.unsafe_to_string res
-+ with Not_found -> subj
-+
-+let substitute_first ?iflags ?flags ?rex ?pat ?pos ?callout ~subst:str_subst
-+ subj =
-+ let subst (subj, ovector) =
-+ let first = Array.unsafe_get ovector 0 in
-+ let last = Array.unsafe_get ovector 1 in
-+ str_subst (string_unsafe_sub subj first (last - first))
-+ in
-+ substitute_substrings_first ?iflags ?flags ?rex ?pat ?pos ?callout ~subst subj
-+
-+(* Splitting *)
-+
-+let internal_psplit flags rex max pos callout subj =
-+ let subj_len = String.length subj in
-+ if subj_len = 0 then []
-+ else if max = 1 then [ subj ]
-+ else
-+ let subgroups2, ovector = make_ovector rex in
-+
-+ (* Adds contents of subgroups to the string accumulator *)
-+ let handle_subgroups strs =
-+ let strs = ref strs in
-+ let i = ref 2 in
-+ while !i < subgroups2 do
-+ let first = Array.unsafe_get ovector !i in
-+ incr i;
-+ let last = Array.unsafe_get ovector !i in
-+ let str =
-+ if first < 0 then "" else string_unsafe_sub subj first (last - first)
-+ in
-+ strs := str :: !strs;
-+ incr i
-+ done;
-+ !strs
-+ in
-+
-+ (* Performs the recursive split *)
-+ let rec loop strs cnt pos prematch =
-+ let len = subj_len - pos in
-+ if len < 0 then strs
-+ else if
-+ (* Checks termination due to max restriction *)
-+ cnt = 0
-+ then
-+ if
-+ prematch
-+ &&
-+ try
-+ unsafe_pcre2_match flags rex ~pos ~subj_start:pos ~subj ovector
-+ callout;
-+ true
-+ with Not_found -> false
-+ then
-+ let last = Array.unsafe_get ovector 1 in
-+ let strs = handle_subgroups strs in
-+ string_unsafe_sub subj last (subj_len - last) :: strs
-+ else string_unsafe_sub subj pos len :: strs
-+ (* Calculates next accumulator state for splitting *)
-+ else if
-+ try
-+ unsafe_pcre2_match flags rex ~pos ~subj_start:pos ~subj ovector
-+ callout;
-+ false
-+ with Not_found -> true
-+ then string_unsafe_sub subj pos len :: strs
-+ else
-+ let first = Array.unsafe_get ovector 0 in
-+ let last = Array.unsafe_get ovector 1 in
-+ if first = pos then
-+ if last = pos then
-+ let strs = if prematch then handle_subgroups strs else strs in
-+ if len = 0 then "" :: strs
-+ else if
-+ try
-+ unsafe_pcre2_match
-+ (* `ANCHORED | `NOTEMPTY *)
-+ (Int64.logor flags 0x80000004L)
-+ rex ~pos ~subj_start:pos ~subj ovector callout;
-+ true
-+ with Not_found -> false
-+ then
-+ let new_strs = handle_subgroups ("" :: strs) in
-+ loop new_strs (cnt - 1) (Array.unsafe_get ovector 1) false
-+ else
-+ let new_strs = string_unsafe_sub subj pos 1 :: strs in
-+ loop new_strs (cnt - 1) (pos + 1) true
-+ else if prematch then loop (handle_subgroups strs) cnt last false
-+ else loop (handle_subgroups ("" :: strs)) (cnt - 1) last false
-+ else
-+ let new_strs = string_unsafe_sub subj pos (first - pos) :: strs in
-+ loop (handle_subgroups new_strs) (cnt - 1) last false
-+ in
-+ loop [] (max - 1) pos false
-+
-+let rec strip_all_empty = function "" :: t -> strip_all_empty t | l -> l
-+
-+external isspace : char -> bool = "pcre2_isspace_stub" [@@noalloc]
-+
-+let rec find_no_space ix len str =
-+ if ix = len || not (isspace (String.unsafe_get str ix)) then ix
-+ else find_no_space (ix + 1) len str
-+
-+let split ?(iflags = 0L) ?flags ?rex ?pat ?(pos = 0) ?(max = 0) ?callout subj =
-+ let iflags = match flags with Some flags -> rflags flags | _ -> iflags in
-+ let res =
-+ match (pat, rex) with
-+ | Some str, _ -> internal_psplit iflags (regexp str) max pos callout subj
-+ | _, Some rex -> internal_psplit iflags rex max pos callout subj
-+ | _ ->
-+ (* special case for Perl-splitting semantics *)
-+ let len = String.length subj in
-+ if pos > len || pos < 0 then failwith "Pcre2.split: illegal offset";
-+ let new_pos = find_no_space pos len subj in
-+ internal_psplit iflags def_rex max new_pos callout subj
-+ in
-+ List.rev (if max = 0 then strip_all_empty res else res)
-+
-+let asplit ?iflags ?flags ?rex ?pat ?pos ?max ?callout subj =
-+ Array.of_list (split ?iflags ?flags ?rex ?pat ?pos ?max ?callout subj)
-+
-+(* Full splitting *)
-+
-+type split_result =
-+ | Text of string
-+ | Delim of string
-+ | Group of int * string
-+ | NoGroup
-+
-+let rec strip_all_empty_full = function
-+ | Delim _ :: rest -> strip_all_empty_full rest
-+ | l -> l
-+
-+let full_split ?(iflags = 0L) ?flags ?(rex = def_rex) ?pat ?(pos = 0) ?(max = 0)
-+ ?callout subj =
-+ let rex = match pat with Some str -> regexp str | _ -> rex in
-+ let iflags = match flags with Some flags -> rflags flags | _ -> iflags in
-+ let subj_len = String.length subj in
-+ if subj_len = 0 then []
-+ else if max = 1 then [ Text subj ]
-+ else
-+ let subgroups2, ovector = make_ovector rex in
-+
-+ (* Adds contents of subgroups to the string accumulator *)
-+ let handle_subgroups strs =
-+ let strs = ref strs in
-+ let i = ref 2 in
-+ while !i < subgroups2 do
-+ let group_nr = !i lsr 1 in
-+ let first = Array.unsafe_get ovector !i in
-+ incr i;
-+ let last = Array.unsafe_get ovector !i in
-+ let str =
-+ if first < 0 then NoGroup
-+ else
-+ let group_str = string_unsafe_sub subj first (last - first) in
-+ Group (group_nr, group_str)
-+ in
-+ strs := str :: !strs;
-+ incr i
-+ done;
-+ !strs
-+ in
-+
-+ (* Performs the recursive split *)
-+ let rec loop strs cnt pos prematch =
-+ let len = subj_len - pos in
-+ if len < 0 then strs
-+ else if
-+ (* Checks termination due to max restriction *)
-+ cnt = 0
-+ then
-+ if
-+ prematch
-+ &&
-+ try
-+ unsafe_pcre2_match iflags rex ~pos ~subj_start:pos ~subj ovector
-+ callout;
-+ true
-+ with Not_found -> false
-+ then
-+ let first = Array.unsafe_get ovector 0 in
-+ let last = Array.unsafe_get ovector 1 in
-+ let delim = Delim (string_unsafe_sub subj first (last - first)) in
-+ Text (string_unsafe_sub subj last (subj_len - last))
-+ :: handle_subgroups (delim :: strs)
-+ else if len = 0 then strs
-+ else Text (string_unsafe_sub subj pos len) :: strs
-+ (* Calculates next accumulator state for splitting *)
-+ else if
-+ try
-+ unsafe_pcre2_match iflags rex ~pos ~subj_start:pos ~subj ovector
-+ callout;
-+ false
-+ with Not_found -> true
-+ then
-+ if len = 0 then strs else Text (string_unsafe_sub subj pos len) :: strs
-+ else
-+ let first = Array.unsafe_get ovector 0 in
-+ let last = Array.unsafe_get ovector 1 in
-+ if first = pos then
-+ if last = pos then
-+ if len = 0 then handle_subgroups (Delim "" :: strs)
-+ else
-+ let empty_groups = handle_subgroups [] in
-+ if
-+ try
-+ unsafe_pcre2_match
-+ (* `ANCHORED | `NOTEMPTY *)
-+ (Int64.logor iflags 0x80000004L)
-+ rex ~pos ~subj_start:pos ~subj ovector callout;
-+ true
-+ with Not_found -> false
-+ then
-+ let first = Array.unsafe_get ovector 0 in
-+ let last = Array.unsafe_get ovector 1 in
-+ let delim =
-+ Delim (string_unsafe_sub subj first (last - first))
-+ in
-+ let new_strs =
-+ let tmp_strs =
-+ if prematch then strs else empty_groups @ (Delim "" :: strs)
-+ in
-+ handle_subgroups (delim :: tmp_strs)
-+ in
-+ loop new_strs (cnt - 1) last false
-+ else
-+ let new_strs =
-+ (Text (string_unsafe_sub subj pos 1) :: empty_groups)
-+ @ (Delim "" :: strs)
-+ in
-+ loop new_strs (cnt - 1) (pos + 1) true
-+ else
-+ let delim = Delim (string_unsafe_sub subj first (last - first)) in
-+ loop (handle_subgroups (delim :: strs)) cnt last false
-+ else
-+ let delim = Delim (string_unsafe_sub subj first (last - first)) in
-+ let pre_strs =
-+ Text (string_unsafe_sub subj pos (first - pos)) :: strs
-+ in
-+ loop (handle_subgroups (delim :: pre_strs)) (cnt - 1) last false
-+ in
-+ let res = loop [] (max - 1) pos true in
-+ List.rev (if max = 0 then strip_all_empty_full res else res)
-+
-+(* Additional convenience functions useful in combination with this library *)
-+
-+let foreach_line ?(ic = stdin) f =
-+ try
-+ while true do
-+ f (input_line ic)
-+ done
-+ with End_of_file -> ()
-+
-+let foreach_file filenames f =
-+ let do_with_file filename =
-+ let file = open_in filename in
-+ try
-+ f filename file;
-+ close_in file
-+ with exn ->
-+ close_in file;
-+ raise exn
-+ in
-+ List.iter do_with_file filenames
-diff --git a/bundles/pcre2/pcre2-ocaml/lib/pcre2.mli b/bundles/pcre2/pcre2-ocaml/lib/pcre2.mli
-new file mode 100644
-index 000000000..a61bcd857
---- /dev/null
-+++ b/bundles/pcre2/pcre2-ocaml/lib/pcre2.mli
-@@ -0,0 +1,1068 @@
-+(* PCRE2-OCAML - Perl Compatibility Regular Expressions for OCaml
-+
-+ Copyright © 1999- Markus Mottl <markus.mottl@gmail.com>
-+
-+ This library is free software; you can redistribute it and/or modify it under
-+ the terms of the GNU Lesser General Public License as published by the Free
-+ Software Foundation; either version 2.1 of the License, or (at your option)
-+ any later version.
-+
-+ This library is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-+ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-+ details.
-+
-+ You should have received a copy of the GNU Lesser General Public License
-+ along with this library; if not, write to the Free Software Foundation, Inc.,
-+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *)
-+
-+(** Perl Compatibility Regular Expressions for OCaml
-+
-+ {e %%VERSION%% - {{:%%PKG_HOMEPAGE%%} homepage}} *)
-+
-+(** {1 Exceptions} *)
-+
-+type error =
-+ | Partial (** String only matched the pattern partially *)
-+ | BadPattern of string * int
-+ (** [BadPattern (msg, pos)] regular expression is malformed. The reason is
-+ in [msg], the position of the error in the pattern in [pos]. *)
-+ | BadUTF (** UTF string being matched is invalid *)
-+ | BadUTFOffset
-+ (** Gets raised when a UTF string being matched with offset is invalid. *)
-+ | MatchLimit
-+ (** Maximum allowed number of match attempts with backtracking or
-+ recursion is reached during matching. ALL FUNCTIONS CALLING THE
-+ MATCHING ENGINE MAY RAISE IT!!! *)
-+ | DepthLimit
-+ | WorkspaceSize
-+ (** Raised by {!pcre2_dfa_match} when the provided workspace array is too
-+ small. See documention on {!pcre2_dfa_match} for details on workspace
-+ array sizing. *)
-+ | InternalError of string
-+ (** [InternalError msg] C-library exhibits unknown/undefined behaviour.
-+ The reason is in [msg]. *)
-+
-+exception Error of error
-+(** Exception indicating PCRE errors. *)
-+
-+exception Backtrack
-+(** [Backtrack] used in callout functions to force backtracking. *)
-+
-+exception Regexp_or of string * error
-+(** [Regexp_or (pat, error)] gets raised for sub-pattern [pat] by [regexp_or] if
-+ it failed to compile. *)
-+
-+(** {1 Compilation and runtime flags and their conversion functions} *)
-+
-+type icflag
-+(** Internal representation of compilation flags *)
-+
-+and irflag
-+(** Internal representation of runtime flags *)
-+
-+and cflag =
-+ [ `ALLOW_EMPTY_CLASS (** Allow empty classes *)
-+ | `ALT_BSUX (** Alternative handling of \u, \U, and \x *)
-+ | `ALT_CIRCUMFLEX (** Alternative handling of ^ in multiline mode *)
-+ | `ALT_VERBNAMES (** Process backslashes in verb names *)
-+ | `ANCHORED (** Pattern matches only at start of string *)
-+ | `AUTO_CALLOUT
-+ (** Automatically inserts callouts with id 255 before each pattern item *)
-+ | `CASELESS (** Case insensitive matching *)
-+ | `DOLLAR_ENDONLY (** '$' in pattern matches only at end of string *)
-+ | `DOTALL (** '.' matches all characters (newlines, too) *)
-+ | `DUPNAMES (** Allow duplicate names for subpatterns *)
-+ | `ENDANCHORED (** Pattern can match only at end of subject *)
-+ | `EXTENDED
-+ (** Ignores whitespace and PERL-comments. Behaves like the '/x'-option in
-+ PERL *)
-+ | `EXTENDED_MORE
-+ | `FIRSTLINE (** Unanchored patterns must match before/at first NL *)
-+ | `LITERAL (** Pattern characters are all literal *)
-+ | `MATCH_INVALID_UTF (** Enable support for matching invalid UTF *)
-+ | `MATCH_UNSET_BACKREF (** Match unset backreferences *)
-+ | `MULTILINE
-+ (** '^' and '$' match before/after newlines, not just at the beginning/end
-+ of a string *)
-+ | `NEVER_BACKSLASH_C (** Lock out the use of \C in patterns *)
-+ | `NEVER_UCP (** Lock out UCP, e.g. via (\*UCP) *)
-+ | `NEVER_UTF (** Lock out UTF, e.g. via (\*UTF) *)
-+ | `NO_AUTO_CAPTURE (** Disables the use of numbered capturing parentheses *)
-+ | `NO_AUTO_POSSESS (** Disable auto-possessification *)
-+ | `NO_DOTSTAR_ANCHOR (** Disable automatic anchoring for .* *)
-+ | `NO_START_OPTIMIZE (** Disable match-time start optimizations *)
-+ | `NO_UTF_CHECK
-+ (** Do not check the pattern for UTF validity (only relevant if UTF is set)
-+ WARNING: with this flag enabled, invalid UTF strings may cause a crash,
-+ loop, or give incorrect results *)
-+ | `UCP (** Use Unicode properties for \d, \w, etc. *)
-+ | `UNGREEDY (** Quantifiers not greedy anymore, only if followed by '?' *)
-+ | `USE_OFFSET_LIMIT (** Enable offset limit for unanchored matching *)
-+ | `UTF (** Treat pattern and subjects as UTF strings *) ]
-+(** Compilation flags *)
-+
-+val cflags : cflag list -> icflag
-+(** [cflags cflag_list] converts a list of compilation flags to their internal
-+ representation. *)
-+
-+val cflag_list : icflag -> cflag list
-+(** [cflag_list cflags] converts internal representation of compilation flags to
-+ a list. *)
-+
-+type rflag =
-+ [ `ANCHORED (** Match only at the first position *)
-+ | `COPY_MATCHED_SUBJECT (** On success, make a private subject copy *)
-+ | `DFA_RESTART
-+ (** Causes matching to proceed presuming the subject string is further to
-+ one partially matched previously using the same int-array working set.
-+ May only be used with {!pcre2_dfa_match} or {!unsafe_pcre2_dfa_match},
-+ and should always be paired with [`PARTIAL]. *)
-+ | `DFA_SHORTEST (** Return only the shortest match *)
-+ | `ENDANCHORED (** Pattern can match only at end of subject *)
-+ | `NOTBOL (** Beginning of string is not treated as beginning of line *)
-+ | `NOTEOL (** End of string is not treated as end of line *)
-+ | `NOTEMPTY (** An empty string is not a valid match *)
-+ | `NOTEMPTY_ATSTART
-+ (** An empty string at the start of the subject is not a valid match *)
-+ | `NO_JIT (** Do not use JIT matching *)
-+ | `NO_UTF_CHECK
-+ (** Do not check the subject for UTF validity (only relevant if PCRE2_UTF
-+ was set at compile time) *)
-+ | `PARTIAL_HARD
-+ (** Throw Pcre2.Partial for a partial match even if there is a full match *)
-+ | `PARTIAL_SOFT
-+ (** Throw Pcre2.Partial for a partial match if no full matches are found *)
-+ ]
-+(** Runtime flags *)
-+
-+val rflags : rflag list -> irflag
-+(** [rflags rflag_list] converts a list of runtime flags to their internal
-+ representation. *)
-+
-+val rflag_list : irflag -> rflag list
-+(** [rflag_list rflags] converts internal representation of runtime flags to a
-+ list. *)
-+
-+(** {1 Information on the PCRE2-configuration (build-time options)} *)
-+
-+(** Version information *)
-+val version : string
-+(** Version of the PCRE2-C-library *)
-+
-+val config_unicode : bool
-+(** Indicates whether unicode support is enabled *)
-+
-+val config_newline : char
-+(** Character used as newline *)
-+
-+val config_link_size : int
-+(** Number of bytes used for internal linkage of regular expressions *)
-+
-+val config_match_limit : int
-+(** Default limit for calls to internal matching function *)
-+
-+val config_depth_limit : int
-+(** Default limit for depth of nested backtracking *)
-+
-+val config_stackrecurse : bool
-+(** Indicates use of stack recursion in matching function *)
-+
-+(** {1 Information on patterns} *)
-+
-+type firstcodeunit_info =
-+ [ `Char of char (** Fixed first character *)
-+ | `Start_only (** Pattern matches at beginning and end of newlines *)
-+ | `ANCHORED (** Pattern is anchored *) ]
-+(** Information on matching of "first chars" in patterns *)
-+
-+type regexp
-+(** Compiled regular expressions *)
-+
-+val options : regexp -> icflag
-+(** [options regexp]
-+
-+ @return compilation flags of [regexp]. *)
-+
-+val size : regexp -> int
-+(** [size regexp]
-+
-+ @return memory size of [regexp]. *)
-+
-+val capturecount : regexp -> int
-+(** [capturecount regexp]
-+
-+ @return number of capturing subpatterns in [regexp]. *)
-+
-+val backrefmax : regexp -> int
-+(** [backrefmax regexp]
-+
-+ @return number of highest backreference in [regexp]. *)
-+
-+val namecount : regexp -> int
-+(** [namecount regexp]
-+
-+ @return number of named subpatterns in [regexp]. *)
-+
-+val nameentrysize : regexp -> int
-+(** [nameentrysize regexp]
-+
-+ @return size of longest name of named subpatterns in [regexp] + 3. *)
-+
-+val names : regexp -> string array
-+(** [names regex]
-+
-+ @return array of names of named substrings in [regexp]. *)
-+
-+val firstcodeunit : regexp -> firstcodeunit_info
-+(** [firstcodeunit regexp]
-+
-+ @return firstcodeunit info on [regexp]. *)
-+
-+val lastcodeunit : regexp -> char option
-+(** [lastcodeunit regexp]
-+
-+ @return
-+ some last matching character of [regexp] if available, [None] otherwise.
-+*)
-+
-+val get_stringnumber : regexp -> string -> int
-+(** [get_stringnumber rex name]
-+
-+ @return
-+ the index of the named substring [name] in regular expression [rex]. This
-+ index can then be used with [get_substring].
-+
-+ @raise Invalid_arg if there is no such named substring. *)
-+
-+(* val get_match_limit : regexp -> int option *)
-+(** [get_match_limit rex]
-+
-+ @return some match limit of regular expression [rex] or [None]. *)
-+
-+(* val get_depth_limit : regexp -> int option *)
-+(** [get_depth_limit rex]
-+
-+ @return some depth limit of regular expression [rex] or [None]. *)
-+
-+(** {1 Compilation of patterns} *)
-+
-+type chtables
-+(** Alternative set of char tables for pattern matching *)
-+
-+val maketables : unit -> chtables
-+(** Generates new set of char tables for the current locale. *)
-+
-+val regexp :
-+ ?limit:
-+ (* ?jit_compile : bool -> *)
-+ int ->
-+ ?depth_limit:int ->
-+ ?iflags:icflag ->
-+ ?flags:cflag list ->
-+ ?chtables:chtables ->
-+ string ->
-+ regexp
-+(** [regexp ?limit ?depth_limit ?iflags ?flags ?chtables pattern] compiles
-+ [pattern] with [flags] when given, with [iflags] otherwise, and with char
-+ tables [chtables]. If [limit] is specified, this sets a limit to the amount
-+ of recursion and backtracking (only lower than the builtin default!). If
-+ this limit is exceeded, [MatchLimit] will be raised during matching.
-+
-+ @param limit default = no extra limit other than default
-+ @param depth_limit default = no extra depth_limit other than default
-+ @param iflags default = no extra flags
-+ @param flags default = ignored
-+ @param chtables default = builtin char tables
-+
-+ @return the regular expression.
-+
-+ For detailed documentation on how you can specify PERL-style regular
-+ expressions (= patterns), please consult the PCRE2-documentation ("man
-+ pcre2pattern") or PERL-manuals.
-+ @see <http://www.perl.com> www.perl.com *)
-+
-+val regexp_or :
-+ ?limit:
-+ (* ?jit_compile : bool -> *)
-+ int ->
-+ ?depth_limit:int ->
-+ ?iflags:icflag ->
-+ ?flags:cflag list ->
-+ ?chtables:chtables ->
-+ string list ->
-+ regexp
-+(** [regexp_or ?limit ?depth_limit ?iflags ?flags ?chtables patterns] like
-+ {!val-regexp}, but combines [patterns] as alternatives (or-patterns) into
-+ one regular expression. *)
-+
-+val quote : string -> string
-+(** [quote str]
-+
-+ @return the quoted string of [str]. *)
-+
-+(** {1 Subpattern extraction} *)
-+
-+type substrings
-+(** Information on substrings after pattern matching *)
-+
-+val get_subject : substrings -> string
-+(** [get_subject substrings]
-+
-+ @return the subject string of [substrings]. *)
-+
-+val num_of_subs : substrings -> int
-+(** [num_of_subs substrings]
-+
-+ @return number of strings in [substrings] (whole match inclusive). *)
-+
-+val get_substring : substrings -> int -> string
-+(** [get_substring substrings n]
-+
-+ @return the [n]th substring (0 is whole match) of [substrings].
-+
-+ @raise Invalid_argument
-+ if [n] is not in the range of the number of substrings.
-+ @raise Not_found
-+ if the corresponding subpattern did not capture a substring. *)
-+
-+val get_substring_ofs : substrings -> int -> int * int
-+(** [get_substring_ofs substrings n]
-+
-+ @return
-+ the offset tuple of the [n]th substring of [substrings] (0 is whole
-+ match).
-+
-+ @raise Invalid_argument
-+ if [n] is not in the range of the number of substrings.
-+ @raise Not_found
-+ if the corresponding subpattern did not capture a substring. *)
-+
-+val get_substrings : ?full_match:bool -> substrings -> string array
-+(** [get_substrings ?full_match substrings]
-+
-+ @return
-+ the array of substrings in [substrings]. It includes the full match at
-+ index 0 when [full_match] is [true], the captured substrings only when it
-+ is [false]. If a subpattern did not capture a substring, the empty string
-+ is returned in the corresponding position instead.
-+
-+ @param full_match default = true *)
-+
-+val get_opt_substrings : ?full_match:bool -> substrings -> string option array
-+(** [get_opt_substrings ?full_match substrings]
-+
-+ @return
-+ the array of optional substrings in [substrings]. It includes
-+ [Some full_match_str] at index 0 when [full_match] is [true],
-+ [Some captured_substrings] only when it is [false]. If a subpattern did
-+ not capture a substring, [None] is returned in the corresponding position
-+ instead.
-+
-+ @param full_match default = true *)
-+
-+val get_named_substring : regexp -> string -> substrings -> string
-+(** [get_named_substring rex name substrings]
-+
-+ @return
-+ the named substring [name] in regular expression [rex] and [substrings].
-+
-+ @raise Invalid_argument if there is no such named substring.
-+ @raise Not_found
-+ if the corresponding subpattern did not capture a substring. *)
-+
-+val get_named_substring_ofs : regexp -> string -> substrings -> int * int
-+(** [get_named_substring_ofs rex name substrings]
-+
-+ @return
-+ the offset tuple of the named substring [name] in regular expression [rex]
-+ and [substrings].
-+
-+ @raise Invalid_argument if there is no such named substring.
-+ @raise Not_found
-+ if the corresponding subpattern did not capture a substring. *)
-+
-+(** {1 Callouts} *)
-+
-+type callout_data = {
-+ callout_number : int; (** Callout number *)
-+ substrings : substrings; (** Substrings matched so far *)
-+ start_match : int; (** Subject start offset of current match attempt *)
-+ current_position : int; (** Subject offset of current match pointer *)
-+ capture_top : int; (** Number of the highest captured substring so far *)
-+ capture_last : int; (** Number of the most recently captured substring *)
-+ pattern_position : int; (** Offset of next match item in pattern string *)
-+ next_item_length : int; (** Length of next match item in pattern string *)
-+}
-+
-+(** Type of callout functions *)
-+type callout = callout_data -> unit
-+(** Callouts are referred to in patterns as "(?Cn)" where "n" is a
-+ [callout_number] ranging from 0 to 255. Substrings captured so far are
-+ accessible as usual via [substrings]. You will have to consider
-+ [capture_top] and [capture_last] to know about the current state of valid
-+ substrings.
-+
-+ By raising exception [Backtrack] within a callout function, the user can
-+ force the pattern matching engine to backtrack to other possible solutions.
-+ Other exceptions will terminate matching immediately and return control to
-+ OCaml. *)
-+
-+(** {1 Matching of patterns and subpattern extraction} *)
-+
-+val pcre2_match :
-+ ?iflags:irflag ->
-+ ?flags:rflag list ->
-+ ?rex:regexp ->
-+ ?pat:string ->
-+ ?pos:int ->
-+ ?callout:callout ->
-+ string ->
-+ int array
-+(** [pcre2_match ?iflags ?flags ?rex ?pat ?pos ?callout subj]
-+
-+ @return
-+ an array of offsets that describe the position of matched subpatterns in
-+ the string [subj] starting at position [pos] with pattern [pat] when
-+ given, regular expression [rex] otherwise. The array also contains
-+ additional workspace needed by the match engine. Uses [flags] when given,
-+ the precompiled [iflags] otherwise. Callouts are handled by [callout].
-+
-+ @param iflags default = no extra flags
-+ @param flags default = ignored
-+ @param rex default = matches whitespace
-+ @param pat default = ignored
-+ @param pos default = 0
-+ @param callout default = ignore callouts
-+
-+ @raise Not_found if pattern does not match. *)
-+
-+val pcre2_dfa_match :
-+ ?iflags:irflag ->
-+ ?flags:rflag list ->
-+ ?rex:regexp ->
-+ ?pat:string ->
-+ ?pos:int ->
-+ ?callout:callout ->
-+ ?workspace:int array ->
-+ string ->
-+ int array
-+(** [pcre2_dfa_match ?iflags ?flags ?rex ?pat ?pos ?callout ?workspace subj]
-+ invokes the "alternative" DFA matching function.
-+
-+ @return
-+ an array of offsets that describe the position of matched subpatterns in
-+ the string [subj] starting at position [pos] with pattern [pat] when
-+ given, regular expression [rex] otherwise. The array also contains
-+ additional workspace needed by the match engine. Uses [flags] when given,
-+ the precompiled [iflags] otherwise. Requires a sufficiently-large
-+ [workspace] array. Callouts are handled by [callout].
-+
-+ Note that the returned array of offsets are quite different from those
-+ returned by {!pcre2_match} et al. The motivating use case for the DFA match
-+ function is to be able to restart a partial match with N additional input
-+ segments. Because the match function/workspace does not store segments seen
-+ previously, the offsets returned when a match completes will refer only to
-+ the matching portion of the last subject string provided. Thus, returned
-+ offsets from this function should not be used to support extracting captured
-+ submatches. If you need to capture submatches from a series of inputs
-+ incrementally matched with this function, you'll need to concatenate those
-+ inputs that yield a successful match here and re-run the same pattern
-+ against that single subject string.
-+
-+ Aside from an absolute minimum of [20], PCRE does not provide any guidance
-+ regarding the size of workspace array needed by any given pattern.
-+ Therefore, it is wise to appropriately handle the possible [WorkspaceSize]
-+ error. If raised, you can allocate a new, larger workspace array and begin
-+ the DFA matching process again.
-+
-+ @param iflags default = no extra flags
-+ @param flags default = ignored
-+ @param rex default = matches whitespace
-+ @param pat default = ignored
-+ @param pos default = 0
-+ @param callout default = ignore callouts
-+ @param workspace default = fresh array of length [20]
-+
-+ @raise Not_found if the pattern match has failed
-+ @raise Error
-+ Partial if the pattern has matched partially; a subsequent exec call with
-+ the same pattern and workspace (adding the [DFA_RESTART] flag) be made to
-+ either further advance or complete the partial match.
-+ @raise Error
-+ WorkspaceSize if the workspace array is too small to accommodate the DFA
-+ state required by the supplied pattern *)
-+
-+val exec :
-+ ?iflags:irflag ->
-+ ?flags:rflag list ->
-+ ?rex:regexp ->
-+ ?pat:string ->
-+ ?pos:int ->
-+ ?callout:callout ->
-+ string ->
-+ substrings
-+(** [exec ?iflags ?flags ?rex ?pat ?pos ?callout subj]
-+
-+ @return
-+ substring information on string [subj] starting at position [pos] with
-+ pattern [pat] when given, regular expression [rex] otherwise. Uses [flags]
-+ when given, the precompiled [iflags] otherwise. Callouts are handled by
-+ [callout].
-+
-+ @param iflags default = no extra flags
-+ @param flags default = ignored
-+ @param rex default = matches whitespace
-+ @param pat default = ignored
-+ @param pos default = 0
-+ @param callout default = ignore callouts
-+
-+ @raise Not_found if pattern does not match. *)
-+
-+val exec_all :
-+ ?iflags:irflag ->
-+ ?flags:rflag list ->
-+ ?rex:regexp ->
-+ ?pat:string ->
-+ ?pos:int ->
-+ ?callout:callout ->
-+ string ->
-+ substrings array
-+(** [exec_all ?iflags ?flags ?rex ?pat ?pos ?callout subj]
-+
-+ @return
-+ an array of substring information of all matching substrings in string
-+ [subj] starting at position [pos] with pattern [pat] when given, regular
-+ expression [rex] otherwise. Uses [flags] when given, the precompiled
-+ [iflags] otherwise. Callouts are handled by [callout].
-+
-+ @param iflags default = no extra flags
-+ @param flags default = ignored
-+ @param rex default = matches whitespace
-+ @param pat default = ignored
-+ @param pos default = 0
-+ @param callout default = ignore callouts
-+
-+ @raise Not_found if pattern does not match. *)
-+
-+val next_match :
-+ ?iflags:irflag ->
-+ ?flags:rflag list ->
-+ ?rex:regexp ->
-+ ?pat:string ->
-+ ?pos:int ->
-+ ?callout:callout ->
-+ substrings ->
-+ substrings
-+(** [next_match ?iflags ?flags ?rex ?pat ?pos ?callout substrs]
-+
-+ @return
-+ substring information on the match that follows on the last match denoted
-+ by [substrs], jumping over [pos] characters (also backwards!), using
-+ pattern [pat] when given, regular expression [rex] otherwise. Uses [flags]
-+ when given, the precompiled [iflags] otherwise. Callouts are handled by
-+ [callout].
-+
-+ @param iflags default = no extra flags
-+ @param flags default = ignored
-+ @param rex default = matches whitespace
-+ @param pat default = ignored
-+ @param pos default = 0
-+ @param callout default = ignore callouts
-+
-+ @raise Not_found if pattern does not match.
-+ @raise Invalid_arg
-+ if [pos] let matching start outside of the subject string. *)
-+
-+val extract :
-+ ?iflags:irflag ->
-+ ?flags:rflag list ->
-+ ?rex:regexp ->
-+ ?pat:string ->
-+ ?pos:int ->
-+ ?full_match:bool ->
-+ ?callout:callout ->
-+ string ->
-+ string array
-+(** [extract ?iflags ?flags ?rex ?pat ?pos ?full_match ?callout subj]
-+
-+ @return
-+ the array of substrings that match [subj] starting at position [pos],
-+ using pattern [pat] when given, regular expression [rex] otherwise. Uses
-+ [flags] when given, the precompiled [iflags] otherwise. It includes the
-+ full match at index 0 when [full_match] is [true], the captured substrings
-+ only when it is [false]. Callouts are handled by [callout]. If a
-+ subpattern did not capture a substring, the empty string is returned in
-+ the corresponding position instead.
-+
-+ @param iflags default = no extra flags
-+ @param flags default = ignored
-+ @param rex default = matches whitespace
-+ @param pat default = ignored
-+ @param pos default = 0
-+ @param full_match default = true
-+ @param callout default = ignore callouts
-+
-+ @raise Not_found if pattern does not match. *)
-+
-+val extract_opt :
-+ ?iflags:irflag ->
-+ ?flags:rflag list ->
-+ ?rex:regexp ->
-+ ?pat:string ->
-+ ?pos:int ->
-+ ?full_match:bool ->
-+ ?callout:callout ->
-+ string ->
-+ string option array
-+(** [extract_opt ?iflags ?flags ?rex ?pat ?pos ?full_match ?callout subj]
-+
-+ @return
-+ the array of optional substrings that match [subj] starting at position
-+ [pos], using pattern [pat] when given, regular expression [rex] otherwise.
-+ Uses [flags] when given, the precompiled [iflags] otherwise. It includes
-+ [Some full_match_str] at index 0 when [full_match] is [true],
-+ [Some captured-substrings] only when it is [false]. Callouts are handled
-+ by [callout]. If a subpattern did not capture a substring, [None] is
-+ returned in the corresponding position instead.
-+
-+ @param iflags default = no extra flags
-+ @param flags default = ignored
-+ @param rex default = matches whitespace
-+ @param pat default = ignored
-+ @param pos default = 0
-+ @param full_match default = true
-+ @param callout default = ignore callouts
-+
-+ @raise Not_found if pattern does not match. *)
-+
-+val extract_all :
-+ ?iflags:irflag ->
-+ ?flags:rflag list ->
-+ ?rex:regexp ->
-+ ?pat:string ->
-+ ?pos:int ->
-+ ?full_match:bool ->
-+ ?callout:callout ->
-+ string ->
-+ string array array
-+(** [extract_all ?iflags ?flags ?rex ?pat ?pos ?full_match ?callout subj]
-+
-+ @return
-+ an array of arrays of all matching substrings that match [subj] starting
-+ at position [pos], using pattern [pat] when given, regular expression
-+ [rex] otherwise. Uses [flags] when given, the precompiled [iflags]
-+ otherwise. It includes the full match at index 0 of the extracted string
-+ arrays when [full_match] is [true], the captured substrings only when it
-+ is [false]. Callouts are handled by [callout].
-+
-+ @param iflags default = no extra flags
-+ @param flags default = ignored
-+ @param rex default = matches whitespace
-+ @param pat default = ignored
-+ @param pos default = 0
-+ @param full_match default = true
-+ @param callout default = ignore callouts
-+
-+ @raise Not_found if pattern does not match. *)
-+
-+val extract_all_opt :
-+ ?iflags:irflag ->
-+ ?flags:rflag list ->
-+ ?rex:regexp ->
-+ ?pat:string ->
-+ ?pos:int ->
-+ ?full_match:bool ->
-+ ?callout:callout ->
-+ string ->
-+ string option array array
-+(** [extract_all_opt ?iflags ?flags ?rex ?pat ?pos ?full_match ?callout subj]
-+
-+ @return
-+ an array of arrays of all optional matching substrings that match [subj]
-+ starting at position [pos], using pattern [pat] when given, regular
-+ expression [rex] otherwise. Uses [flags] when given, the precompiled
-+ [iflags] otherwise. It includes [Some full_match_str] at index 0 of the
-+ extracted string arrays when [full_match] is [true],
-+ [Some captured_substrings] only when it is [false]. Callouts are handled
-+ by [callout]. If a subpattern did not capture a substring, [None] is
-+ returned in the corresponding position instead.
-+
-+ @param iflags default = no extra flags
-+ @param flags default = ignored
-+ @param rex default = matches whitespace
-+ @param pat default = ignored
-+ @param pos default = 0
-+ @param full_match default = true
-+ @param callout default = ignore callouts
-+
-+ @raise Not_found if pattern does not match. *)
-+
-+val pmatch :
-+ ?iflags:irflag ->
-+ ?flags:rflag list ->
-+ ?rex:regexp ->
-+ ?pat:string ->
-+ ?pos:int ->
-+ ?callout:callout ->
-+ string ->
-+ bool
-+(** [pmatch ?iflags ?flags ?rex ?pat ?pos ?callout subj]
-+
-+ @return
-+ [true] if [subj] is matched by pattern [pat] when given, regular
-+ expression [rex] otherwise, starting at position [pos]. Uses [flags] when
-+ given, the precompiled [iflags] otherwise. Callouts are handled by
-+ [callout].
-+
-+ @param iflags default = no extra flags
-+ @param flags default = ignored
-+ @param rex default = matches whitespace
-+ @param pat default = ignored
-+ @param pos default = 0
-+ @param callout default = ignore callouts *)
-+
-+(** {1 String substitution} *)
-+
-+type substitution
-+(** Information on substitution patterns *)
-+
-+val subst : string -> substitution
-+(** [subst str] converts the string [str] representing a substitution pattern to
-+ the internal representation
-+
-+ The contents of the substitution string [str] can be normal text mixed with
-+ any of the following (mostly as in PERL):
-+
-+ - {e $\[0-9\]+} - a "$" immediately followed by an arbitrary number. "$0"
-+ stands for the name of the executable, any other number for the n-th
-+ backreference.
-+ - {e $&} - the whole matched pattern
-+ - {e $`} - the text before the match
-+ - {e $'} - the text after the match
-+ - {e $+} - the last group that matched
-+ - {e $$} - a single "$"
-+ - {e $!} - delimiter which does not appear in the substitution. Can be used
-+ to part "$[0-9]+" from an immediately following other number. *)
-+
-+val replace :
-+ ?iflags:irflag ->
-+ ?flags:rflag list ->
-+ ?rex:regexp ->
-+ ?pat:string ->
-+ ?pos:int ->
-+ ?itempl:substitution ->
-+ ?templ:string ->
-+ ?callout:callout ->
-+ string ->
-+ string
-+(** [replace ?iflags ?flags ?rex ?pat ?pos ?itempl ?templ ?callout subj]
-+ replaces all substrings of [subj] matching pattern [pat] when given, regular
-+ expression [rex] otherwise, starting at position [pos] with the substitution
-+ string [templ] when given, [itempl] otherwise. Uses [flags] when given, the
-+ precompiled [iflags] otherwise. Callouts are handled by [callout].
-+
-+ @param iflags default = no extra flags
-+ @param flags default = ignored
-+ @param rex default = matches whitespace
-+ @param pat default = ignored
-+ @param pos default = 0
-+ @param itempl default = empty string
-+ @param templ default = ignored
-+ @param callout default = ignore callouts
-+
-+ @raise Failure if there are backreferences to nonexistent subpatterns. *)
-+
-+val qreplace :
-+ ?iflags:irflag ->
-+ ?flags:rflag list ->
-+ ?rex:regexp ->
-+ ?pat:string ->
-+ ?pos:int ->
-+ ?templ:string ->
-+ ?callout:callout ->
-+ string ->
-+ string
-+(** [qreplace ?iflags ?flags ?rex ?pat ?pos ?templ ?callout subj] replaces all
-+ substrings of [subj] matching pattern [pat] when given, regular expression
-+ [rex] otherwise, starting at position [pos] with the string [templ]. Uses
-+ [flags] when given, the precompiled [iflags] otherwise. Callouts are handled
-+ by [callout].
-+
-+ @param iflags default = no extra flags
-+ @param flags default = ignored
-+ @param rex default = matches whitespace
-+ @param pat default = ignored
-+ @param pos default = 0
-+ @param templ default = ignored
-+ @param callout default = ignore callouts *)
-+
-+val substitute_substrings :
-+ ?iflags:irflag ->
-+ ?flags:rflag list ->
-+ ?rex:regexp ->
-+ ?pat:string ->
-+ ?pos:int ->
-+ ?callout:callout ->
-+ subst:(substrings -> string) ->
-+ string ->
-+ string
-+(** [substitute_substrings ?iflags ?flags ?rex ?pat ?pos ?callout ~subst subj]
-+ replaces all substrings of [subj] matching pattern [pat] when given, regular
-+ expression [rex] otherwise, starting at position [pos] with the result of
-+ function [subst] applied to the substrings of the match. Uses [flags] when
-+ given, the precompiled [iflags] otherwise. Callouts are handled by
-+ [callout].
-+
-+ @param iflags default = no extra flags
-+ @param flags default = ignored
-+ @param rex default = matches whitespace
-+ @param pat default = ignored
-+ @param pos default = 0
-+ @param callout default = ignore callouts *)
-+
-+val substitute :
-+ ?iflags:irflag ->
-+ ?flags:rflag list ->
-+ ?rex:regexp ->
-+ ?pat:string ->
-+ ?pos:int ->
-+ ?callout:callout ->
-+ subst:(string -> string) ->
-+ string ->
-+ string
-+(** [substitute ?iflags ?flags ?rex ?pat ?pos ?callout ~subst subj] replaces all
-+ substrings of [subj] matching pattern [pat] when given, regular expression
-+ [rex] otherwise, starting at position [pos] with the result of function
-+ [subst] applied to the match. Uses [flags] when given, the precompiled
-+ [iflags] otherwise. Callouts are handled by [callout].
-+
-+ @param iflags default = no extra flags
-+ @param flags default = ignored
-+ @param rex default = matches whitespace
-+ @param pat default = ignored
-+ @param pos default = 0
-+ @param callout default = ignore callouts *)
-+
-+val replace_first :
-+ ?iflags:irflag ->
-+ ?flags:rflag list ->
-+ ?rex:regexp ->
-+ ?pat:string ->
-+ ?pos:int ->
-+ ?itempl:substitution ->
-+ ?templ:string ->
-+ ?callout:callout ->
-+ string ->
-+ string
-+(** [replace_first ?iflags ?flags ?rex ?pat ?pos ?itempl ?templ ?callout subj]
-+ replaces the first substring of [subj] matching pattern [pat] when given,
-+ regular expression [rex] otherwise, starting at position [pos] with the
-+ substitution string [templ] when given, [itempl] otherwise. Uses [flags]
-+ when given, the precompiled [iflags] otherwise. Callouts are handled by
-+ [callout].
-+
-+ @param iflags default = no extra flags
-+ @param flags default = ignored
-+ @param rex default = matches whitespace
-+ @param pat default = ignored
-+ @param pos default = 0
-+ @param itempl default = empty string
-+ @param templ default = ignored
-+ @param callout default = ignore callouts
-+
-+ @raise Failure if there are backreferences to nonexistent subpatterns. *)
-+
-+val qreplace_first :
-+ ?iflags:irflag ->
-+ ?flags:rflag list ->
-+ ?rex:regexp ->
-+ ?pat:string ->
-+ ?pos:int ->
-+ ?templ:string ->
-+ ?callout:callout ->
-+ string ->
-+ string
-+(** [qreplace_first ?iflags ?flags ?rex ?pat ?pos ?templ ?callout subj] replaces
-+ the first substring of [subj] matching pattern [pat] when given, regular
-+ expression [rex] otherwise, starting at position [pos] with the string
-+ [templ]. Uses [flags] when given, the precompiled [iflags] otherwise.
-+ Callouts are handled by [callout].
-+
-+ @param iflags default = no extra flags
-+ @param flags default = ignored
-+ @param rex default = matches whitespace
-+ @param pat default = ignored
-+ @param pos default = 0
-+ @param templ default = ignored
-+ @param callout default = ignore callouts *)
-+
-+val substitute_substrings_first :
-+ ?iflags:irflag ->
-+ ?flags:rflag list ->
-+ ?rex:regexp ->
-+ ?pat:string ->
-+ ?pos:int ->
-+ ?callout:callout ->
-+ subst:(substrings -> string) ->
-+ string ->
-+ string
-+(** [substitute_substrings_first ?iflags ?flags ?rex ?pat ?pos ?callout ~subst
-+ subj] replaces the first substring of [subj] matching pattern [pat] when
-+ given, regular expression [rex] otherwise, starting at position [pos] with
-+ the result of function [subst] applied to the substrings of the match. Uses
-+ [flags] when given, the precompiled [iflags] otherwise. Callouts are handled
-+ by [callout].
-+
-+ @param iflags default = no extra flags
-+ @param flags default = ignored
-+ @param rex default = matches whitespace
-+ @param pat default = ignored
-+ @param pos default = 0
-+ @param callout default = ignore callouts *)
-+
-+val substitute_first :
-+ ?iflags:irflag ->
-+ ?flags:rflag list ->
-+ ?rex:regexp ->
-+ ?pat:string ->
-+ ?pos:int ->
-+ ?callout:callout ->
-+ subst:(string -> string) ->
-+ string ->
-+ string
-+(** [substitute_first ?iflags ?flags ?rex ?pat ?pos ?callout ~subst subj]
-+ replaces the first substring of [subj] matching pattern [pat] when given,
-+ regular expression [rex] otherwise, starting at position [pos] with the
-+ result of function [subst] applied to the match. Uses [flags] when given,
-+ the precompiled [iflags] otherwise. Callouts are handled by [callout].
-+
-+ @param iflags default = no extra flags
-+ @param flags default = ignored
-+ @param rex default = matches whitespace
-+ @param pat default = ignored
-+ @param pos default = 0
-+ @param callout default = ignore callouts *)
-+
-+(** {1 Splitting} *)
-+
-+val split :
-+ ?iflags:irflag ->
-+ ?flags:rflag list ->
-+ ?rex:regexp ->
-+ ?pat:string ->
-+ ?pos:int ->
-+ ?max:int ->
-+ ?callout:callout ->
-+ string ->
-+ string list
-+(** [split ?iflags ?flags ?rex ?pat ?pos ?max ?callout subj] splits [subj] into
-+ a list of at most [max] strings, using as delimiter pattern [pat] when
-+ given, regular expression [rex] otherwise, starting at position [pos]. Uses
-+ [flags] when given, the precompiled [iflags] otherwise. If [max] is zero,
-+ trailing empty fields are stripped. If it is negative, it is treated as
-+ arbitrarily large. If neither [pat] nor [rex] are specified, leading
-+ whitespace will be stripped! Should behave exactly as in PERL. Callouts are
-+ handled by [callout].
-+
-+ @param iflags default = no extra flags
-+ @param flags default = ignored
-+ @param rex default = matches whitespace
-+ @param pat default = ignored
-+ @param pos default = 0
-+ @param max default = 0
-+ @param callout default = ignore callouts *)
-+
-+val asplit :
-+ ?iflags:irflag ->
-+ ?flags:rflag list ->
-+ ?rex:regexp ->
-+ ?pat:string ->
-+ ?pos:int ->
-+ ?max:int ->
-+ ?callout:callout ->
-+ string ->
-+ string array
-+(** [asplit ?iflags ?flags ?rex ?pat ?pos ?max ?callout subj] same as
-+ {!Pcre2.split} but return an array instead of a list. *)
-+
-+(** Result of a {!Pcre2.full_split} *)
-+type split_result =
-+ | Text of string (** Text part of split string *)
-+ | Delim of string (** Delimiter part of split string *)
-+ | Group of int * string
-+ (** Subgroup of matched delimiter (subgroup_nr, subgroup_str) *)
-+ | NoGroup (** Unmatched subgroup *)
-+
-+val full_split :
-+ ?iflags:irflag ->
-+ ?flags:rflag list ->
-+ ?rex:regexp ->
-+ ?pat:string ->
-+ ?pos:int ->
-+ ?max:int ->
-+ ?callout:callout ->
-+ string ->
-+ split_result list
-+(** [full_split ?iflags ?flags ?rex ?pat ?pos ?max ?callout subj] splits [subj]
-+ into a list of at most [max] elements of type "split_result", using as
-+ delimiter pattern [pat] when given, regular expression [rex] otherwise,
-+ starting at position [pos]. Uses [flags] when given, the precompiled
-+ [iflags] otherwise. If [max] is zero, trailing empty fields are stripped. If
-+ it is negative, it is treated as arbitrarily large. Should behave exactly as
-+ in PERL. Callouts are handled by [callout].
-+
-+ @param iflags default = no extra flags
-+ @param flags default = ignored
-+ @param rex default = matches whitespace
-+ @param pat default = ignored
-+ @param pos default = 0
-+ @param max default = 0
-+ @param callout default = ignore callouts *)
-+
-+(** {1 Additional convenience functions} *)
-+
-+val foreach_line : ?ic:in_channel -> (string -> unit) -> unit
-+(** [foreach_line ?ic f] applies [f] to each line in inchannel [ic] until the
-+ end-of-file is reached.
-+
-+ @param ic default = stdin *)
-+
-+val foreach_file : string list -> (string -> in_channel -> unit) -> unit
-+(** [foreach_file filenames f] opens each file in the list [filenames] for input
-+ and applies [f] to each filename and the corresponding channel. Channels are
-+ closed after each operation (even when exceptions occur - they get reraised
-+ afterwards!). *)
-+
-+(** {1 {b UNSAFE STUFF - USE WITH CAUTION!}} *)
-+
-+val unsafe_pcre2_match :
-+ irflag ->
-+ regexp ->
-+ pos:int ->
-+ subj_start:int ->
-+ subj:string ->
-+ int array ->
-+ callout option ->
-+ unit
-+(** [unsafe_pcre_exec flags rex ~pos ~subj_start ~subj offset_vector callout].
-+ You should read the C-source to know what happens. If you do not understand
-+ it - {b don't use this function!} *)
-+
-+val make_ovector : regexp -> int * int array
-+(** [make_ovector regexp] calculates the tuple (subgroups2, ovector) which is
-+ the number of subgroup offsets and the offset array. *)
-+
-+val unsafe_pcre2_dfa_match :
-+ irflag ->
-+ regexp ->
-+ pos:int ->
-+ subj_start:int ->
-+ subj:string ->
-+ int array ->
-+ callout option ->
-+ workspace:int array ->
-+ unit
-+(** [unsafe_pcre_dfa_exec flags rex ~pos ~subj_start ~subj offset_vector callout
-+ ~workpace]. You should read the C-source to know what happens. If you do
-+ not understand it - {b don't use this function!} *)
-diff --git a/bundles/pcre2/pcre2-ocaml/lib/pcre2_stubs.c b/bundles/pcre2/pcre2-ocaml/lib/pcre2_stubs.c
-new file mode 100644
-index 000000000..c923ae29a
---- /dev/null
-+++ b/bundles/pcre2/pcre2-ocaml/lib/pcre2_stubs.c
-@@ -0,0 +1,807 @@
-+/*
-+ PCRE2-OCAML - Perl Compatibility Regular Expressions for OCaml
-+
-+ Copyright © 1999- Markus Mottl <markus.mottl@gmail.com>
-+
-+ This library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ This library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with this library; if not, write to the Free Software
-+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-+*/
-+
-+#if defined(_WIN32)
-+#define snprintf _snprintf
-+#if defined(_DLL)
-+#define PCREextern __declspec(dllexport)
-+#else
-+#define PCREextern
-+#endif
-+#endif
-+
-+#if defined(_WIN64)
-+typedef long long *caml_int_ptr;
-+#else
-+typedef long *caml_int_ptr;
-+#endif
-+
-+#if __GNUC__ >= 3
-+#define __unused __attribute__((unused))
-+#else
-+#define __unused
-+#endif
-+
-+#include <ctype.h>
-+#include <stdio.h>
-+#include <string.h>
-+
-+#include <caml/alloc.h>
-+#include <caml/callback.h>
-+#include <caml/custom.h>
-+#include <caml/fail.h>
-+#include <caml/memory.h>
-+#include <caml/mlvalues.h>
-+#include <caml/version.h>
-+
-+#if (OCAML_VERSION_MAJOR == 4) && (OCAML_VERSION_MINOR < 12)
-+#define Val_none (Val_long(0))
-+#define Some_val(v) Field(v, 0)
-+#define Tag_some 0
-+#define Is_none(v) ((v) == Val_none)
-+#define Is_some(v) Is_block(v)
-+
-+CAMLexport static value caml_alloc_some(value v) {
-+ CAMLparam1(v);
-+ value some = caml_alloc_small(1, 0);
-+ Field(some, 0) = v;
-+ CAMLreturn(some);
-+}
-+#endif
-+
-+#define PCRE2_CODE_UNIT_WIDTH 8
-+
-+#include <pcre2.h>
-+
-+typedef const unsigned char *chartables; /* Type of chartable sets */
-+
-+/* Contents of callout data */
-+struct cod {
-+ long subj_start; /* Start of subject string */
-+ value *v_substrings_p; /* Pointer to substrings matched so far */
-+ value *v_cof_p; /* Pointer to callout function */
-+ value v_exn; /* Possible exception raised by callout function */
-+};
-+
-+/* Cache for exceptions */
-+static const value *pcre2_exc_Error = NULL; /* Exception [Error] */
-+static const value *pcre2_exc_Backtrack = NULL; /* Exception [Backtrack] */
-+
-+/* Cache for polymorphic variants */
-+static value var_Start_only; /* Variant [`Start_only] */
-+static value var_ANCHORED; /* Variant [`ANCHORED] */
-+static value var_Char; /* Variant [`Char char] */
-+
-+/* Data associated with OCaml values of PCRE regular expression */
-+struct pcre2_ocaml_regexp {
-+ pcre2_code *rex;
-+ pcre2_match_context *mcontext;
-+};
-+
-+#define Pcre2_ocaml_regexp_val(v) \
-+ ((struct pcre2_ocaml_regexp *)Data_custom_val(v))
-+
-+#define get_rex(v) Pcre2_ocaml_regexp_val(v)->rex
-+#define get_mcontext(v) Pcre2_ocaml_regexp_val(v)->mcontext
-+
-+#define set_rex(v, r) Pcre2_ocaml_regexp_val(v)->rex = r
-+#define set_mcontext(v, c) Pcre2_ocaml_regexp_val(v)->mcontext = c
-+
-+/* Data associated with OCaml values of PCRE tables */
-+struct pcre2_ocaml_tables {
-+ chartables tables;
-+};
-+
-+#define Pcre2_ocaml_tables_val(v) \
-+ ((struct pcre2_ocaml_tables *)Data_custom_val(v))
-+
-+#define get_tables(v) Pcre2_ocaml_tables_val(v)->tables
-+#define set_tables(v, t) Pcre2_ocaml_tables_val(v)->tables = t
-+
-+/* Converts subject offsets from C-integers to OCaml-Integers.
-+
-+ This is a bit tricky, because there are 32- and 64-bit platforms around
-+ and OCaml chooses the larger possibility for representing integers when
-+ available (also in arrays) - not so the PCRE!
-+*/
-+static inline void copy_ovector(long subj_start, const size_t *ovec_src,
-+ caml_int_ptr ovec_dst, uint32_t subgroups2) {
-+ if (subj_start == 0)
-+ while (subgroups2--) {
-+ *ovec_dst = (*ovec_src == PCRE2_UNSET) ? Val_int(-1) : Val_int(*ovec_src);
-+ --ovec_src;
-+ --ovec_dst;
-+ }
-+ else
-+ while (subgroups2--) {
-+ *ovec_dst = (*ovec_src == PCRE2_UNSET) ? Val_int(-1)
-+ : Val_long(*ovec_src + subj_start);
-+ --ovec_src;
-+ --ovec_dst;
-+ }
-+}
-+
-+/* Callout handler */
-+static int pcre2_callout_handler(pcre2_callout_block *cb, struct cod *cod) {
-+ if (cod != NULL) {
-+ /* Callout is available */
-+ value v_res;
-+
-+ /* Set up parameter array */
-+ value v_callout_data = caml_alloc_small(8, 0);
-+
-+ const value v_substrings = *cod->v_substrings_p;
-+
-+ const uint32_t capture_top = cb->capture_top;
-+ uint32_t subgroups2 = capture_top << 1;
-+ const uint32_t subgroups2_1 = subgroups2 - 1;
-+
-+ const size_t *ovec_src = cb->offset_vector + subgroups2_1;
-+ caml_int_ptr ovec_dst =
-+ (caml_int_ptr)&Field(Field(v_substrings, 1), 0) + subgroups2_1;
-+ long subj_start = cod->subj_start;
-+
-+ copy_ovector(subj_start, ovec_src, ovec_dst, subgroups2);
-+
-+ Field(v_callout_data, 0) = Val_int(cb->callout_number);
-+ Field(v_callout_data, 1) = v_substrings;
-+ Field(v_callout_data, 2) = Val_int(cb->start_match + subj_start);
-+ Field(v_callout_data, 3) = Val_int(cb->current_position + subj_start);
-+ Field(v_callout_data, 4) = Val_int(capture_top);
-+ Field(v_callout_data, 5) = Val_int(cb->capture_last);
-+ Field(v_callout_data, 6) = Val_int(cb->pattern_position);
-+ Field(v_callout_data, 7) = Val_int(cb->next_item_length);
-+
-+ /* Perform callout */
-+ v_res = caml_callback_exn(*cod->v_cof_p, v_callout_data);
-+
-+ if (Is_exception_result(v_res)) {
-+ /* Callout raised an exception */
-+ const value v_exn = Extract_exception(v_res);
-+ if (Field(v_exn, 0) == *pcre2_exc_Backtrack)
-+ return 1;
-+ cod->v_exn = v_exn;
-+ return PCRE2_ERROR_CALLOUT;
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+/* Fetches the named OCaml-values + caches them and
-+ calculates + caches the variant hash values */
-+CAMLprim value pcre2_ocaml_init(value __unused v_unit) {
-+ pcre2_exc_Error = caml_named_value("Pcre2.Error");
-+ pcre2_exc_Backtrack = caml_named_value("Pcre2.Backtrack");
-+
-+ var_Start_only = caml_hash_variant("Start_only");
-+ var_ANCHORED = caml_hash_variant("ANCHORED");
-+ var_Char = caml_hash_variant("Char");
-+
-+ return Val_unit;
-+}
-+
-+/* Finalizing deallocation function for chartable sets */
-+static void pcre2_dealloc_tables(value v_tables) {
-+#if PCRE2_MINOR >= 34
-+ pcre2_maketables_free(NULL, get_tables(v_tables));
-+#else
-+ free((void *)get_tables(v_tables));
-+#endif
-+}
-+
-+/* Finalizing deallocation function for compiled regular expressions */
-+static void pcre2_dealloc_regexp(value v_rex) {
-+ pcre2_code_free(get_rex(v_rex));
-+ pcre2_match_context_free(get_mcontext(v_rex));
-+}
-+
-+/* Raising exceptions */
-+
-+CAMLnoreturn_start static inline void
-+raise_pcre2_error(value v_arg) CAMLnoreturn_end;
-+
-+CAMLnoreturn_start static inline void raise_partial(void) CAMLnoreturn_end;
-+
-+CAMLnoreturn_start static inline void raise_bad_utf(void) CAMLnoreturn_end;
-+
-+CAMLnoreturn_start static inline void
-+raise_bad_utf_offset(void) CAMLnoreturn_end;
-+
-+CAMLnoreturn_start static inline void raise_match_limit(void) CAMLnoreturn_end;
-+
-+CAMLnoreturn_start static inline void raise_depth_limit(void) CAMLnoreturn_end;
-+
-+CAMLnoreturn_start static inline void
-+raise_workspace_size(void) CAMLnoreturn_end;
-+
-+CAMLnoreturn_start static inline void
-+raise_bad_pattern(int code, size_t pos) CAMLnoreturn_end;
-+
-+CAMLnoreturn_start static inline void
-+raise_internal_error(char *msg) CAMLnoreturn_end;
-+
-+static inline void raise_pcre2_error(value v_arg) {
-+ caml_raise_with_arg(*pcre2_exc_Error, v_arg);
-+}
-+
-+static inline void raise_partial(void) { raise_pcre2_error(Val_int(0)); }
-+static inline void raise_bad_utf(void) { raise_pcre2_error(Val_int(1)); }
-+static inline void raise_bad_utf_offset(void) { raise_pcre2_error(Val_int(2)); }
-+static inline void raise_match_limit(void) { raise_pcre2_error(Val_int(3)); }
-+static inline void raise_depth_limit(void) { raise_pcre2_error(Val_int(4)); }
-+static inline void raise_workspace_size(void) { raise_pcre2_error(Val_int(5)); }
-+
-+/* The length of msg_buf in this function is chosen to be larger than
-+ any existing error-message in pcre2_error.c. Currently (Feb 25, 2025, Git
-+ commit 0880a6c33a51e2dfded8864a6bcc8ae4e9a90f89), the longest error-message
-+ is about 110 chars. Uncomfortably close to 128, so I doubled the length to
-+ 256.
-+*/
-+
-+static inline void raise_bad_pattern(int code, size_t pos) {
-+ CAMLparam0();
-+ CAMLlocal2(v_msg, v_arg);
-+ char msg_buf[128];
-+ pcre2_get_error_message(code, (PCRE2_UCHAR *)msg_buf,
-+ (sizeof msg_buf) / (sizeof(PCRE2_UCHAR)));
-+ v_msg = caml_copy_string(msg_buf);
-+ v_arg = caml_alloc_small(2, 0);
-+ Field(v_arg, 0) = v_msg;
-+ Field(v_arg, 1) = Val_int(pos);
-+ raise_pcre2_error(v_arg);
-+ CAMLnoreturn;
-+}
-+
-+static inline void raise_internal_error(char *msg) {
-+ CAMLparam0();
-+ CAMLlocal1(v_msg);
-+ value v_arg;
-+ v_msg = caml_copy_string(msg);
-+ v_arg = caml_alloc_small(1, 1);
-+ Field(v_arg, 0) = v_msg;
-+ raise_pcre2_error(v_arg);
-+ CAMLnoreturn;
-+}
-+
-+/* PCRE pattern compilation */
-+
-+static struct custom_operations regexp_ops = {
-+ "pcre2_ocaml_regexp", pcre2_dealloc_regexp,
-+ custom_compare_default, custom_hash_default,
-+ custom_serialize_default, custom_deserialize_default,
-+ custom_compare_ext_default, custom_fixed_length_default};
-+
-+/* Makes compiled regular expression from compilation options, an optional
-+ value of chartables and the pattern string */
-+
-+CAMLprim value pcre2_compile_stub(int64_t v_opt, value v_tables, value v_pat) {
-+ value v_rex; /* Final result -> value of type [regexp] */
-+ size_t regexp_size, ocaml_regexp_size = sizeof(struct pcre2_ocaml_regexp);
-+ int error_code = 0; /* error code for potential error */
-+ size_t error_ofs = 0; /* offset in the pattern at which error occurred */
-+ size_t length = caml_string_length(v_pat);
-+
-+ pcre2_compile_context *ccontext = NULL;
-+ /* If v_tables = [None], then pointer to tables is NULL, otherwise
-+ set it to the appropriate value */
-+ if (Is_some(v_tables)) {
-+ ccontext = pcre2_compile_context_create(NULL);
-+ pcre2_set_character_tables(ccontext, get_tables(Field(v_tables, 0)));
-+ }
-+
-+ /* Compiles the pattern */
-+ pcre2_code *regexp = pcre2_compile((PCRE2_SPTR)String_val(v_pat), length,
-+ v_opt, &error_code, &error_ofs, ccontext);
-+
-+ pcre2_compile_context_free(ccontext);
-+
-+ /* Raises appropriate exception with [BadPattern] if the pattern
-+ could not be compiled */
-+ if (regexp == NULL)
-+ raise_bad_pattern(error_code, error_ofs);
-+
-+ /* It's unknown at this point whether JIT compilation is going to be used,
-+ but we have to decide on a size. Tests with some simple patterns indicate
-+ a roughly 50% increase in size when studying without JIT. A factor of two
-+ times hence seems like a reasonable bound to use here. */
-+ pcre2_pattern_info(regexp, PCRE2_INFO_SIZE, ®exp_size);
-+ v_rex =
-+ caml_alloc_custom_mem(®exp_ops, ocaml_regexp_size, 2 * regexp_size);
-+
-+ set_rex(v_rex, regexp);
-+ set_mcontext(v_rex, pcre2_match_context_create(NULL));
-+
-+ return v_rex;
-+}
-+
-+CAMLprim value pcre2_compile_stub_bc(value v_opt, value v_tables, value v_pat) {
-+ return pcre2_compile_stub(Int64_val(v_opt), v_tables, v_pat);
-+}
-+
-+/* Gets the depth limit of a regular expression if it exists */
-+/* CAMLprim value pcre2_get_depth_limit_stub(value v_rex); */
-+
-+/* Gets the match limit of a regular expression if it exists */
-+/* CAMLprim value pcre2_get_match_limit_stub(value v_rex); */
-+
-+/* Sets a match limit for a regular expression imperatively */
-+
-+CAMLprim value pcre2_set_imp_match_limit_stub(value v_rex, intnat v_lim) {
-+ pcre2_match_context *mcontext = get_mcontext(v_rex);
-+ pcre2_set_match_limit(mcontext, v_lim);
-+ return v_rex;
-+}
-+
-+CAMLprim value pcre2_set_imp_match_limit_stub_bc(value v_rex, value v_lim) {
-+ return pcre2_set_imp_match_limit_stub(v_rex, Int_val(v_lim));
-+}
-+
-+/* Sets a depth limit for a regular expression imperatively */
-+
-+CAMLprim value pcre2_set_imp_depth_limit_stub(value v_rex, intnat v_lim) {
-+ pcre2_match_context *mcontext = get_mcontext(v_rex);
-+ pcre2_set_depth_limit(mcontext, v_lim);
-+ return v_rex;
-+}
-+
-+CAMLprim value pcre2_set_imp_depth_limit_stub_bc(value v_rex, value v_lim) {
-+ return pcre2_set_imp_depth_limit_stub(v_rex, Int_val(v_lim));
-+}
-+
-+/* Performs the call to the pcre2_pattern_info function */
-+static inline int pcre2_pattern_info_stub(value v_rex, int what, void *where) {
-+ return pcre2_pattern_info(get_rex(v_rex), what, where);
-+}
-+
-+/* Some stubs for info-functions */
-+
-+/* Generic macro for getting integer results from pcre2_pattern_info */
-+#define MAKE_INTNAT_INFO(tp, name, option) \
-+ CAMLprim intnat pcre2_##name##_stub(value v_rex) { \
-+ tp options; \
-+ const int ret = \
-+ pcre2_pattern_info_stub(v_rex, PCRE2_INFO_##option, &options); \
-+ if (ret != 0) \
-+ raise_internal_error("pcre2_##name##_stub"); \
-+ return options; \
-+ } \
-+ \
-+ CAMLprim value pcre2_##name##_stub_bc(value v_rex) { \
-+ return Val_int(pcre2_##name##_stub(v_rex)); \
-+ }
-+
-+MAKE_INTNAT_INFO(size_t, size, SIZE)
-+MAKE_INTNAT_INFO(int, capturecount, CAPTURECOUNT)
-+MAKE_INTNAT_INFO(int, backrefmax, BACKREFMAX)
-+MAKE_INTNAT_INFO(int, namecount, NAMECOUNT)
-+MAKE_INTNAT_INFO(int, nameentrysize, NAMEENTRYSIZE)
-+
-+CAMLprim int64_t pcre2_argoptions_stub(value v_rex) {
-+ uint32_t options;
-+ const int ret =
-+ pcre2_pattern_info_stub(v_rex, PCRE2_INFO_ARGOPTIONS, &options);
-+ if (ret != 0)
-+ raise_internal_error("pcre2_argoptions_stub");
-+ return (int64_t)options;
-+}
-+
-+CAMLprim value pcre2_argoptions_stub_bc(value v_rex) {
-+ CAMLparam1(v_rex);
-+ CAMLreturn(caml_copy_int64(pcre2_argoptions_stub(v_rex)));
-+}
-+
-+CAMLprim value pcre2_firstcodeunit_stub(value v_rex) {
-+ uint32_t firstcodetype;
-+ const int ret =
-+ pcre2_pattern_info_stub(v_rex, PCRE2_INFO_FIRSTCODETYPE, &firstcodetype);
-+
-+ if (ret != 0)
-+ raise_internal_error("pcre2_firstcodeunit_stub");
-+
-+ switch (firstcodetype) {
-+ case 2:
-+ return var_Start_only;
-+ break; /* [`Start_only] */
-+ case 0:
-+ return var_ANCHORED;
-+ break; /* [`ANCHORED] */
-+ case 1: {
-+ uint32_t firstcodeunit;
-+ const int ret = pcre2_pattern_info_stub(v_rex, PCRE2_INFO_FIRSTCODEUNIT,
-+ &firstcodeunit);
-+ if (ret != 0)
-+ raise_internal_error("pcre2_firstcodeunit_stub");
-+
-+ value v_firstbyte;
-+ /* Allocates the non-constant constructor [`Char of char] and fills
-+ in the appropriate value */
-+ v_firstbyte = caml_alloc_small(2, 0);
-+ Field(v_firstbyte, 0) = var_Char;
-+ Field(v_firstbyte, 1) = Val_int(firstcodeunit);
-+
-+ return v_firstbyte;
-+ break;
-+ }
-+ default: /* Should not happen */
-+ raise_internal_error("pcre2_firstcodeunit_stub");
-+ }
-+}
-+
-+CAMLprim value pcre2_lastcodeunit_stub(value v_rex) {
-+ uint32_t lastcodetype;
-+ const int ret =
-+ pcre2_pattern_info_stub(v_rex, PCRE2_INFO_LASTCODETYPE, &lastcodetype);
-+
-+ if (ret != 0)
-+ raise_internal_error("pcre2_lastcodeunit_stub");
-+
-+ if (lastcodetype == 0)
-+ return Val_none;
-+ if (lastcodetype != 1)
-+ raise_internal_error("pcre2_lastcodeunit_stub");
-+ else {
-+ uint32_t lastcodeunit;
-+ const int ret =
-+ pcre2_pattern_info_stub(v_rex, PCRE2_INFO_LASTCODEUNIT, &lastcodeunit);
-+ if (ret != 0)
-+ raise_internal_error("pcre2_lastcodeunit_stub");
-+ return caml_alloc_some(Val_int(lastcodeunit));
-+ }
-+}
-+
-+CAMLnoreturn_start static inline void
-+handle_match_error(char *loc, const int ret) CAMLnoreturn_end;
-+
-+static inline void handle_match_error(char *loc, const int ret) {
-+ switch (ret) {
-+ /* Dedicated exceptions */
-+ case PCRE2_ERROR_NOMATCH:
-+ caml_raise_not_found();
-+ case PCRE2_ERROR_PARTIAL:
-+ raise_partial();
-+ case PCRE2_ERROR_MATCHLIMIT:
-+ raise_match_limit();
-+ case PCRE2_ERROR_BADUTFOFFSET:
-+ raise_bad_utf_offset();
-+ case PCRE2_ERROR_DEPTHLIMIT:
-+ raise_depth_limit();
-+ case PCRE2_ERROR_DFA_WSSIZE:
-+ raise_workspace_size();
-+ default: {
-+ if (PCRE2_ERROR_UTF8_ERR21 <= ret && ret <= PCRE2_ERROR_UTF8_ERR1)
-+ raise_bad_utf();
-+ /* Unknown error */
-+ char err_buf[100];
-+ snprintf(err_buf, 100, "%s: unhandled PCRE2 error code: %d", loc, ret);
-+ raise_internal_error(err_buf);
-+ }
-+ }
-+}
-+
-+static inline void handle_pcre2_match_result(size_t *ovec, value v_ovec,
-+ size_t ovec_len, long subj_start,
-+ uint32_t ret) {
-+ caml_int_ptr ocaml_ovec = (caml_int_ptr)&Field(v_ovec, 0);
-+ const uint32_t subgroups2 = ret * 2;
-+ const uint32_t subgroups2_1 = subgroups2 - 1;
-+ const size_t *ovec_src = ovec + subgroups2_1;
-+ caml_int_ptr ovec_clear_stop = ocaml_ovec + (ovec_len * 2) / 3;
-+ caml_int_ptr ovec_dst = ocaml_ovec + subgroups2_1;
-+ copy_ovector(subj_start, ovec_src, ovec_dst, subgroups2);
-+ while (++ovec_dst < ovec_clear_stop)
-+ *ovec_dst = -1;
-+}
-+
-+/* Executes a pattern match with runtime options, a regular expression, a
-+ matching position, the start of the subject string, a subject string,
-+ a number of subgroup offsets, an offset vector and an optional callout
-+ function */
-+
-+CAMLprim value pcre2_match_stub0(int64_t v_opt, value v_rex, intnat v_pos,
-+ intnat v_subj_start, value v_subj,
-+ value v_ovec, value v_maybe_cof,
-+ value v_workspace) {
-+ int ret;
-+ int is_dfa = v_workspace != (value)NULL;
-+ long pos = v_pos, subj_start = v_subj_start;
-+ size_t ovec_len = Wosize_val(v_ovec), len = caml_string_length(v_subj);
-+
-+ if (pos > (long)len || pos < subj_start)
-+ caml_invalid_argument("Pcre2.pcre2_match_stub: illegal position");
-+
-+ if (subj_start > (long)len || subj_start < 0)
-+ caml_invalid_argument("Pcre2.pcre2_match_stub: illegal subject start");
-+
-+ pos -= subj_start;
-+ len -= subj_start;
-+
-+ {
-+ const pcre2_code *code = get_rex(v_rex); /* Compiled pattern */
-+ pcre2_match_context *mcontext = get_mcontext(v_rex); /* Match context */
-+ PCRE2_SPTR ocaml_subj =
-+ (PCRE2_SPTR)String_val(v_subj) + subj_start; /* Subject string */
-+
-+ pcre2_match_data *match_data =
-+ pcre2_match_data_create_from_pattern(code, NULL);
-+
-+ /* Special case when no callout functions specified */
-+ if (Is_none(v_maybe_cof)) {
-+ /* Performs the match */
-+ if (is_dfa)
-+ ret = pcre2_dfa_match(code, ocaml_subj, len, pos, v_opt, match_data,
-+ mcontext, (int *)&Field(v_workspace, 0),
-+ Wosize_val(v_workspace));
-+ else
-+ ret = pcre2_match(code, ocaml_subj, len, pos, v_opt, match_data,
-+ mcontext);
-+
-+ size_t *ovec = pcre2_get_ovector_pointer(match_data);
-+
-+ if (ret < 0) {
-+ pcre2_match_data_free(match_data);
-+ handle_match_error("pcre2_match_stub", ret);
-+ } else {
-+ handle_pcre2_match_result(ovec, v_ovec, ovec_len, subj_start, ret);
-+ }
-+ }
-+
-+ /* There are callout functions */
-+ else {
-+ value v_cof = Field(v_maybe_cof, 0);
-+ value v_substrings;
-+ PCRE2_UCHAR *subj = caml_stat_alloc(sizeof(char) * len);
-+ int workspace_len = 0;
-+ int *workspace = NULL;
-+ struct cod cod = {0, (value *)NULL, (value *)NULL, (value)NULL};
-+ pcre2_match_context *new_mcontext = pcre2_match_context_copy(mcontext);
-+
-+ pcre2_set_callout(
-+ new_mcontext,
-+ (int (*)(pcre2_callout_block_8 *, void *))&pcre2_callout_handler,
-+ &cod);
-+
-+ cod.subj_start = subj_start;
-+ memcpy(subj, ocaml_subj, len);
-+
-+ Begin_roots4(v_rex, v_cof, v_substrings, v_ovec);
-+ Begin_roots1(v_subj);
-+ v_substrings = caml_alloc_small(2, 0);
-+ End_roots();
-+
-+ Field(v_substrings, 0) = v_subj;
-+ Field(v_substrings, 1) = v_ovec;
-+
-+ cod.v_substrings_p = &v_substrings;
-+ cod.v_cof_p = &v_cof;
-+
-+ if (is_dfa) {
-+ workspace_len = Wosize_val(v_workspace);
-+ workspace = caml_stat_alloc(sizeof(int) * workspace_len);
-+ ret = pcre2_dfa_match(code, subj, len, pos, v_opt, match_data,
-+ new_mcontext, (int *)&Field(v_workspace, 0),
-+ workspace_len);
-+ } else
-+ ret =
-+ pcre2_match(code, subj, len, pos, v_opt, match_data, new_mcontext);
-+
-+ caml_stat_free(subj);
-+ End_roots();
-+
-+ pcre2_match_context_free(new_mcontext);
-+ size_t *ovec = pcre2_get_ovector_pointer(match_data);
-+ if (ret < 0) {
-+ if (is_dfa)
-+ caml_stat_free(workspace);
-+ pcre2_match_data_free(match_data);
-+ if (ret == PCRE2_ERROR_CALLOUT)
-+ caml_raise(cod.v_exn);
-+ else
-+ handle_match_error("pcre2_match_stub(callout)", ret);
-+ } else {
-+ handle_pcre2_match_result(ovec, v_ovec, ovec_len, subj_start, ret);
-+ if (is_dfa) {
-+ caml_int_ptr ocaml_workspace_dst =
-+ (caml_int_ptr)&Field(v_workspace, 0);
-+ const int *workspace_src = workspace;
-+ const int *workspace_src_stop = workspace + workspace_len;
-+ while (workspace_src != workspace_src_stop) {
-+ *ocaml_workspace_dst = *workspace_src;
-+ ocaml_workspace_dst++;
-+ workspace_src++;
-+ }
-+ caml_stat_free(workspace);
-+ }
-+ }
-+ }
-+ pcre2_match_data_free(match_data);
-+ }
-+
-+ return Val_unit;
-+}
-+
-+CAMLprim value pcre2_match_stub(int64_t v_opt, value v_rex, intnat v_pos,
-+ intnat v_subj_start, value v_subj, value v_ovec,
-+ value v_maybe_cof) {
-+ return pcre2_match_stub0(v_opt, v_rex, v_pos, v_subj_start, v_subj, v_ovec,
-+ v_maybe_cof, (value)NULL);
-+}
-+
-+/* Byte-code hook for pcre2_match_stub
-+ Needed, because there are more than 5 arguments */
-+CAMLprim value pcre2_match_stub_bc(value *argv, int __unused argn) {
-+ return pcre2_match_stub0(Int64_val(argv[0]), argv[1], Int_val(argv[2]),
-+ Int_val(argv[3]), argv[4], argv[5], argv[6],
-+ (value)NULL);
-+}
-+
-+/* Byte-code hook for pcre2_dfa_match_stub
-+ Needed, because there are more than 5 arguments */
-+CAMLprim value pcre2_dfa_match_stub_bc(value *argv, int __unused argn) {
-+ return pcre2_match_stub0(Int64_val(argv[0]), argv[1], Int_val(argv[2]),
-+ Int_val(argv[3]), argv[4], argv[5], argv[6],
-+ argv[7]);
-+}
-+
-+static struct custom_operations tables_ops = {
-+ "pcre2_ocaml_tables", pcre2_dealloc_tables,
-+ custom_compare_default, custom_hash_default,
-+ custom_serialize_default, custom_deserialize_default,
-+ custom_compare_ext_default, custom_fixed_length_default};
-+
-+/* Generates a new set of chartables for the current locale (see man
-+ page of PCRE */
-+CAMLprim value pcre2_maketables_stub(value __unused v_unit) {
-+ /* According to testing with `malloc_size`, it seems that a typical set of
-+ tables will require about 1536 bytes of memory. This may or may not
-+ be true on other platforms or for all versions of PCRE. Since there
-+ is apparently no reliable way of finding out, 1536 is probably a good
-+ default value. */
-+ size_t tables_size = sizeof(struct pcre2_ocaml_tables);
-+ const value v_tables = caml_alloc_custom_mem(&tables_ops, tables_size, 1536);
-+ set_tables(v_tables, pcre2_maketables(NULL));
-+ return v_tables;
-+}
-+
-+/* Wraps around the isspace-function */
-+CAMLprim value pcre2_isspace_stub(value v_c) {
-+ return Val_bool(isspace(Int_val(v_c)));
-+}
-+
-+/* Returns number of substring associated with a name */
-+
-+CAMLprim intnat pcre2_substring_number_from_name_stub(value v_rex,
-+ value v_name) {
-+ const int ret = pcre2_substring_number_from_name(
-+ get_rex(v_rex), (PCRE2_SPTR)String_val(v_name));
-+ if (ret == PCRE2_ERROR_NOSUBSTRING)
-+ caml_invalid_argument("Named string not found");
-+
-+ return ret;
-+}
-+
-+CAMLprim value pcre2_substring_number_from_name_stub_bc(value v_rex,
-+ value v_name) {
-+ return Val_int(pcre2_substring_number_from_name_stub(v_rex, v_name));
-+}
-+
-+/* Returns array of names of named substrings in a regexp */
-+CAMLprim value pcre2_names_stub(value v_rex) {
-+ CAMLparam1(v_rex);
-+ CAMLlocal1(v_res);
-+ uint32_t name_count;
-+ uint32_t entry_size;
-+ const char *tbl_ptr;
-+ uint32_t i;
-+
-+ int ret = pcre2_pattern_info_stub(v_rex, PCRE2_INFO_NAMECOUNT, &name_count);
-+ if (ret != 0)
-+ raise_internal_error("pcre2_names_stub: namecount");
-+
-+ ret = pcre2_pattern_info_stub(v_rex, PCRE2_INFO_NAMEENTRYSIZE, &entry_size);
-+ if (ret != 0)
-+ raise_internal_error("pcre2_names_stub: nameentrysize");
-+
-+ ret = pcre2_pattern_info_stub(v_rex, PCRE2_INFO_NAMETABLE, &tbl_ptr);
-+ if (ret != 0)
-+ raise_internal_error("pcre2_names_stub: nametable");
-+
-+ v_res = caml_alloc(name_count, 0);
-+
-+ for (i = 0; i < name_count; ++i) {
-+ value v_name = caml_copy_string(tbl_ptr + 2);
-+ Store_field(v_res, i, v_name);
-+ tbl_ptr += entry_size;
-+ }
-+
-+ CAMLreturn(v_res);
-+}
-+
-+/* Generic stub for getting integer results from pcre2_config */
-+static inline int pcre2_config_int(int what) {
-+ int ret;
-+ pcre2_config(what, (void *)&ret);
-+ return ret;
-+}
-+
-+/* Generic stub for getting long integer results from pcre2_config */
-+static inline long pcre2_config_long(int what) {
-+ long ret;
-+ pcre2_config(what, (void *)&ret);
-+ return ret;
-+}
-+
-+/* Some stubs for config-functions */
-+
-+/* Makes OCaml-string from PCRE-version */
-+CAMLprim value pcre2_version_stub(value __unused v_unit) {
-+ CAMLparam1(v_unit);
-+ CAMLlocal1(v_version);
-+ v_version = caml_alloc_string(32);
-+
-+ pcre2_config(PCRE2_CONFIG_VERSION, (void *)String_val(v_version));
-+
-+ CAMLreturn(v_version);
-+}
-+
-+/* Returns boolean indicating unicode support */
-+CAMLprim value pcre2_config_unicode_stub(value __unused v_unit) {
-+ return Val_bool(pcre2_config_int(PCRE2_CONFIG_UNICODE));
-+}
-+
-+/* Returns character used as newline */
-+CAMLprim value pcre2_config_newline_stub(value __unused v_unit) {
-+ return Val_int(pcre2_config_int(PCRE2_CONFIG_NEWLINE));
-+}
-+
-+/* Returns number of bytes used for internal linkage of regular expressions */
-+
-+CAMLprim intnat pcre2_config_link_size_stub(value __unused v_unit) {
-+ return pcre2_config_int(PCRE2_CONFIG_LINKSIZE);
-+}
-+
-+CAMLprim value pcre2_config_link_size_stub_bc(value v_unit) {
-+ return Val_int(pcre2_config_link_size_stub(v_unit));
-+}
-+
-+/* Returns default limit for calls to internal matching function */
-+
-+CAMLprim intnat pcre2_config_match_limit_stub(value __unused v_unit) {
-+ return pcre2_config_long(PCRE2_CONFIG_MATCHLIMIT);
-+}
-+
-+CAMLprim value pcre2_config_match_limit_stub_bc(value v_unit) {
-+ return Val_int(pcre2_config_match_limit_stub(v_unit));
-+}
-+
-+/* Returns default limit for depth of nested backtracking */
-+
-+CAMLprim intnat pcre2_config_depth_limit_stub(value __unused v_unit) {
-+ return pcre2_config_long(PCRE2_CONFIG_DEPTHLIMIT);
-+}
-+
-+CAMLprim value pcre2_config_depth_limit_stub_bc(value v_unit) {
-+ return Val_int(pcre2_config_depth_limit_stub(v_unit));
-+}
-+
-+/* Returns boolean indicating use of stack recursion */
-+CAMLprim intnat pcre2_config_stackrecurse_stub(value __unused v_unit) {
-+ return Val_bool(pcre2_config_int(PCRE2_CONFIG_STACKRECURSE));
-+}
-diff --git a/bundles/pcre2/pcre2-ocaml/pa_ppx_test/Makefile b/bundles/pcre2/pcre2-ocaml/pa_ppx_test/Makefile
-new file mode 100644
-index 000000000..e35bbc1f1
---- /dev/null
-+++ b/bundles/pcre2/pcre2-ocaml/pa_ppx_test/Makefile
-@@ -0,0 +1,11 @@
-+NOT_OCAMLFIND=not-ocamlfind
-+
-+bootstrap: ../test/pcre2_tests.ml
-+
-+../test/%.ml: %.ml
-+ $(NOT_OCAMLFIND) preprocess \
-+ -package pa_ppx_regexp,camlp5.pr_o -ppopt -pa_ppx_regexp-nostatic \
-+ -syntax camlp5o $< > $@.NEW && \
-+ mv $@.NEW $@
-+
-+.SUFFIXES: .ml
-diff --git a/bundles/pcre2/pcre2-ocaml/pa_ppx_test/pcre2_tests.ml b/bundles/pcre2/pcre2-ocaml/pa_ppx_test/pcre2_tests.ml
-new file mode 100644
-index 000000000..79c9ac763
---- /dev/null
-+++ b/bundles/pcre2/pcre2-ocaml/pa_ppx_test/pcre2_tests.ml
-@@ -0,0 +1,249 @@
-+open OUnit2
-+(**pp -syntax camlp5o -package pa_ppx.deriving_plugins.std *)
-+
-+let test_special_char_regexps ctxt =
-+ ();
-+ assert_equal "\n" ([%match {|\n$|} / s exc pcre2 strings] "\n");
-+ assert_equal "" ([%subst {|\n+$|} / {||} / s pcre2] "\n\n")
-+
-+let test_pcre2_simple_match ctxt =
-+ ();
-+ assert_equal "abc"
-+ (Pcre2.get_substring ([%match "abc" / exc raw pcre2] "abc") 0);
-+ assert_equal (Some "abc") ([%match "abc" / pcre2] "abc");
-+ assert_equal (Some "abc") ([%match "abc" / strings pcre2] "abc");
-+ assert_equal true ([%match "abc" / pred pcre2] "abc");
-+ assert_equal false ([%match "abc" / pred pcre2] "abd");
-+ assert_equal None ([%match "abc" / pcre2] "abd");
-+ assert_raises Not_found (fun () -> [%match "abc" / exc pcre2] "abd");
-+ assert_raises Not_found (fun () -> [%match "abc" / exc strings pcre2] "abd");
-+ assert_equal None ([%match "abc" / strings pcre2] "abd");
-+ assert_equal "abc" ([%match "abc" / exc strings pcre2] "abc");
-+ assert_equal ("abc", Some "b") ([%match "a(b)c" / exc strings pcre2] "abc");
-+ assert_equal ("ac", None) ([%match "a(?:(b)?)c" / exc strings pcre2] "ac");
-+ assert_equal "abc"
-+ (Pcre2.get_substring ([%match "ABC" / exc raw i pcre2] "abc") 0);
-+ assert_equal
-+ ("abc", Some "a", Some "b", Some "c")
-+ ([%match "(a)(b)(c)" / exc strings pcre2] "abc")
-+
-+let test_pcre2_selective_match ctxt =
-+ ();
-+ assert_equal ("abc", Some "b")
-+ ([%match "a(b)c" / exc strings (!0, 1) pcre2] "abc");
-+ assert_equal ("abc", "b")
-+ ([%match "a(b)c" / exc strings (!0, !1) pcre2] "abc");
-+ assert_equal "b" ([%match "a(b)c" / exc strings !1 pcre2] "abc");
-+ assert_equal
-+ (Some ("abc", "b"))
-+ ([%match "a(b)c" / strings (!0, !1) pcre2] "abc");
-+ assert_equal ("ac", None) ([%match "a(b)?c" / exc strings (!0, 1) pcre2] "ac");
-+ assert_raises Not_found (fun _ ->
-+ [%match "a(b)?c" / exc strings (!0, !1) pcre2] "ac");
-+ assert_equal None ([%match "a(b)?c" / strings (!0, !1) pcre2] "ac")
-+
-+let test_pcre2_search ctxt =
-+ ();
-+ assert_equal "abc" ([%match "abc" / exc strings pcre2] "zzzabc");
-+ assert_equal None ([%match "^abc" / strings pcre2] "zzzabc")
-+
-+let show_string_option = function
-+ | None -> "None"
-+ | Some s -> Printf.sprintf "Some %s" s
-+
-+let test_pcre2_single ctxt =
-+ let printer = show_string_option in
-+ ();
-+ assert_equal ~printer None ([%match ".+" / pcre2] "\n\n");
-+ assert_equal ~printer None ([%match ".+" / m pcre2 strings] "\n\n");
-+
-+ assert_equal ~printer None ([%match ".+" / pcre2 strings] "\n\n");
-+ assert_equal ~printer (Some "\n\n") ([%match ".+" / s pcre2 strings] "\n\n");
-+ assert_equal ~printer None ([%match ".+" / m pcre2 strings] "\n\n");
-+
-+ let printer x = x in
-+ ();
-+ assert_equal ~printer "\n\n" ([%match ".+" / s exc pcre2 strings] "\n\n");
-+ assert_equal ~printer "<<abc>>\ndef"
-+ ([%subst ".+" / {|<<$0>>|} / pcre2] "abc\ndef");
-+ assert_equal ~printer "<<abc\ndef>>"
-+ ([%subst ".+" / {|<<$0>>|} / s pcre2] "abc\ndef");
-+ assert_equal ~printer "<<abc>>\ndef"
-+ ([%subst ".+" / {|<<$0>>|} / m pcre2] "abc\ndef");
-+
-+ assert_equal ~printer "<<abc>>\ndef"
-+ ([%subst ".*" / {|<<$0>>|} / pcre2] "abc\ndef");
-+ assert_equal ~printer "<<abc>><<>>\n<<def>><<>>"
-+ ([%subst ".*" / {|<<$0>>|} / g pcre2] "abc\ndef");
-+ assert_equal ~printer "<<abc>>\n<<def>>"
-+ ([%subst ".+" / {|<<$0>>|} / g pcre2] "abc\ndef");
-+ assert_equal ~printer "<<abc>>a\nc<<aec>>"
-+ ([%subst "a.c" / {|<<$0>>|} / g pcre2] "abca\ncaec");
-+ assert_equal ~printer "<<abc>><<a\nc>><<aec>>"
-+ ([%subst "a.c" / {|<<$0>>|} / g s pcre2] "abca\ncaec")
-+
-+let test_pcre2_multiline ctxt =
-+ ();
-+ assert_equal (Some "bar") ([%match ".+$" / strings pcre2] "foo\nbar");
-+ assert_equal (Some "foo") ([%match ".+$" / m strings pcre2] "foo\nbar")
-+
-+let test_pcre2_simple_split ctxt =
-+ ();
-+ assert_equal [ "bb" ] ([%split "a" / pcre2] "bb")
-+
-+let test_pcre2_delim_split_raw ctxt =
-+ let open Pcre2 in
-+ ();
-+ assert_equal
-+ [ Delim "a"; Text "b"; Delim "a"; Text "b" ]
-+ ([%split "a" / pcre2 raw] "ababa");
-+ assert_equal
-+ [ Delim "a"; Text "b"; Delim "a"; Delim "a"; Text "b" ]
-+ ([%split "a" / pcre2 raw] "abaaba");
-+ assert_equal
-+ [
-+ Delim "a";
-+ NoGroup;
-+ Text "b";
-+ Delim "ac";
-+ Group (1, "c");
-+ Text "b";
-+ Delim "a";
-+ NoGroup;
-+ ]
-+ ([%split "a(c)?" / pcre2 raw] "abacba");
-+ assert_equal
-+ [
-+ Delim "ac";
-+ Group (1, "c");
-+ Text "b";
-+ Delim "ac";
-+ Group (1, "c");
-+ Text "b";
-+ Delim "ac";
-+ Group (1, "c");
-+ ]
-+ ([%split "a(c)" / pcre2 raw] "acbacbac");
-+ assert_equal
-+ [
-+ Delim "ac";
-+ Group (1, "c");
-+ Text "b";
-+ Delim "ac";
-+ Group (1, "c");
-+ Text "b";
-+ Delim "ac";
-+ Group (1, "c");
-+ ]
-+ ([%split "a(c)" / pcre2 raw] "acbacbac");
-+ assert_equal
-+ [
-+ Delim "a";
-+ NoGroup;
-+ Text "b";
-+ Delim "ac";
-+ Group (1, "c");
-+ Text "b";
-+ Delim "a";
-+ NoGroup;
-+ ]
-+ ([%split "a(c)?" / pcre2 raw] "abacba");
-+ assert_equal
-+ [ Text "ab"; Delim "x"; Group (1, "x"); NoGroup; Text "cd" ]
-+ ([%split {|(x)|(u)|} / raw pcre2] "abxcd");
-+ assert_equal
-+ [
-+ Text "ab";
-+ Delim "x";
-+ Group (1, "x");
-+ NoGroup;
-+ Text "cd";
-+ Delim "u";
-+ NoGroup;
-+ Group (2, "u");
-+ ]
-+ ([%split {|(x)|(u)|} / raw pcre2] "abxcdu")
-+
-+let test_pcre2_string_pattern ctxt =
-+ ();
-+ assert_equal "$b"
-+ ([%pattern {|$$$1|} / pcre2] ([%match "a(b)c" / exc pcre2 raw] "abc"));
-+ assert_equal "b"
-+ ([%pattern {|${01}|} / pcre2] ([%match "a(b)c" / exc pcre2 raw] "abc"));
-+ assert_equal "bx"
-+ (let s = "x" in
-+ [%pattern {|${01}${s}|} / pcre2] ([%match "a(b)c" / exc pcre2 raw] "abc"));
-+ assert_equal {|"bx|}
-+ (let s = "x" in
-+ [%pattern {|"${01}${s}|} / pcre2] ([%match "a(b)c" / exc pcre2 raw] "abc"));
-+ assert_equal {|"x|}
-+ (let s = "x" in
-+ [%pattern {|"${s}|} / pcre2])
-+
-+let test_pcre2_expr_pattern ctxt =
-+ ();
-+ assert_equal "abc"
-+ ([%pattern "$0$" / e pcre2] ([%match "abc" / exc pcre2 raw] "abc"));
-+ assert_equal "abcx"
-+ ([%pattern {|$0$ ^ "x"|} / e pcre2] ([%match "abc" / exc pcre2 raw] "abc"));
-+ assert_equal "abcx"
-+ (let x = "x" in
-+ [%pattern {|$0$ ^ x|} / e pcre2] ([%match "abc" / exc pcre2 raw] "abc"));
-+ assert_equal "x"
-+ (let x = "x" in
-+ [%pattern {|"" ^ x|} / e pcre2])
-+
-+let test_pcre2_subst ctxt =
-+ ();
-+ assert_equal "$b" ([%subst "a(b)c" / {|$$$1|} / pcre2] "abc");
-+ assert_equal "$b" ([%subst "A(B)C" / {|$$$1|} / i pcre2] "abc");
-+ assert_equal "$babc" ([%subst "A(B)C" / {|$$$1|} / i pcre2] "abcabc");
-+ assert_equal "$b$b" ([%subst "A(B)C" / {|$$$1|} / g i pcre2] "abcabc");
-+ assert_equal "$b$b" ([%subst "A(B)C" / {|"$" ^ $1$|} / e g i pcre2] "abcabc");
-+ assert_equal "$$" ([%subst "A(B)C" / {|"$"|} / e g i pcre2] "abcabc");
-+ assert_equal "$$" ([%subst "A(B)C" / {|$$|} / g i pcre2] "abcabc")
-+
-+let test_pcre2_ocamlfind_bits ctxt =
-+ ();
-+ assert_equal ~printer:show_string_option (Some "-syntax camlp5o ")
-+ (snd
-+ ([%match {|^\(\*\*pp (.*?)\*\)|} / exc strings pcre2]
-+ {|(**pp -syntax camlp5o *)
-+|}))
-+
-+let pcre2_envsubst envlookup s =
-+ let f s1 s2 =
-+ if s1 <> "" then envlookup s1
-+ else if s2 <> "" then envlookup s2
-+ else assert false
-+ in
-+
-+ [%subst {|(?:\$\(([^)]+)\)|\$\{([^}]+)\})|} / {| f $1$ $2$ |} / g e pcre2] s
-+
-+let test_pcre2_envsubst_via_replace ctxt =
-+ let f = function
-+ | "A" -> "res1"
-+ | "B" -> "res2"
-+ | _ -> failwith "unexpected arg in envsubst"
-+ in
-+ assert_equal "...res1...res2..." (pcre2_envsubst f {|...$(A)...${B}...|})
-+
-+let suite =
-+ "Test pa_ppx_regexp"
-+ >::: [
-+ "pcre2 simple_match" >:: test_pcre2_simple_match;
-+ "pcre2 selective_match" >:: test_pcre2_selective_match;
-+ "pcre2 search" >:: test_pcre2_search;
-+ "pcre2 single" >:: test_pcre2_single;
-+ "pcre2 multiline" >:: test_pcre2_multiline;
-+ "pcre2 simple_split" >:: test_pcre2_simple_split;
-+ "pcre2 delim_split raw" >:: test_pcre2_delim_split_raw;
-+ "pcre2 string_pattern" >:: test_pcre2_string_pattern;
-+ "pcre2 expr_pattern" >:: test_pcre2_expr_pattern;
-+ "pcre2 subst" >:: test_pcre2_subst;
-+ "pcre2 ocamlfind bits" >:: test_pcre2_ocamlfind_bits;
-+ "pcre2 envsubst via replace" >:: test_pcre2_envsubst_via_replace;
-+ "pcre only_regexps" >:: test_special_char_regexps;
-+ ]
-+
-+let _ = if not !Sys.interactive then run_test_tt_main suite else ()
-diff --git a/bundles/pcre2/pcre2-ocaml/pcre2.opam b/bundles/pcre2/pcre2-ocaml/pcre2.opam
-new file mode 100644
-index 000000000..f191fcd4d
---- /dev/null
-+++ b/bundles/pcre2/pcre2-ocaml/pcre2.opam
-@@ -0,0 +1,37 @@
-+# This file is generated by dune, edit dune-project instead
-+opam-version: "2.0"
-+version: "8.0.4"
-+synopsis:
-+ "Bindings to the Perl Compatibility Regular Expressions library (version 2)"
-+description: """
-+pcre2-ocaml offers library functions for string pattern matching and
-+substitution, similar to the functionality offered by the Perl language."""
-+maintainer: ["Chet Murthy <chetsky@gmail.com>"]
-+authors: ["Markus Mottl <markus.mottl@gmail.com>"]
-+license: "LGPL-2.1-or-later WITH OCaml-LGPL-linking-exception"
-+homepage: "https://github.com/camlp5/pcre2-ocaml"
-+bug-reports: "https://github.com/camlp5/pcre2-ocaml/issues"
-+depends: [
-+ "dune" {>= "2.7"}
-+ "ocaml" {>= "4.08"}
-+ "dune-compiledb"
-+ "dune-configurator"
-+ "conf-libpcre2-8" {build}
-+ "ounit2" {with-test}
-+ "odoc" {with-doc}
-+]
-+build: [
-+ ["dune" "subst"] {dev}
-+ [
-+ "dune"
-+ "build"
-+ "-p"
-+ name
-+ "-j"
-+ jobs
-+ "@install"
-+ "@runtest" {with-test}
-+ "@doc" {with-doc}
-+ ]
-+]
-+dev-repo: "git+https://github.com/camlp5/pcre2-ocaml.git"
-diff --git a/bundles/pcre2/pcre2-ocaml/test/dune b/bundles/pcre2/pcre2-ocaml/test/dune
-new file mode 100644
-index 000000000..af6fcfa5f
---- /dev/null
-+++ b/bundles/pcre2/pcre2-ocaml/test/dune
-@@ -0,0 +1,14 @@
-+(test
-+ (name old_pcre2_tests)
-+ (modules Old_pcre2_tests)
-+ (libraries pcre2 ounit2))
-+
-+(test
-+ (name pcre2_tests)
-+ (modules Pcre2_tests)
-+ (libraries pcre2 ounit2))
-+
-+(env
-+ (dev
-+ (flags
-+ (:standard -w -27))))
-diff --git a/bundles/pcre2/pcre2-ocaml/test/old_pcre2_tests.ml b/bundles/pcre2/pcre2-ocaml/test/old_pcre2_tests.ml
-new file mode 100644
-index 000000000..e1f21e438
---- /dev/null
-+++ b/bundles/pcre2/pcre2-ocaml/test/old_pcre2_tests.ml
-@@ -0,0 +1,24 @@
-+open OUnit2
-+open Pcre2
-+
-+let simple_test ctxt =
-+ assert_equal 0 0;
-+ assert_equal
-+ [ Text "ab"; Delim "x"; Group (1, "x"); NoGroup; Text "cd" ]
-+ (full_split ~pat:"(x)|(u)" "abxcd");
-+ assert_equal
-+ [
-+ Text "ab";
-+ Delim "x";
-+ Group (1, "x");
-+ NoGroup;
-+ Text "cd";
-+ Delim "u";
-+ NoGroup;
-+ Group (2, "u");
-+ Text "ef";
-+ ]
-+ (full_split ~pat:"(x)|(u)" "abxcduef")
-+
-+let suite = "Test pcre" >::: [ "simple_test" >:: simple_test ]
-+let _ = if not !Sys.interactive then run_test_tt_main suite else ()
-diff --git a/bundles/pcre2/pcre2-ocaml/test/pcre2_tests.ml b/bundles/pcre2/pcre2-ocaml/test/pcre2_tests.ml
-new file mode 100644
-index 000000000..fe600881a
---- /dev/null
-+++ b/bundles/pcre2/pcre2-ocaml/test/pcre2_tests.ml
-@@ -0,0 +1,746 @@
-+open OUnit2
-+(**pp -syntax camlp5o -package pa_ppx.deriving_plugins.std *)
-+
-+let test_special_char_regexps ctxt =
-+ ();
-+ assert_equal "\n"
-+ ((let __re__ = Pcre2.regexp ~flags:[ `DOTALL ] "\\n$" in
-+ fun __subj__ ->
-+ (fun __g__ -> Pcre2.get_substring __g__ 0)
-+ (Pcre2.exec ~rex:__re__ __subj__))
-+ "\n");
-+ assert_equal ""
-+ (Pcre2.substitute_substrings_first
-+ ~rex:(Pcre2.regexp ~flags:[ `DOTALL ] "\\n+$")
-+ ~subst:(fun __g__ -> String.concat "" [])
-+ "\n\n")
-+
-+let test_pcre2_simple_match ctxt =
-+ ();
-+ assert_equal "abc"
-+ (Pcre2.get_substring
-+ ((let __re__ = Pcre2.regexp ~flags:[] "abc" in
-+ fun __subj__ -> Pcre2.exec ~rex:__re__ __subj__)
-+ "abc")
-+ 0);
-+ assert_equal (Some "abc")
-+ ((let __re__ = Pcre2.regexp ~flags:[] "abc" in
-+ fun __subj__ ->
-+ match
-+ Option.map
-+ (fun __g__ -> Pcre2.get_substring __g__ 0)
-+ (try Some (Pcre2.exec ~rex:__re__ __subj__) with Not_found -> None)
-+ with
-+ | exception Not_found -> None
-+ | rv -> rv)
-+ "abc");
-+ assert_equal (Some "abc")
-+ ((let __re__ = Pcre2.regexp ~flags:[] "abc" in
-+ fun __subj__ ->
-+ match
-+ Option.map
-+ (fun __g__ -> Pcre2.get_substring __g__ 0)
-+ (try Some (Pcre2.exec ~rex:__re__ __subj__) with Not_found -> None)
-+ with
-+ | exception Not_found -> None
-+ | rv -> rv)
-+ "abc");
-+ assert_equal true
-+ ((let __re__ = Pcre2.regexp ~flags:[] "abc" in
-+ fun __subj__ -> Pcre2.pmatch ~rex:__re__ __subj__)
-+ "abc");
-+ assert_equal false
-+ ((let __re__ = Pcre2.regexp ~flags:[] "abc" in
-+ fun __subj__ -> Pcre2.pmatch ~rex:__re__ __subj__)
-+ "abd");
-+ assert_equal None
-+ ((let __re__ = Pcre2.regexp ~flags:[] "abc" in
-+ fun __subj__ ->
-+ match
-+ Option.map
-+ (fun __g__ -> Pcre2.get_substring __g__ 0)
-+ (try Some (Pcre2.exec ~rex:__re__ __subj__) with Not_found -> None)
-+ with
-+ | exception Not_found -> None
-+ | rv -> rv)
-+ "abd");
-+ assert_raises Not_found (fun () ->
-+ (let __re__ = Pcre2.regexp ~flags:[] "abc" in
-+ fun __subj__ ->
-+ (fun __g__ -> Pcre2.get_substring __g__ 0)
-+ (Pcre2.exec ~rex:__re__ __subj__))
-+ "abd");
-+ assert_raises Not_found (fun () ->
-+ (let __re__ = Pcre2.regexp ~flags:[] "abc" in
-+ fun __subj__ ->
-+ (fun __g__ -> Pcre2.get_substring __g__ 0)
-+ (Pcre2.exec ~rex:__re__ __subj__))
-+ "abd");
-+ assert_equal None
-+ ((let __re__ = Pcre2.regexp ~flags:[] "abc" in
-+ fun __subj__ ->
-+ match
-+ Option.map
-+ (fun __g__ -> Pcre2.get_substring __g__ 0)
-+ (try Some (Pcre2.exec ~rex:__re__ __subj__) with Not_found -> None)
-+ with
-+ | exception Not_found -> None
-+ | rv -> rv)
-+ "abd");
-+ assert_equal "abc"
-+ ((let __re__ = Pcre2.regexp ~flags:[] "abc" in
-+ fun __subj__ ->
-+ (fun __g__ -> Pcre2.get_substring __g__ 0)
-+ (Pcre2.exec ~rex:__re__ __subj__))
-+ "abc");
-+ assert_equal ("abc", Some "b")
-+ ((let __re__ = Pcre2.regexp ~flags:[] "a(b)c" in
-+ fun __subj__ ->
-+ (fun __g__ ->
-+ ( Pcre2.get_substring __g__ 0,
-+ try Some (Pcre2.get_substring __g__ 1) with Not_found -> None ))
-+ (Pcre2.exec ~rex:__re__ __subj__))
-+ "abc");
-+ assert_equal ("ac", None)
-+ ((let __re__ = Pcre2.regexp ~flags:[] "a(?:(b)?)c" in
-+ fun __subj__ ->
-+ (fun __g__ ->
-+ ( Pcre2.get_substring __g__ 0,
-+ try Some (Pcre2.get_substring __g__ 1) with Not_found -> None ))
-+ (Pcre2.exec ~rex:__re__ __subj__))
-+ "ac");
-+ assert_equal "abc"
-+ (Pcre2.get_substring
-+ ((let __re__ = Pcre2.regexp ~flags:[ `CASELESS ] "ABC" in
-+ fun __subj__ -> Pcre2.exec ~rex:__re__ __subj__)
-+ "abc")
-+ 0);
-+ assert_equal
-+ ("abc", Some "a", Some "b", Some "c")
-+ ((let __re__ = Pcre2.regexp ~flags:[] "(a)(b)(c)" in
-+ fun __subj__ ->
-+ (fun __g__ ->
-+ ( Pcre2.get_substring __g__ 0,
-+ (try Some (Pcre2.get_substring __g__ 1) with Not_found -> None),
-+ (try Some (Pcre2.get_substring __g__ 2) with Not_found -> None),
-+ try Some (Pcre2.get_substring __g__ 3) with Not_found -> None ))
-+ (Pcre2.exec ~rex:__re__ __subj__))
-+ "abc")
-+
-+let test_pcre2_selective_match ctxt =
-+ ();
-+ assert_equal ("abc", Some "b")
-+ ((let __re__ = Pcre2.regexp ~flags:[] "a(b)c" in
-+ fun __subj__ ->
-+ (fun __g__ ->
-+ ( Pcre2.get_substring __g__ 0,
-+ try Some (Pcre2.get_substring __g__ 1) with Not_found -> None ))
-+ (Pcre2.exec ~rex:__re__ __subj__))
-+ "abc");
-+ assert_equal ("abc", "b")
-+ ((let __re__ = Pcre2.regexp ~flags:[] "a(b)c" in
-+ fun __subj__ ->
-+ (fun __g__ ->
-+ (Pcre2.get_substring __g__ 0, Pcre2.get_substring __g__ 1))
-+ (Pcre2.exec ~rex:__re__ __subj__))
-+ "abc");
-+ assert_equal "b"
-+ ((let __re__ = Pcre2.regexp ~flags:[] "a(b)c" in
-+ fun __subj__ ->
-+ (fun __g__ -> Pcre2.get_substring __g__ 1)
-+ (Pcre2.exec ~rex:__re__ __subj__))
-+ "abc");
-+ assert_equal
-+ (Some ("abc", "b"))
-+ ((let __re__ = Pcre2.regexp ~flags:[] "a(b)c" in
-+ fun __subj__ ->
-+ match
-+ Option.map
-+ (fun __g__ ->
-+ (Pcre2.get_substring __g__ 0, Pcre2.get_substring __g__ 1))
-+ (try Some (Pcre2.exec ~rex:__re__ __subj__) with Not_found -> None)
-+ with
-+ | exception Not_found -> None
-+ | rv -> rv)
-+ "abc");
-+ assert_equal ("ac", None)
-+ ((let __re__ = Pcre2.regexp ~flags:[] "a(b)?c" in
-+ fun __subj__ ->
-+ (fun __g__ ->
-+ ( Pcre2.get_substring __g__ 0,
-+ try Some (Pcre2.get_substring __g__ 1) with Not_found -> None ))
-+ (Pcre2.exec ~rex:__re__ __subj__))
-+ "ac");
-+ assert_raises Not_found (fun _ ->
-+ (let __re__ = Pcre2.regexp ~flags:[] "a(b)?c" in
-+ fun __subj__ ->
-+ (fun __g__ ->
-+ (Pcre2.get_substring __g__ 0, Pcre2.get_substring __g__ 1))
-+ (Pcre2.exec ~rex:__re__ __subj__))
-+ "ac");
-+ assert_equal None
-+ ((let __re__ = Pcre2.regexp ~flags:[] "a(b)?c" in
-+ fun __subj__ ->
-+ match
-+ Option.map
-+ (fun __g__ ->
-+ (Pcre2.get_substring __g__ 0, Pcre2.get_substring __g__ 1))
-+ (try Some (Pcre2.exec ~rex:__re__ __subj__) with Not_found -> None)
-+ with
-+ | exception Not_found -> None
-+ | rv -> rv)
-+ "ac")
-+
-+let test_pcre2_search ctxt =
-+ ();
-+ assert_equal "abc"
-+ ((let __re__ = Pcre2.regexp ~flags:[] "abc" in
-+ fun __subj__ ->
-+ (fun __g__ -> Pcre2.get_substring __g__ 0)
-+ (Pcre2.exec ~rex:__re__ __subj__))
-+ "zzzabc");
-+ assert_equal None
-+ ((let __re__ = Pcre2.regexp ~flags:[] "^abc" in
-+ fun __subj__ ->
-+ match
-+ Option.map
-+ (fun __g__ -> Pcre2.get_substring __g__ 0)
-+ (try Some (Pcre2.exec ~rex:__re__ __subj__) with Not_found -> None)
-+ with
-+ | exception Not_found -> None
-+ | rv -> rv)
-+ "zzzabc")
-+
-+let show_string_option = function
-+ | None -> "None"
-+ | Some s -> Printf.sprintf "Some %s" s
-+
-+let test_pcre2_single ctxt =
-+ let printer = show_string_option in
-+ ();
-+ assert_equal ~printer None
-+ ((let __re__ = Pcre2.regexp ~flags:[] ".+" in
-+ fun __subj__ ->
-+ match
-+ Option.map
-+ (fun __g__ -> Pcre2.get_substring __g__ 0)
-+ (try Some (Pcre2.exec ~rex:__re__ __subj__) with Not_found -> None)
-+ with
-+ | exception Not_found -> None
-+ | rv -> rv)
-+ "\n\n");
-+ assert_equal ~printer None
-+ ((let __re__ = Pcre2.regexp ~flags:[ `MULTILINE ] ".+" in
-+ fun __subj__ ->
-+ match
-+ Option.map
-+ (fun __g__ -> Pcre2.get_substring __g__ 0)
-+ (try Some (Pcre2.exec ~rex:__re__ __subj__) with Not_found -> None)
-+ with
-+ | exception Not_found -> None
-+ | rv -> rv)
-+ "\n\n");
-+ assert_equal ~printer None
-+ ((let __re__ = Pcre2.regexp ~flags:[] ".+" in
-+ fun __subj__ ->
-+ match
-+ Option.map
-+ (fun __g__ -> Pcre2.get_substring __g__ 0)
-+ (try Some (Pcre2.exec ~rex:__re__ __subj__) with Not_found -> None)
-+ with
-+ | exception Not_found -> None
-+ | rv -> rv)
-+ "\n\n");
-+ assert_equal ~printer (Some "\n\n")
-+ ((let __re__ = Pcre2.regexp ~flags:[ `DOTALL ] ".+" in
-+ fun __subj__ ->
-+ match
-+ Option.map
-+ (fun __g__ -> Pcre2.get_substring __g__ 0)
-+ (try Some (Pcre2.exec ~rex:__re__ __subj__) with Not_found -> None)
-+ with
-+ | exception Not_found -> None
-+ | rv -> rv)
-+ "\n\n");
-+ assert_equal ~printer None
-+ ((let __re__ = Pcre2.regexp ~flags:[ `MULTILINE ] ".+" in
-+ fun __subj__ ->
-+ match
-+ Option.map
-+ (fun __g__ -> Pcre2.get_substring __g__ 0)
-+ (try Some (Pcre2.exec ~rex:__re__ __subj__) with Not_found -> None)
-+ with
-+ | exception Not_found -> None
-+ | rv -> rv)
-+ "\n\n");
-+ let printer x = x in
-+ ();
-+ assert_equal ~printer "\n\n"
-+ ((let __re__ = Pcre2.regexp ~flags:[ `DOTALL ] ".+" in
-+ fun __subj__ ->
-+ (fun __g__ -> Pcre2.get_substring __g__ 0)
-+ (Pcre2.exec ~rex:__re__ __subj__))
-+ "\n\n");
-+ assert_equal ~printer "<<abc>>\ndef"
-+ (Pcre2.substitute_substrings_first
-+ ~rex:(Pcre2.regexp ~flags:[] ".+")
-+ ~subst:(fun __g__ ->
-+ String.concat ""
-+ [
-+ "<<";
-+ (match Pcre2.get_substring __g__ 0 with
-+ | exception Not_found -> ""
-+ | s -> s);
-+ ">>";
-+ ])
-+ "abc\ndef");
-+ assert_equal ~printer "<<abc\ndef>>"
-+ (Pcre2.substitute_substrings_first
-+ ~rex:(Pcre2.regexp ~flags:[ `DOTALL ] ".+")
-+ ~subst:(fun __g__ ->
-+ String.concat ""
-+ [
-+ "<<";
-+ (match Pcre2.get_substring __g__ 0 with
-+ | exception Not_found -> ""
-+ | s -> s);
-+ ">>";
-+ ])
-+ "abc\ndef");
-+ assert_equal ~printer "<<abc>>\ndef"
-+ (Pcre2.substitute_substrings_first
-+ ~rex:(Pcre2.regexp ~flags:[ `MULTILINE ] ".+")
-+ ~subst:(fun __g__ ->
-+ String.concat ""
-+ [
-+ "<<";
-+ (match Pcre2.get_substring __g__ 0 with
-+ | exception Not_found -> ""
-+ | s -> s);
-+ ">>";
-+ ])
-+ "abc\ndef");
-+ assert_equal ~printer "<<abc>>\ndef"
-+ (Pcre2.substitute_substrings_first
-+ ~rex:(Pcre2.regexp ~flags:[] ".*")
-+ ~subst:(fun __g__ ->
-+ String.concat ""
-+ [
-+ "<<";
-+ (match Pcre2.get_substring __g__ 0 with
-+ | exception Not_found -> ""
-+ | s -> s);
-+ ">>";
-+ ])
-+ "abc\ndef");
-+ assert_equal ~printer "<<abc>><<>>\n<<def>><<>>"
-+ (Pcre2.substitute_substrings
-+ ~rex:(Pcre2.regexp ~flags:[] ".*")
-+ ~subst:(fun __g__ ->
-+ String.concat ""
-+ [
-+ "<<";
-+ (match Pcre2.get_substring __g__ 0 with
-+ | exception Not_found -> ""
-+ | s -> s);
-+ ">>";
-+ ])
-+ "abc\ndef");
-+ assert_equal ~printer "<<abc>>\n<<def>>"
-+ (Pcre2.substitute_substrings
-+ ~rex:(Pcre2.regexp ~flags:[] ".+")
-+ ~subst:(fun __g__ ->
-+ String.concat ""
-+ [
-+ "<<";
-+ (match Pcre2.get_substring __g__ 0 with
-+ | exception Not_found -> ""
-+ | s -> s);
-+ ">>";
-+ ])
-+ "abc\ndef");
-+ assert_equal ~printer "<<abc>>a\nc<<aec>>"
-+ (Pcre2.substitute_substrings
-+ ~rex:(Pcre2.regexp ~flags:[] "a.c")
-+ ~subst:(fun __g__ ->
-+ String.concat ""
-+ [
-+ "<<";
-+ (match Pcre2.get_substring __g__ 0 with
-+ | exception Not_found -> ""
-+ | s -> s);
-+ ">>";
-+ ])
-+ "abca\ncaec");
-+ assert_equal ~printer "<<abc>><<a\nc>><<aec>>"
-+ (Pcre2.substitute_substrings
-+ ~rex:(Pcre2.regexp ~flags:[ `DOTALL ] "a.c")
-+ ~subst:(fun __g__ ->
-+ String.concat ""
-+ [
-+ "<<";
-+ (match Pcre2.get_substring __g__ 0 with
-+ | exception Not_found -> ""
-+ | s -> s);
-+ ">>";
-+ ])
-+ "abca\ncaec")
-+
-+let test_pcre2_multiline ctxt =
-+ ();
-+ assert_equal (Some "bar")
-+ ((let __re__ = Pcre2.regexp ~flags:[] ".+$" in
-+ fun __subj__ ->
-+ match
-+ Option.map
-+ (fun __g__ -> Pcre2.get_substring __g__ 0)
-+ (try Some (Pcre2.exec ~rex:__re__ __subj__) with Not_found -> None)
-+ with
-+ | exception Not_found -> None
-+ | rv -> rv)
-+ "foo\nbar");
-+ assert_equal (Some "foo")
-+ ((let __re__ = Pcre2.regexp ~flags:[ `MULTILINE ] ".+$" in
-+ fun __subj__ ->
-+ match
-+ Option.map
-+ (fun __g__ -> Pcre2.get_substring __g__ 0)
-+ (try Some (Pcre2.exec ~rex:__re__ __subj__) with Not_found -> None)
-+ with
-+ | exception Not_found -> None
-+ | rv -> rv)
-+ "foo\nbar")
-+
-+let test_pcre2_simple_split ctxt =
-+ ();
-+ assert_equal [ "bb" ]
-+ ((let __re__ = Pcre2.regexp ~flags:[] "a" in
-+ fun __subj__ -> Pcre2.split ~rex:__re__ __subj__)
-+ "bb")
-+
-+let test_pcre2_delim_split_raw ctxt =
-+ let open Pcre2 in
-+ ();
-+ assert_equal
-+ [ Delim "a"; Text "b"; Delim "a"; Text "b" ]
-+ ((let __re__ = Pcre2.regexp ~flags:[] "a" in
-+ fun __subj__ -> Pcre2.full_split ~rex:__re__ __subj__)
-+ "ababa");
-+ assert_equal
-+ [ Delim "a"; Text "b"; Delim "a"; Delim "a"; Text "b" ]
-+ ((let __re__ = Pcre2.regexp ~flags:[] "a" in
-+ fun __subj__ -> Pcre2.full_split ~rex:__re__ __subj__)
-+ "abaaba");
-+ assert_equal
-+ [
-+ Delim "a";
-+ NoGroup;
-+ Text "b";
-+ Delim "ac";
-+ Group (1, "c");
-+ Text "b";
-+ Delim "a";
-+ NoGroup;
-+ ]
-+ ((let __re__ = Pcre2.regexp ~flags:[] "a(c)?" in
-+ fun __subj__ -> Pcre2.full_split ~rex:__re__ __subj__)
-+ "abacba");
-+ assert_equal
-+ [
-+ Delim "ac";
-+ Group (1, "c");
-+ Text "b";
-+ Delim "ac";
-+ Group (1, "c");
-+ Text "b";
-+ Delim "ac";
-+ Group (1, "c");
-+ ]
-+ ((let __re__ = Pcre2.regexp ~flags:[] "a(c)" in
-+ fun __subj__ -> Pcre2.full_split ~rex:__re__ __subj__)
-+ "acbacbac");
-+ assert_equal
-+ [
-+ Delim "ac";
-+ Group (1, "c");
-+ Text "b";
-+ Delim "ac";
-+ Group (1, "c");
-+ Text "b";
-+ Delim "ac";
-+ Group (1, "c");
-+ ]
-+ ((let __re__ = Pcre2.regexp ~flags:[] "a(c)" in
-+ fun __subj__ -> Pcre2.full_split ~rex:__re__ __subj__)
-+ "acbacbac");
-+ assert_equal
-+ [
-+ Delim "a";
-+ NoGroup;
-+ Text "b";
-+ Delim "ac";
-+ Group (1, "c");
-+ Text "b";
-+ Delim "a";
-+ NoGroup;
-+ ]
-+ ((let __re__ = Pcre2.regexp ~flags:[] "a(c)?" in
-+ fun __subj__ -> Pcre2.full_split ~rex:__re__ __subj__)
-+ "abacba");
-+ assert_equal
-+ [ Text "ab"; Delim "x"; Group (1, "x"); NoGroup; Text "cd" ]
-+ ((let __re__ = Pcre2.regexp ~flags:[] "(x)|(u)" in
-+ fun __subj__ -> Pcre2.full_split ~rex:__re__ __subj__)
-+ "abxcd");
-+ assert_equal
-+ [
-+ Text "ab";
-+ Delim "x";
-+ Group (1, "x");
-+ NoGroup;
-+ Text "cd";
-+ Delim "u";
-+ NoGroup;
-+ Group (2, "u");
-+ ]
-+ ((let __re__ = Pcre2.regexp ~flags:[] "(x)|(u)" in
-+ fun __subj__ -> Pcre2.full_split ~rex:__re__ __subj__)
-+ "abxcdu")
-+
-+let test_pcre2_string_pattern ctxt =
-+ ();
-+ assert_equal "$b"
-+ ((fun __g__ ->
-+ String.concat ""
-+ [
-+ "$";
-+ "";
-+ (match Pcre2.get_substring __g__ 1 with
-+ | exception Not_found -> ""
-+ | s -> s);
-+ ])
-+ ((let __re__ = Pcre2.regexp ~flags:[] "a(b)c" in
-+ fun __subj__ -> Pcre2.exec ~rex:__re__ __subj__)
-+ "abc"));
-+ assert_equal "b"
-+ ((fun __g__ ->
-+ String.concat ""
-+ [
-+ (match Pcre2.get_substring __g__ 01 with
-+ | exception Not_found -> ""
-+ | s -> s);
-+ ])
-+ ((let __re__ = Pcre2.regexp ~flags:[] "a(b)c" in
-+ fun __subj__ -> Pcre2.exec ~rex:__re__ __subj__)
-+ "abc"));
-+ assert_equal "bx"
-+ (let s = "x" in
-+ (fun __g__ ->
-+ String.concat ""
-+ [
-+ (match Pcre2.get_substring __g__ 01 with
-+ | exception Not_found -> ""
-+ | s -> s);
-+ "";
-+ s;
-+ ])
-+ ((let __re__ = Pcre2.regexp ~flags:[] "a(b)c" in
-+ fun __subj__ -> Pcre2.exec ~rex:__re__ __subj__)
-+ "abc"));
-+ assert_equal "\"bx"
-+ (let s = "x" in
-+ (fun __g__ ->
-+ String.concat ""
-+ [
-+ "\"";
-+ (match Pcre2.get_substring __g__ 01 with
-+ | exception Not_found -> ""
-+ | s -> s);
-+ "";
-+ s;
-+ ])
-+ ((let __re__ = Pcre2.regexp ~flags:[] "a(b)c" in
-+ fun __subj__ -> Pcre2.exec ~rex:__re__ __subj__)
-+ "abc"));
-+ assert_equal "\"x"
-+ (let s = "x" in
-+ String.concat "" [ "\""; s ])
-+
-+let test_pcre2_expr_pattern ctxt =
-+ ();
-+ assert_equal "abc"
-+ ((fun __g__ ->
-+ match Pcre2.get_substring __g__ 0 with
-+ | exception Not_found -> ""
-+ | s -> s)
-+ ((let __re__ = Pcre2.regexp ~flags:[] "abc" in
-+ fun __subj__ -> Pcre2.exec ~rex:__re__ __subj__)
-+ "abc"));
-+ assert_equal "abcx"
-+ ((fun __g__ ->
-+ (match Pcre2.get_substring __g__ 0 with
-+ | exception Not_found -> ""
-+ | s -> s)
-+ ^ "x")
-+ ((let __re__ = Pcre2.regexp ~flags:[] "abc" in
-+ fun __subj__ -> Pcre2.exec ~rex:__re__ __subj__)
-+ "abc"));
-+ assert_equal "abcx"
-+ (let x = "x" in
-+ (fun __g__ ->
-+ (match Pcre2.get_substring __g__ 0 with
-+ | exception Not_found -> ""
-+ | s -> s)
-+ ^ x)
-+ ((let __re__ = Pcre2.regexp ~flags:[] "abc" in
-+ fun __subj__ -> Pcre2.exec ~rex:__re__ __subj__)
-+ "abc"));
-+ assert_equal "x"
-+ (let x = "x" in
-+ "" ^ x)
-+
-+let test_pcre2_subst ctxt =
-+ ();
-+ assert_equal "$b"
-+ (Pcre2.substitute_substrings_first
-+ ~rex:(Pcre2.regexp ~flags:[] "a(b)c")
-+ ~subst:(fun __g__ ->
-+ String.concat ""
-+ [
-+ "$";
-+ "";
-+ (match Pcre2.get_substring __g__ 1 with
-+ | exception Not_found -> ""
-+ | s -> s);
-+ ])
-+ "abc");
-+ assert_equal "$b"
-+ (Pcre2.substitute_substrings_first
-+ ~rex:(Pcre2.regexp ~flags:[ `CASELESS ] "A(B)C")
-+ ~subst:(fun __g__ ->
-+ String.concat ""
-+ [
-+ "$";
-+ "";
-+ (match Pcre2.get_substring __g__ 1 with
-+ | exception Not_found -> ""
-+ | s -> s);
-+ ])
-+ "abc");
-+ assert_equal "$babc"
-+ (Pcre2.substitute_substrings_first
-+ ~rex:(Pcre2.regexp ~flags:[ `CASELESS ] "A(B)C")
-+ ~subst:(fun __g__ ->
-+ String.concat ""
-+ [
-+ "$";
-+ "";
-+ (match Pcre2.get_substring __g__ 1 with
-+ | exception Not_found -> ""
-+ | s -> s);
-+ ])
-+ "abcabc");
-+ assert_equal "$b$b"
-+ (Pcre2.substitute_substrings
-+ ~rex:(Pcre2.regexp ~flags:[ `CASELESS ] "A(B)C")
-+ ~subst:(fun __g__ ->
-+ String.concat ""
-+ [
-+ "$";
-+ "";
-+ (match Pcre2.get_substring __g__ 1 with
-+ | exception Not_found -> ""
-+ | s -> s);
-+ ])
-+ "abcabc");
-+ assert_equal "$b$b"
-+ (Pcre2.substitute_substrings
-+ ~rex:(Pcre2.regexp ~flags:[ `CASELESS ] "A(B)C")
-+ ~subst:(fun __g__ ->
-+ "$"
-+ ^
-+ match Pcre2.get_substring __g__ 1 with
-+ | exception Not_found -> ""
-+ | s -> s)
-+ "abcabc");
-+ assert_equal "$$"
-+ (Pcre2.substitute_substrings
-+ ~rex:(Pcre2.regexp ~flags:[ `CASELESS ] "A(B)C")
-+ ~subst:(fun __g__ -> "$")
-+ "abcabc");
-+ assert_equal "$$"
-+ (Pcre2.substitute_substrings
-+ ~rex:(Pcre2.regexp ~flags:[ `CASELESS ] "A(B)C")
-+ ~subst:(fun __g__ -> String.concat "" [ "$" ])
-+ "abcabc")
-+
-+let test_pcre2_ocamlfind_bits ctxt =
-+ ();
-+ assert_equal ~printer:show_string_option (Some "-syntax camlp5o ")
-+ (snd
-+ ((let __re__ = Pcre2.regexp ~flags:[] "^\\(\\*\\*pp (.*?)\\*\\)" in
-+ fun __subj__ ->
-+ (fun __g__ ->
-+ ( Pcre2.get_substring __g__ 0,
-+ try Some (Pcre2.get_substring __g__ 1) with Not_found -> None ))
-+ (Pcre2.exec ~rex:__re__ __subj__))
-+ "(**pp -syntax camlp5o *)\n"))
-+
-+let pcre2_envsubst envlookup s =
-+ let f s1 s2 =
-+ if s1 <> "" then envlookup s1
-+ else if s2 <> "" then envlookup s2
-+ else assert false
-+ in
-+ Pcre2.substitute_substrings
-+ ~rex:(Pcre2.regexp ~flags:[] "(?:\\$\\(([^)]+)\\)|\\$\\{([^}]+)\\})")
-+ ~subst:(fun __g__ ->
-+ f
-+ (match Pcre2.get_substring __g__ 1 with
-+ | exception Not_found -> ""
-+ | s -> s)
-+ (match Pcre2.get_substring __g__ 2 with
-+ | exception Not_found -> ""
-+ | s -> s))
-+ s
-+
-+let test_pcre2_envsubst_via_replace ctxt =
-+ let f = function
-+ | "A" -> "res1"
-+ | "B" -> "res2"
-+ | _ -> failwith "unexpected arg in envsubst"
-+ in
-+ assert_equal "...res1...res2..." (pcre2_envsubst f "...$(A)...${B}...")
-+
-+let bad_pattern ctxt =
-+ let open Pcre2 in
-+ try
-+ ignore (regexp "?");
-+ assert_failure "Regex should fail to parse"
-+ with Error (BadPattern (s, _)) ->
-+ assert_bool
-+ "String contains a zero byte. In 8-bit mode this indicates an error in \
-+ the creation of the error message since strings created by PCRE2 should \
-+ be null terminated."
-+ (not @@ String.exists (fun c -> c = '\000') s)
-+
-+let suite =
-+ "Test pa_ppx_regexp"
-+ >::: [
-+ "pcre2 simple_match" >:: test_pcre2_simple_match;
-+ "pcre2 selective_match" >:: test_pcre2_selective_match;
-+ "pcre2 search" >:: test_pcre2_search;
-+ "pcre2 single" >:: test_pcre2_single;
-+ "pcre2 multiline" >:: test_pcre2_multiline;
-+ "pcre2 simple_split" >:: test_pcre2_simple_split;
-+ "pcre2 delim_split raw" >:: test_pcre2_delim_split_raw;
-+ "pcre2 string_pattern" >:: test_pcre2_string_pattern;
-+ "pcre2 expr_pattern" >:: test_pcre2_expr_pattern;
-+ "pcre2 subst" >:: test_pcre2_subst;
-+ "pcre2 ocamlfind bits" >:: test_pcre2_ocamlfind_bits;
-+ "pcre2 envsubst via replace" >:: test_pcre2_envsubst_via_replace;
-+ "pcre only_regexps" >:: test_special_char_regexps;
-+ "bad_pattern" >:: bad_pattern;
-+ ]
-+
-+let _ = if not !Sys.interactive then run_test_tt_main suite
---
-2.52.0
-
diff --git a/0005-rename-some-bundled-pcre2-files-to-be-input-files.patch b/0005-rename-some-bundled-pcre2-files-to-be-input-files.patch
deleted file mode 100644
index fe449c8..0000000
--- a/0005-rename-some-bundled-pcre2-files-to-be-input-files.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From ba09b5d2c8c71ba64ac520367401c58555b48190 Mon Sep 17 00:00:00 2001
-From: Victor Gambier <victor.gambier@inria.fr>
-Date: Wed, 14 Jan 2026 11:34:57 +0100
-Subject: [PATCH 5/9] rename some bundled pcre2 files to be input files
-
-(cherry picked from commit a616d0a2498da843d4cde33eea81ec9967689363)
----
- bundles/pcre2/pcre2-ocaml/lib/{pcre2.ml => pcre2.ml.in} | 0
- bundles/pcre2/pcre2-ocaml/lib/{pcre2_stubs.c => pcre2_stubs.c.in} | 0
- 2 files changed, 0 insertions(+), 0 deletions(-)
- rename bundles/pcre2/pcre2-ocaml/lib/{pcre2.ml => pcre2.ml.in} (100%)
- rename bundles/pcre2/pcre2-ocaml/lib/{pcre2_stubs.c => pcre2_stubs.c.in} (100%)
-
-diff --git a/bundles/pcre2/pcre2-ocaml/lib/pcre2.ml b/bundles/pcre2/pcre2-ocaml/lib/pcre2.ml.in
-similarity index 100%
-rename from bundles/pcre2/pcre2-ocaml/lib/pcre2.ml
-rename to bundles/pcre2/pcre2-ocaml/lib/pcre2.ml.in
-diff --git a/bundles/pcre2/pcre2-ocaml/lib/pcre2_stubs.c b/bundles/pcre2/pcre2-ocaml/lib/pcre2_stubs.c.in
-similarity index 100%
-rename from bundles/pcre2/pcre2-ocaml/lib/pcre2_stubs.c
-rename to bundles/pcre2/pcre2-ocaml/lib/pcre2_stubs.c.in
---
-2.52.0
-
diff --git a/0006-add-.gitignore-in-pcre2-bundle-to-exclude-generated-.patch b/0006-add-.gitignore-in-pcre2-bundle-to-exclude-generated-.patch
deleted file mode 100644
index 8149a3b..0000000
--- a/0006-add-.gitignore-in-pcre2-bundle-to-exclude-generated-.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From 2e34e86bda23cabd7d278a2aae1f420da44aa50e Mon Sep 17 00:00:00 2001
-From: Victor Gambier <victor.gambier@inria.fr>
-Date: Wed, 14 Jan 2026 11:38:08 +0100
-Subject: [PATCH 6/9] add .gitignore in pcre2 bundle to exclude generated files
-
-(cherry picked from commit 0bb085307618652f79cc7a688a66d37d881b26ad)
----
- bundles/pcre2/.gitignore | 2 ++
- 1 file changed, 2 insertions(+)
- create mode 100644 bundles/pcre2/.gitignore
-
-diff --git a/bundles/pcre2/.gitignore b/bundles/pcre2/.gitignore
-new file mode 100644
-index 000000000..81438e117
---- /dev/null
-+++ b/bundles/pcre2/.gitignore
-@@ -0,0 +1,2 @@
-+pcre2-ocaml/lib/pcre2.ml
-+pcre2-ocaml/lib/pcre2_stubs.c
-\ No newline at end of file
---
-2.52.0
-
diff --git a/0007-rename-update-pcre-bundle-Makefile-to-reflect-bundle.patch b/0007-rename-update-pcre-bundle-Makefile-to-reflect-bundle.patch
deleted file mode 100644
index cf35ec5..0000000
--- a/0007-rename-update-pcre-bundle-Makefile-to-reflect-bundle.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From 2ea3e988228e8b27966fea07b718efffc7d82d5e Mon Sep 17 00:00:00 2001
-From: Victor Gambier <victor.gambier@inria.fr>
-Date: Wed, 14 Jan 2026 12:04:36 +0100
-Subject: [PATCH 7/9] rename/update pcre bundle Makefile to reflect bundle
- changes
-
-(cherry picked from commit cb87f4511db9321909c157aee9a68a52d9b6619c)
----
- bundles/{pcre => pcre2}/Makefile | 18 +++++++++---------
- 1 file changed, 9 insertions(+), 9 deletions(-)
- rename bundles/{pcre => pcre2}/Makefile (60%)
-
-diff --git a/bundles/pcre/Makefile b/bundles/pcre2/Makefile
-similarity index 60%
-rename from bundles/pcre/Makefile
-rename to bundles/pcre2/Makefile
-index 0db00b087..e1aed9865 100644
---- a/bundles/pcre/Makefile
-+++ b/bundles/pcre2/Makefile
-@@ -1,14 +1,14 @@
- # This Makefile serves as a wrapper to bundle the
--# pcre module without modifications.
-+# pcre2 module without modifications.
-
--MODULES=pcre
--OBJS=pcre
--INTERFACES=pcre
--C_OBJS=pcre
--ARCHIVE=pcre
--LIBRARY=pcre
--C_LIBS=pcre
--SRC_DIR=pcre-ocaml/src
-+MODULES=pcre2
-+OBJS=pcre2
-+INTERFACES=pcre2
-+C_OBJS=pcre2
-+ARCHIVE=pcre2
-+LIBRARY=pcre2
-+C_LIBS=pcre2-8
-+SRC_DIR=pcre2-ocaml/lib
-
- OCAMLFLAGS+=-I $(STDCOMPATDIR)
-
---
-2.52.0
-
diff --git a/0008-configure.ac-use-pcre2-ocaml-lib-folder-to-reflect-n.patch b/0008-configure.ac-use-pcre2-ocaml-lib-folder-to-reflect-n.patch
deleted file mode 100644
index c3cf2a0..0000000
--- a/0008-configure.ac-use-pcre2-ocaml-lib-folder-to-reflect-n.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From c82439140c22419d7eec30a94cc244e20d1fe41e Mon Sep 17 00:00:00 2001
-From: Victor Gambier <victor.gambier@inria.fr>
-Date: Tue, 20 Jan 2026 15:44:47 +0100
-Subject: [PATCH 8/9] configure.ac: use pcre2-ocaml/lib folder to reflect new
- bundle structure
-
-(cherry picked from commit b231de0db3f9513f6ea936caea5428fe627af1b9)
----
- configure.ac | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/configure.ac b/configure.ac
-index cd9005a87..aea7e35e0 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -594,8 +594,8 @@ AS_IF([test "$MAKE_pcre2"],
- AC_SUBST([noalloc], [[[@@noalloc]]])
- AC_SUBST([untagged], [[[@untagged]]])])
- AC_CONFIG_FILES([
-- bundles/pcre/pcre-ocaml/src/pcre.ml
-- bundles/pcre/pcre-ocaml/src/pcre_stubs.c
-+ bundles/pcre2/pcre2-ocaml/lib/pcre2.ml
-+ bundles/pcre2/pcre2-ocaml/lib/pcre2_stubs.c
- ])])
-
- dnl
---
-2.52.0
-
diff --git a/0009-replace-obsolescent-egrep-with-grep-E.patch b/0009-replace-obsolescent-egrep-with-grep-E.patch
deleted file mode 100644
index fdec4d1..0000000
--- a/0009-replace-obsolescent-egrep-with-grep-E.patch
+++ /dev/null
@@ -1,88 +0,0 @@
-From 18fc421c9af69d085e6e1c95e9d5cf36a2ba7011 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Christoph=20B=C3=B6hmwalder?=
- <christoph.boehmwalder@linbit.com>
-Date: Mon, 2 Mar 2026 16:44:10 +0100
-Subject: [PATCH 9/9] replace obsolescent egrep with grep -E
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-egrep has been deprecated since GNU grep 3.8 (Sep 2022) and prints a
-warning to stderr on every invocation. Replace all occurrences with
-the POSIX-standard grep -E.
-
-Signed-off-by: Christoph Böhmwalder <christoph.boehmwalder@linbit.com>
-(cherry picked from commit 233b5ceb1d5a701fb270ebdf0a9bd6be0a6ce53b)
----
- cocci.ml | 2 +-
- docs/manual/Makefile | 4 ++--
- parsing_cocci/patch_diff.ml | 4 ++--
- scripts/stat_directory_complete.pl | 2 +-
- 4 files changed, 6 insertions(+), 6 deletions(-)
-
-diff --git a/cocci.ml b/cocci.ml
-index 124156856..e769d5fe4 100644
---- a/cocci.ml
-+++ b/cocci.ml
-@@ -531,7 +531,7 @@ let worth_trying2 cfiles (tokens,_,query,_) =
-
- ) in
- let com =
-- Printf.sprintf "egrep -q '(%s)' %s"
-+ Printf.sprintf "grep -E -q '(%s)' %s"
- (String.concat "|" tokens)
- (String.concat " " (List.map fst cfiles)) in
- (match Sys.command com with
-diff --git a/docs/manual/Makefile b/docs/manual/Makefile
-index 7a0e001a9..b0ed58019 100644
---- a/docs/manual/Makefile
-+++ b/docs/manual/Makefile
-@@ -63,8 +63,8 @@ distclean:: clean
- #
- #%.pdf: %.tex
- # $(PDFLATEX) $<
--# if egrep -s '$(RERUN)' $*.log ;then $(PDFLATEX) $<; fi
--# if egrep -s '$(RERUN)' $*.log ;then $(PDFLATEX) $<; fi
-+# if grep -E -s '$(RERUN)' $*.log ;then $(PDFLATEX) $<; fi
-+# if grep -E -s '$(RERUN)' $*.log ;then $(PDFLATEX) $<; fi
-
- ##############################################################################
- # Html version
-diff --git a/parsing_cocci/patch_diff.ml b/parsing_cocci/patch_diff.ml
-index d84f3ad7c..88bd4077c 100755
---- a/parsing_cocci/patch_diff.ml
-+++ b/parsing_cocci/patch_diff.ml
-@@ -82,7 +82,7 @@ let rec mlines lines =
- let final_info dir =
- let git_root = get_root dir in
- let git_read_command =
-- "cd " ^ git_root ^ " && git diff " ^ dir ^ " | egrep '^+++|^@'" in
-+ "cd " ^ git_root ^ " && git diff " ^ dir ^ " | grep -E '^+++|^@'" in
- let list_diff =
- reorg dir git_root (mlines (Common.cmd_to_list git_read_command)) in
- list_diff
-@@ -103,7 +103,7 @@ let final_patch_info dir startid endid =
- if recent
- then "--merge-base"
- else "" in
-- Printf.sprintf " cd %s && git diff %s %s %s | egrep '^+++|^@'"
-+ Printf.sprintf " cd %s && git diff %s %s %s | grep -E '^+++|^@'"
- git_root extra startid endid in
- let list_diff =
- reorg dir git_root (mlines (Common.cmd_to_list git_read_command)) in
-diff --git a/scripts/stat_directory_complete.pl b/scripts/stat_directory_complete.pl
-index f7894d70a..9caf5a601 100755
---- a/scripts/stat_directory_complete.pl
-+++ b/scripts/stat_directory_complete.pl
-@@ -164,7 +164,7 @@ if(-e "gitinfo") {
- my $nodateyet = 1;
-
- while(<TMP>) {
-- #can also do: egrep "^Author" gitinfo | sort | uniq | wc -l
-+ #can also do: grep -E "^Author" gitinfo | sort | uniq | wc -l
- if (/^Author: (.*)/) {
- $h->{$1}++;
- }
---
-2.52.0
-
diff --git a/coccinelle.spec b/coccinelle.spec
index 93eb66f..dc8c1bd 100644
--- a/coccinelle.spec
+++ b/coccinelle.spec
@@ -3,10 +3,10 @@ ExcludeArch: %{ix86}
#global forgeurl https://github.com/coccinelle/coccinelle
%global forgeurl https://gitlab.inria.fr/coccinelle/coccinelle
-%global tag 1.3.1
+%global tag 1.3.3
#global commit 09b475bb3dd2b29c6bd904cc455d4c25c6641649
#global date 20251118
-Version: 1.3.1
+Version: 1.3.3
%forgemeta
# Build the documentation on Fedora only.
@@ -23,7 +23,7 @@ Version: 1.3.1
%endif
Name: coccinelle
-Release: 10%{?dist}
+Release: 1%{?dist}
Summary: Semantic patching for Linux (spatch)
License: GPL-2.0-only
@@ -35,19 +35,6 @@ Source0: %{forgesource}
Source1: test.c
Source2: testpy.cocci
-# RWMJ: I backported some patches for ocaml-pcre2 support from upstream.
-# They can be found here:
-# https://github.com/rwmjones/coccinelle/tree/fedora-1.3.1
-Patch: 0001-replace-pcre-with-pcre2.patch
-Patch: 0002-use-pcre2-instead-of-pcre-in-some-more-places.patch
-Patch: 0003-replace-pcre-with-pcre2-in-install.txt-instructions.patch
-Patch: 0004-replace-pcre-bundle-with-pcre2-bundle.patch
-Patch: 0005-rename-some-bundled-pcre2-files-to-be-input-files.patch
-Patch: 0006-add-.gitignore-in-pcre2-bundle-to-exclude-generated-.patch
-Patch: 0007-rename-update-pcre-bundle-Makefile-to-reflect-bundle.patch
-Patch: 0008-configure.ac-use-pcre2-ocaml-lib-folder-to-reflect-n.patch
-Patch: 0009-replace-obsolescent-egrep-with-grep-E.patch
-
BuildRequires: autoconf
BuildRequires: automake
BuildRequires: python3-devel
@@ -300,6 +287,10 @@ $spatch --sp-file %{SOURCE2} %{SOURCE1}
%changelog
+* Fri Sep 04 2026 Richard W.M. Jones <rjones@redhat.com> - 1.3.3-1
+- New version 1.3.3 (RHBZ#2519492)
+- Drop ocaml-pcre2, egrep patches which are now upstream.
+
* Wed Jul 22 2026 Python Maint <python-maint@redhat.com> - 1.3.1-10
- Rebuilt for Python 3.15.0b4 ABI change
diff --git a/sources b/sources
index 9fac5c9..7daeeb9 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-SHA512 (coccinelle-1.3.1.tar.bz2) = 924aea43b4e927b6a1d0775e064b697abeeb4de0dd1dec8885ccdf1494d65336802a78d281f8e9179db625a8857d10e6585a28570e6f563273c2f31736083715
+SHA512 (coccinelle-1.3.3.tar.bz2) = 4ebd46faf15d8d9fffd9475f5d675deeab13a884b6210a0c8be03457843deec65dc7c33a2d9a29b3dd99e4454488a7abdbe42a30e3ab3e1d51e1390d9e578c42
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-09-04 10:20 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-04 10:20 [rpms/coccinelle] rawhide: New version 1.3.3 (RHBZ#2519492) Richard W.M. Jones
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox