forked from Elara6331/pcre
Initial Commit
This commit is contained in:
commit
406de00b82
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2022 Arsen Musayelyan
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
|
@ -0,0 +1,94 @@
|
||||||
|
PCRE2 LICENCE
|
||||||
|
-------------
|
||||||
|
|
||||||
|
PCRE2 is a library of functions to support regular expressions whose syntax
|
||||||
|
and semantics are as close as possible to those of the Perl 5 language.
|
||||||
|
|
||||||
|
Releases 10.00 and above of PCRE2 are distributed under the terms of the "BSD"
|
||||||
|
licence, as specified below, with one exemption for certain binary
|
||||||
|
redistributions. The documentation for PCRE2, supplied in the "doc" directory,
|
||||||
|
is distributed under the same terms as the software itself. The data in the
|
||||||
|
testdata directory is not copyrighted and is in the public domain.
|
||||||
|
|
||||||
|
The basic library functions are written in C and are freestanding. Also
|
||||||
|
included in the distribution is a just-in-time compiler that can be used to
|
||||||
|
optimize pattern matching. This is an optional feature that can be omitted when
|
||||||
|
the library is built.
|
||||||
|
|
||||||
|
|
||||||
|
THE BASIC LIBRARY FUNCTIONS
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
Written by: Philip Hazel
|
||||||
|
Email local part: Philip.Hazel
|
||||||
|
Email domain: gmail.com
|
||||||
|
|
||||||
|
Retired from University of Cambridge Computing Service,
|
||||||
|
Cambridge, England.
|
||||||
|
|
||||||
|
Copyright (c) 1997-2022 University of Cambridge
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
|
||||||
|
PCRE2 JUST-IN-TIME COMPILATION SUPPORT
|
||||||
|
--------------------------------------
|
||||||
|
|
||||||
|
Written by: Zoltan Herczeg
|
||||||
|
Email local part: hzmester
|
||||||
|
Email domain: freemail.hu
|
||||||
|
|
||||||
|
Copyright(c) 2010-2022 Zoltan Herczeg
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
|
||||||
|
STACK-LESS JUST-IN-TIME COMPILER
|
||||||
|
--------------------------------
|
||||||
|
|
||||||
|
Written by: Zoltan Herczeg
|
||||||
|
Email local part: hzmester
|
||||||
|
Email domain: freemail.hu
|
||||||
|
|
||||||
|
Copyright(c) 2009-2022 Zoltan Herczeg
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
|
||||||
|
THE "BSD" LICENCE
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notices,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notices, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the University of Cambridge nor the names of any
|
||||||
|
contributors may be used to endorse or promote products derived from this
|
||||||
|
software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
|
||||||
|
EXEMPTION FOR BINARY LIBRARY-LIKE PACKAGES
|
||||||
|
------------------------------------------
|
||||||
|
|
||||||
|
The second condition in the BSD licence (covering binary redistributions) does
|
||||||
|
not apply all the way down a chain of software. If binary package A includes
|
||||||
|
PCRE2, it must respect the condition, but if package B is software that
|
||||||
|
includes package A, the condition is not imposed on package B unless it uses
|
||||||
|
PCRE2 independently.
|
||||||
|
|
||||||
|
End
|
|
@ -0,0 +1,42 @@
|
||||||
|
# pcre
|
||||||
|
This package provides a CGo-free port of the PCRE2 regular expression library. The [lib](lib) directory contains source code automatically translated from PCRE2's C source. This package wraps that code and provides an interface as close as possible to Go's stdlib [regexp](https://pkg.go.dev/regexp) package
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Supported GOOS/GOARCH:
|
||||||
|
|
||||||
|
- linux/amd64
|
||||||
|
- linux/386
|
||||||
|
- linux/arm64
|
||||||
|
- linux/arm
|
||||||
|
- linux/riscv64
|
||||||
|
|
||||||
|
More OS support is planned.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## How to transpile pcre2
|
||||||
|
|
||||||
|
In order to transpile pcre2, a Go and C compiler (preferably GCC) will be needed.
|
||||||
|
|
||||||
|
- First, install [ccgo](https://pkg.go.dev/modernc.org/ccgo/v3)
|
||||||
|
|
||||||
|
- Then, download the pcre source code. It can be found here: https://github.com/PCRE2Project/pcre2.
|
||||||
|
|
||||||
|
- Once downloaded, `cd` into the source directory
|
||||||
|
|
||||||
|
- Run `./configure`. If cross-compiling, provide the path to the cross-compiler in the `CC` variable, and set `--target` to the target architecture.
|
||||||
|
|
||||||
|
- When it completes, there should be a `Makefile` in the directory.
|
||||||
|
|
||||||
|
- Run `ccgo -compiledb pcre.json make`. Do not add `-j` arguments to the make command.
|
||||||
|
|
||||||
|
- Run the following command (replace items in triangle brackets):
|
||||||
|
|
||||||
|
```shell
|
||||||
|
CC=/usr/bin/gcc ccgo -o pcre2_<os>_<arch>.go -pkgname lib -trace-translation-units -export-externs X -export-defines D -export-fields F -export-structs S -export-typedefs T pcre.json .libs/libpcre2-8.a
|
||||||
|
```
|
||||||
|
|
||||||
|
- If cross-compiling, set the `CCGO_CC` variable to to path of the cross-compiler, and the `CCGO_AR` variable to the path of the cross-compiler's `ar` binary. Also, set `TARGET_GOARCH` to the GOARCH you're targeting and `TARGET_GOOS` to the OS you're targeting.
|
||||||
|
|
||||||
|
- Once the command completes, two go files will be created. One will start with `pcre2`, the other with `capi`. Copy both of these to the `lib` directory in this repo.
|
|
@ -0,0 +1,82 @@
|
||||||
|
package pcre
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"go.arsenm.dev/pcre/lib"
|
||||||
|
|
||||||
|
"modernc.org/libc"
|
||||||
|
"modernc.org/libc/sys/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
var pce pcreError
|
||||||
|
|
||||||
|
// pcreError is meant to be manually allocated
|
||||||
|
// for when pcre requires a pointer to store an error
|
||||||
|
// such as for Xpcre2_compile_8().
|
||||||
|
type pcreError struct {
|
||||||
|
errCode int32
|
||||||
|
errOffset lib.Tsize_t
|
||||||
|
}
|
||||||
|
|
||||||
|
// allocError manually allocates memory for the
|
||||||
|
// pcreError struct.
|
||||||
|
//
|
||||||
|
// libc.Xfree() should be called on the returned
|
||||||
|
// pointer once it is no longer needed.
|
||||||
|
func allocError(tls *libc.TLS) uintptr {
|
||||||
|
return libc.Xmalloc(tls, types.Size_t(unsafe.Sizeof(pce)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// addErrCodeOffset adds the offset of the error code
|
||||||
|
// within the pcreError struct to a given pointer
|
||||||
|
func addErrCodeOffset(p uintptr) uintptr {
|
||||||
|
ptrOffset := unsafe.Offsetof(pce.errCode)
|
||||||
|
return p + ptrOffset
|
||||||
|
}
|
||||||
|
|
||||||
|
// addErrOffsetOffset adds the offset of the error
|
||||||
|
// offset within the pcreError struct to a given pointer
|
||||||
|
func addErrOffsetOffset(p uintptr) uintptr {
|
||||||
|
offsetOffset := unsafe.Offsetof(pce.errOffset)
|
||||||
|
return p + offsetOffset
|
||||||
|
}
|
||||||
|
|
||||||
|
// ptrToError converts the given pointer to a Go error
|
||||||
|
func ptrToError(tls *libc.TLS, pe uintptr) *PcreError {
|
||||||
|
eo := *(*pcreError)(unsafe.Pointer(pe))
|
||||||
|
|
||||||
|
err := codeToError(tls, eo.errCode)
|
||||||
|
err.offset = eo.errOffset
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// codeToError converts the given error code into a Go error
|
||||||
|
func codeToError(tls *libc.TLS, code int32) *PcreError {
|
||||||
|
errBuf := make([]byte, 256)
|
||||||
|
cErrBuf := uintptr(unsafe.Pointer(&errBuf[0]))
|
||||||
|
|
||||||
|
// Get the textual error message associated with the code,
|
||||||
|
// and store it in errBuf.
|
||||||
|
msgLen := lib.Xpcre2_get_error_message_8(tls, code, cErrBuf, 256)
|
||||||
|
|
||||||
|
return &PcreError{0, string(errBuf[:msgLen])}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PcreError represents errors returned
|
||||||
|
// by underlying pcre2 functions.
|
||||||
|
type PcreError struct {
|
||||||
|
offset lib.Tsize_t
|
||||||
|
errStr string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error returns the string within the error,
|
||||||
|
// prepending the offset if it exists.
|
||||||
|
func (pe *PcreError) Error() string {
|
||||||
|
if pe.offset == 0 {
|
||||||
|
return pe.errStr
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("offset %d: %s", pe.offset, pe.errStr)
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
module go.arsenm.dev/pcre
|
||||||
|
|
||||||
|
go 1.18
|
||||||
|
|
||||||
|
require modernc.org/libc v1.16.8
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/google/uuid v1.3.0 // indirect
|
||||||
|
github.com/mattn/go-isatty v0.0.12 // indirect
|
||||||
|
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac // indirect
|
||||||
|
modernc.org/mathutil v1.4.1 // indirect
|
||||||
|
modernc.org/memory v1.1.1 // indirect
|
||||||
|
)
|
|
@ -0,0 +1,55 @@
|
||||||
|
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||||
|
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||||
|
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||||
|
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||||
|
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
|
||||||
|
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||||
|
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac h1:oN6lz7iLW/YC7un8pq+9bOLyXrprv2+DKfkJY+2LJJw=
|
||||||
|
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
|
||||||
|
modernc.org/cc/v3 v3.36.0/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI=
|
||||||
|
modernc.org/ccgo/v3 v3.0.0-20220428102840-41399a37e894/go.mod h1:eI31LL8EwEBKPpNpA4bU1/i+sKOwOrQy8D87zWUcRZc=
|
||||||
|
modernc.org/ccgo/v3 v3.0.0-20220430103911-bc99d88307be/go.mod h1:bwdAnOoaIt8Ax9YdWGjxWsdkPcZyRPHqrOvJxaKAKGw=
|
||||||
|
modernc.org/ccgo/v3 v3.16.6/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ=
|
||||||
|
modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=
|
||||||
|
modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=
|
||||||
|
modernc.org/libc v0.0.0-20220428101251-2d5f3daf273b/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA=
|
||||||
|
modernc.org/libc v1.16.0/go.mod h1:N4LD6DBE9cf+Dzf9buBlzVJndKr/iJHG97vGLHYnb5A=
|
||||||
|
modernc.org/libc v1.16.1/go.mod h1:JjJE0eu4yeK7tab2n4S1w8tlWd9MxXLRzheaRnAKymU=
|
||||||
|
modernc.org/libc v1.16.8 h1:Ux98PaOMvolgoFX/YwusFOHBnanXdGRmWgI8ciI2z4o=
|
||||||
|
modernc.org/libc v1.16.8/go.mod h1:hYIV5VZczAmGZAnG15Vdngn5HSF5cSkbvfz2B7GRuVU=
|
||||||
|
modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||||
|
modernc.org/mathutil v1.4.1 h1:ij3fYGe8zBF4Vu+g0oT7mB06r8sqGWKuJu1yXeR4by8=
|
||||||
|
modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||||
|
modernc.org/memory v1.1.1 h1:bDOL0DIDLQv7bWhP3gMvIrnoFw+Eo6F7a2QK9HPDiFU=
|
||||||
|
modernc.org/memory v1.1.1/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw=
|
||||||
|
modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||||
|
modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw=
|
||||||
|
modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
|
@ -0,0 +1,128 @@
|
||||||
|
// Code generated by 'ccgo -o pcre2_linux_386.go -pkgname lib -trace-translation-units -export-externs X -export-defines D -export-fields F -export-structs S -export-typedefs T pcre.json .libs/libpcre2-8.a', DO NOT EDIT.
|
||||||
|
|
||||||
|
package lib
|
||||||
|
|
||||||
|
var CAPI = map[string]struct{}{
|
||||||
|
"_pcre2_OP_lengths_8": {},
|
||||||
|
"_pcre2_auto_possessify_8": {},
|
||||||
|
"_pcre2_callout_end_delims_8": {},
|
||||||
|
"_pcre2_callout_start_delims_8": {},
|
||||||
|
"_pcre2_check_escape_8": {},
|
||||||
|
"_pcre2_default_compile_context_8": {},
|
||||||
|
"_pcre2_default_convert_context_8": {},
|
||||||
|
"_pcre2_default_match_context_8": {},
|
||||||
|
"_pcre2_default_tables_8": {},
|
||||||
|
"_pcre2_extuni_8": {},
|
||||||
|
"_pcre2_find_bracket_8": {},
|
||||||
|
"_pcre2_hspace_list_8": {},
|
||||||
|
"_pcre2_is_newline_8": {},
|
||||||
|
"_pcre2_jit_free_8": {},
|
||||||
|
"_pcre2_jit_free_rodata_8": {},
|
||||||
|
"_pcre2_jit_get_size_8": {},
|
||||||
|
"_pcre2_jit_get_target_8": {},
|
||||||
|
"_pcre2_memctl_malloc_8": {},
|
||||||
|
"_pcre2_ord2utf_8": {},
|
||||||
|
"_pcre2_script_run_8": {},
|
||||||
|
"_pcre2_strcmp_8": {},
|
||||||
|
"_pcre2_strcmp_c8_8": {},
|
||||||
|
"_pcre2_strcpy_c8_8": {},
|
||||||
|
"_pcre2_strlen_8": {},
|
||||||
|
"_pcre2_strncmp_8": {},
|
||||||
|
"_pcre2_strncmp_c8_8": {},
|
||||||
|
"_pcre2_study_8": {},
|
||||||
|
"_pcre2_ucd_boolprop_sets_8": {},
|
||||||
|
"_pcre2_ucd_caseless_sets_8": {},
|
||||||
|
"_pcre2_ucd_digit_sets_8": {},
|
||||||
|
"_pcre2_ucd_records_8": {},
|
||||||
|
"_pcre2_ucd_script_sets_8": {},
|
||||||
|
"_pcre2_ucd_stage1_8": {},
|
||||||
|
"_pcre2_ucd_stage2_8": {},
|
||||||
|
"_pcre2_ucp_gbtable_8": {},
|
||||||
|
"_pcre2_ucp_gentype_8": {},
|
||||||
|
"_pcre2_unicode_version_8": {},
|
||||||
|
"_pcre2_utf8_table1": {},
|
||||||
|
"_pcre2_utf8_table1_size": {},
|
||||||
|
"_pcre2_utf8_table2": {},
|
||||||
|
"_pcre2_utf8_table3": {},
|
||||||
|
"_pcre2_utf8_table4": {},
|
||||||
|
"_pcre2_utt_8": {},
|
||||||
|
"_pcre2_utt_names_8": {},
|
||||||
|
"_pcre2_utt_size_8": {},
|
||||||
|
"_pcre2_valid_utf_8": {},
|
||||||
|
"_pcre2_vspace_list_8": {},
|
||||||
|
"_pcre2_was_newline_8": {},
|
||||||
|
"_pcre2_xclass_8": {},
|
||||||
|
"pcre2_callout_enumerate_8": {},
|
||||||
|
"pcre2_code_copy_8": {},
|
||||||
|
"pcre2_code_copy_with_tables_8": {},
|
||||||
|
"pcre2_code_free_8": {},
|
||||||
|
"pcre2_compile_8": {},
|
||||||
|
"pcre2_compile_context_copy_8": {},
|
||||||
|
"pcre2_compile_context_create_8": {},
|
||||||
|
"pcre2_compile_context_free_8": {},
|
||||||
|
"pcre2_config_8": {},
|
||||||
|
"pcre2_convert_context_copy_8": {},
|
||||||
|
"pcre2_convert_context_create_8": {},
|
||||||
|
"pcre2_convert_context_free_8": {},
|
||||||
|
"pcre2_converted_pattern_free_8": {},
|
||||||
|
"pcre2_dfa_match_8": {},
|
||||||
|
"pcre2_general_context_copy_8": {},
|
||||||
|
"pcre2_general_context_create_8": {},
|
||||||
|
"pcre2_general_context_free_8": {},
|
||||||
|
"pcre2_get_error_message_8": {},
|
||||||
|
"pcre2_get_mark_8": {},
|
||||||
|
"pcre2_get_match_data_size_8": {},
|
||||||
|
"pcre2_get_ovector_count_8": {},
|
||||||
|
"pcre2_get_ovector_pointer_8": {},
|
||||||
|
"pcre2_get_startchar_8": {},
|
||||||
|
"pcre2_jit_compile_8": {},
|
||||||
|
"pcre2_jit_free_unused_memory_8": {},
|
||||||
|
"pcre2_jit_match_8": {},
|
||||||
|
"pcre2_jit_stack_assign_8": {},
|
||||||
|
"pcre2_jit_stack_create_8": {},
|
||||||
|
"pcre2_jit_stack_free_8": {},
|
||||||
|
"pcre2_maketables_8": {},
|
||||||
|
"pcre2_maketables_free_8": {},
|
||||||
|
"pcre2_match_8": {},
|
||||||
|
"pcre2_match_context_copy_8": {},
|
||||||
|
"pcre2_match_context_create_8": {},
|
||||||
|
"pcre2_match_context_free_8": {},
|
||||||
|
"pcre2_match_data_create_8": {},
|
||||||
|
"pcre2_match_data_create_from_pattern_8": {},
|
||||||
|
"pcre2_match_data_free_8": {},
|
||||||
|
"pcre2_pattern_convert_8": {},
|
||||||
|
"pcre2_pattern_info_8": {},
|
||||||
|
"pcre2_serialize_decode_8": {},
|
||||||
|
"pcre2_serialize_encode_8": {},
|
||||||
|
"pcre2_serialize_free_8": {},
|
||||||
|
"pcre2_serialize_get_number_of_codes_8": {},
|
||||||
|
"pcre2_set_bsr_8": {},
|
||||||
|
"pcre2_set_callout_8": {},
|
||||||
|
"pcre2_set_character_tables_8": {},
|
||||||
|
"pcre2_set_compile_extra_options_8": {},
|
||||||
|
"pcre2_set_compile_recursion_guard_8": {},
|
||||||
|
"pcre2_set_depth_limit_8": {},
|
||||||
|
"pcre2_set_glob_escape_8": {},
|
||||||
|
"pcre2_set_glob_separator_8": {},
|
||||||
|
"pcre2_set_heap_limit_8": {},
|
||||||
|
"pcre2_set_match_limit_8": {},
|
||||||
|
"pcre2_set_max_pattern_length_8": {},
|
||||||
|
"pcre2_set_newline_8": {},
|
||||||
|
"pcre2_set_offset_limit_8": {},
|
||||||
|
"pcre2_set_parens_nest_limit_8": {},
|
||||||
|
"pcre2_set_recursion_limit_8": {},
|
||||||
|
"pcre2_set_recursion_memory_management_8": {},
|
||||||
|
"pcre2_set_substitute_callout_8": {},
|
||||||
|
"pcre2_substitute_8": {},
|
||||||
|
"pcre2_substring_copy_byname_8": {},
|
||||||
|
"pcre2_substring_copy_bynumber_8": {},
|
||||||
|
"pcre2_substring_free_8": {},
|
||||||
|
"pcre2_substring_get_byname_8": {},
|
||||||
|
"pcre2_substring_get_bynumber_8": {},
|
||||||
|
"pcre2_substring_length_byname_8": {},
|
||||||
|
"pcre2_substring_length_bynumber_8": {},
|
||||||
|
"pcre2_substring_list_free_8": {},
|
||||||
|
"pcre2_substring_list_get_8": {},
|
||||||
|
"pcre2_substring_nametable_scan_8": {},
|
||||||
|
"pcre2_substring_number_from_name_8": {},
|
||||||
|
}
|
|
@ -0,0 +1,128 @@
|
||||||
|
// Code generated by 'ccgo -o pcre2.go -pkgname lib -trace-translation-units -export-externs X -export-defines D -export-fields F -export-structs S -export-typedefs T pcre.json .libs/libpcre2-8.a', DO NOT EDIT.
|
||||||
|
|
||||||
|
package lib
|
||||||
|
|
||||||
|
var CAPI = map[string]struct{}{
|
||||||
|
"_pcre2_OP_lengths_8": {},
|
||||||
|
"_pcre2_auto_possessify_8": {},
|
||||||
|
"_pcre2_callout_end_delims_8": {},
|
||||||
|
"_pcre2_callout_start_delims_8": {},
|
||||||
|
"_pcre2_check_escape_8": {},
|
||||||
|
"_pcre2_default_compile_context_8": {},
|
||||||
|
"_pcre2_default_convert_context_8": {},
|
||||||
|
"_pcre2_default_match_context_8": {},
|
||||||
|
"_pcre2_default_tables_8": {},
|
||||||
|
"_pcre2_extuni_8": {},
|
||||||
|
"_pcre2_find_bracket_8": {},
|
||||||
|
"_pcre2_hspace_list_8": {},
|
||||||
|
"_pcre2_is_newline_8": {},
|
||||||
|
"_pcre2_jit_free_8": {},
|
||||||
|
"_pcre2_jit_free_rodata_8": {},
|
||||||
|
"_pcre2_jit_get_size_8": {},
|
||||||
|
"_pcre2_jit_get_target_8": {},
|
||||||
|
"_pcre2_memctl_malloc_8": {},
|
||||||
|
"_pcre2_ord2utf_8": {},
|
||||||
|
"_pcre2_script_run_8": {},
|
||||||
|
"_pcre2_strcmp_8": {},
|
||||||
|
"_pcre2_strcmp_c8_8": {},
|
||||||
|
"_pcre2_strcpy_c8_8": {},
|
||||||
|
"_pcre2_strlen_8": {},
|
||||||
|
"_pcre2_strncmp_8": {},
|
||||||
|
"_pcre2_strncmp_c8_8": {},
|
||||||
|
"_pcre2_study_8": {},
|
||||||
|
"_pcre2_ucd_boolprop_sets_8": {},
|
||||||
|
"_pcre2_ucd_caseless_sets_8": {},
|
||||||
|
"_pcre2_ucd_digit_sets_8": {},
|
||||||
|
"_pcre2_ucd_records_8": {},
|
||||||
|
"_pcre2_ucd_script_sets_8": {},
|
||||||
|
"_pcre2_ucd_stage1_8": {},
|
||||||
|
"_pcre2_ucd_stage2_8": {},
|
||||||
|
"_pcre2_ucp_gbtable_8": {},
|
||||||
|
"_pcre2_ucp_gentype_8": {},
|
||||||
|
"_pcre2_unicode_version_8": {},
|
||||||
|
"_pcre2_utf8_table1": {},
|
||||||
|
"_pcre2_utf8_table1_size": {},
|
||||||
|
"_pcre2_utf8_table2": {},
|
||||||
|
"_pcre2_utf8_table3": {},
|
||||||
|
"_pcre2_utf8_table4": {},
|
||||||
|
"_pcre2_utt_8": {},
|
||||||
|
"_pcre2_utt_names_8": {},
|
||||||
|
"_pcre2_utt_size_8": {},
|
||||||
|
"_pcre2_valid_utf_8": {},
|
||||||
|
"_pcre2_vspace_list_8": {},
|
||||||
|
"_pcre2_was_newline_8": {},
|
||||||
|
"_pcre2_xclass_8": {},
|
||||||
|
"pcre2_callout_enumerate_8": {},
|
||||||
|
"pcre2_code_copy_8": {},
|
||||||
|
"pcre2_code_copy_with_tables_8": {},
|
||||||
|
"pcre2_code_free_8": {},
|
||||||
|
"pcre2_compile_8": {},
|
||||||
|
"pcre2_compile_context_copy_8": {},
|
||||||
|
"pcre2_compile_context_create_8": {},
|
||||||
|
"pcre2_compile_context_free_8": {},
|
||||||
|
"pcre2_config_8": {},
|
||||||
|
"pcre2_convert_context_copy_8": {},
|
||||||
|
"pcre2_convert_context_create_8": {},
|
||||||
|
"pcre2_convert_context_free_8": {},
|
||||||
|
"pcre2_converted_pattern_free_8": {},
|
||||||
|
"pcre2_dfa_match_8": {},
|
||||||
|
"pcre2_general_context_copy_8": {},
|
||||||
|
"pcre2_general_context_create_8": {},
|
||||||
|
"pcre2_general_context_free_8": {},
|
||||||
|
"pcre2_get_error_message_8": {},
|
||||||
|
"pcre2_get_mark_8": {},
|
||||||
|
"pcre2_get_match_data_size_8": {},
|
||||||
|
"pcre2_get_ovector_count_8": {},
|
||||||
|
"pcre2_get_ovector_pointer_8": {},
|
||||||
|
"pcre2_get_startchar_8": {},
|
||||||
|
"pcre2_jit_compile_8": {},
|
||||||
|
"pcre2_jit_free_unused_memory_8": {},
|
||||||
|
"pcre2_jit_match_8": {},
|
||||||
|
"pcre2_jit_stack_assign_8": {},
|
||||||
|
"pcre2_jit_stack_create_8": {},
|
||||||
|
"pcre2_jit_stack_free_8": {},
|
||||||
|
"pcre2_maketables_8": {},
|
||||||
|
"pcre2_maketables_free_8": {},
|
||||||
|
"pcre2_match_8": {},
|
||||||
|
"pcre2_match_context_copy_8": {},
|
||||||
|
"pcre2_match_context_create_8": {},
|
||||||
|
"pcre2_match_context_free_8": {},
|
||||||
|
"pcre2_match_data_create_8": {},
|
||||||
|
"pcre2_match_data_create_from_pattern_8": {},
|
||||||
|
"pcre2_match_data_free_8": {},
|
||||||
|
"pcre2_pattern_convert_8": {},
|
||||||
|
"pcre2_pattern_info_8": {},
|
||||||
|
"pcre2_serialize_decode_8": {},
|
||||||
|
"pcre2_serialize_encode_8": {},
|
||||||
|
"pcre2_serialize_free_8": {},
|
||||||
|
"pcre2_serialize_get_number_of_codes_8": {},
|
||||||
|
"pcre2_set_bsr_8": {},
|
||||||
|
"pcre2_set_callout_8": {},
|
||||||
|
"pcre2_set_character_tables_8": {},
|
||||||
|
"pcre2_set_compile_extra_options_8": {},
|
||||||
|
"pcre2_set_compile_recursion_guard_8": {},
|
||||||
|
"pcre2_set_depth_limit_8": {},
|
||||||
|
"pcre2_set_glob_escape_8": {},
|
||||||
|
"pcre2_set_glob_separator_8": {},
|
||||||
|
"pcre2_set_heap_limit_8": {},
|
||||||
|
"pcre2_set_match_limit_8": {},
|
||||||
|
"pcre2_set_max_pattern_length_8": {},
|
||||||
|
"pcre2_set_newline_8": {},
|
||||||
|
"pcre2_set_offset_limit_8": {},
|
||||||
|
"pcre2_set_parens_nest_limit_8": {},
|
||||||
|
"pcre2_set_recursion_limit_8": {},
|
||||||
|
"pcre2_set_recursion_memory_management_8": {},
|
||||||
|
"pcre2_set_substitute_callout_8": {},
|
||||||
|
"pcre2_substitute_8": {},
|
||||||
|
"pcre2_substring_copy_byname_8": {},
|
||||||
|
"pcre2_substring_copy_bynumber_8": {},
|
||||||
|
"pcre2_substring_free_8": {},
|
||||||
|
"pcre2_substring_get_byname_8": {},
|
||||||
|
"pcre2_substring_get_bynumber_8": {},
|
||||||
|
"pcre2_substring_length_byname_8": {},
|
||||||
|
"pcre2_substring_length_bynumber_8": {},
|
||||||
|
"pcre2_substring_list_free_8": {},
|
||||||
|
"pcre2_substring_list_get_8": {},
|
||||||
|
"pcre2_substring_nametable_scan_8": {},
|
||||||
|
"pcre2_substring_number_from_name_8": {},
|
||||||
|
}
|
|
@ -0,0 +1,128 @@
|
||||||
|
// Code generated by 'ccgo -o pcre2_linux_arm.go -pkgname lib -trace-translation-units -export-externs X -export-defines D -export-fields F -export-structs S -export-typedefs T pcre.json .libs/libpcre2-8.a', DO NOT EDIT.
|
||||||
|
|
||||||
|
package lib
|
||||||
|
|
||||||
|
var CAPI = map[string]struct{}{
|
||||||
|
"_pcre2_OP_lengths_8": {},
|
||||||
|
"_pcre2_auto_possessify_8": {},
|
||||||
|
"_pcre2_callout_end_delims_8": {},
|
||||||
|
"_pcre2_callout_start_delims_8": {},
|
||||||
|
"_pcre2_check_escape_8": {},
|
||||||
|
"_pcre2_default_compile_context_8": {},
|
||||||
|
"_pcre2_default_convert_context_8": {},
|
||||||
|
"_pcre2_default_match_context_8": {},
|
||||||
|
"_pcre2_default_tables_8": {},
|
||||||
|
"_pcre2_extuni_8": {},
|
||||||
|
"_pcre2_find_bracket_8": {},
|
||||||
|
"_pcre2_hspace_list_8": {},
|
||||||
|
"_pcre2_is_newline_8": {},
|
||||||
|
"_pcre2_jit_free_8": {},
|
||||||
|
"_pcre2_jit_free_rodata_8": {},
|
||||||
|
"_pcre2_jit_get_size_8": {},
|
||||||
|
"_pcre2_jit_get_target_8": {},
|
||||||
|
"_pcre2_memctl_malloc_8": {},
|
||||||
|
"_pcre2_ord2utf_8": {},
|
||||||
|
"_pcre2_script_run_8": {},
|
||||||
|
"_pcre2_strcmp_8": {},
|
||||||
|
"_pcre2_strcmp_c8_8": {},
|
||||||
|
"_pcre2_strcpy_c8_8": {},
|
||||||
|
"_pcre2_strlen_8": {},
|
||||||
|
"_pcre2_strncmp_8": {},
|
||||||
|
"_pcre2_strncmp_c8_8": {},
|
||||||
|
"_pcre2_study_8": {},
|
||||||
|
"_pcre2_ucd_boolprop_sets_8": {},
|
||||||
|
"_pcre2_ucd_caseless_sets_8": {},
|
||||||
|
"_pcre2_ucd_digit_sets_8": {},
|
||||||
|
"_pcre2_ucd_records_8": {},
|
||||||
|
"_pcre2_ucd_script_sets_8": {},
|
||||||
|
"_pcre2_ucd_stage1_8": {},
|
||||||
|
"_pcre2_ucd_stage2_8": {},
|
||||||
|
"_pcre2_ucp_gbtable_8": {},
|
||||||
|
"_pcre2_ucp_gentype_8": {},
|
||||||
|
"_pcre2_unicode_version_8": {},
|
||||||
|
"_pcre2_utf8_table1": {},
|
||||||
|
"_pcre2_utf8_table1_size": {},
|
||||||
|
"_pcre2_utf8_table2": {},
|
||||||
|
"_pcre2_utf8_table3": {},
|
||||||
|
"_pcre2_utf8_table4": {},
|
||||||
|
"_pcre2_utt_8": {},
|
||||||
|
"_pcre2_utt_names_8": {},
|
||||||
|
"_pcre2_utt_size_8": {},
|
||||||
|
"_pcre2_valid_utf_8": {},
|
||||||
|
"_pcre2_vspace_list_8": {},
|
||||||
|
"_pcre2_was_newline_8": {},
|
||||||
|
"_pcre2_xclass_8": {},
|
||||||
|
"pcre2_callout_enumerate_8": {},
|
||||||
|
"pcre2_code_copy_8": {},
|
||||||
|
"pcre2_code_copy_with_tables_8": {},
|
||||||
|
"pcre2_code_free_8": {},
|
||||||
|
"pcre2_compile_8": {},
|
||||||
|
"pcre2_compile_context_copy_8": {},
|
||||||
|
"pcre2_compile_context_create_8": {},
|
||||||
|
"pcre2_compile_context_free_8": {},
|
||||||
|
"pcre2_config_8": {},
|
||||||
|
"pcre2_convert_context_copy_8": {},
|
||||||
|
"pcre2_convert_context_create_8": {},
|
||||||
|
"pcre2_convert_context_free_8": {},
|
||||||
|
"pcre2_converted_pattern_free_8": {},
|
||||||
|
"pcre2_dfa_match_8": {},
|
||||||
|
"pcre2_general_context_copy_8": {},
|
||||||
|
"pcre2_general_context_create_8": {},
|
||||||
|
"pcre2_general_context_free_8": {},
|
||||||
|
"pcre2_get_error_message_8": {},
|
||||||
|
"pcre2_get_mark_8": {},
|
||||||
|
"pcre2_get_match_data_size_8": {},
|
||||||
|
"pcre2_get_ovector_count_8": {},
|
||||||
|
"pcre2_get_ovector_pointer_8": {},
|
||||||
|
"pcre2_get_startchar_8": {},
|
||||||
|
"pcre2_jit_compile_8": {},
|
||||||
|
"pcre2_jit_free_unused_memory_8": {},
|
||||||
|
"pcre2_jit_match_8": {},
|
||||||
|
"pcre2_jit_stack_assign_8": {},
|
||||||
|
"pcre2_jit_stack_create_8": {},
|
||||||
|
"pcre2_jit_stack_free_8": {},
|
||||||
|
"pcre2_maketables_8": {},
|
||||||
|
"pcre2_maketables_free_8": {},
|
||||||
|
"pcre2_match_8": {},
|
||||||
|
"pcre2_match_context_copy_8": {},
|
||||||
|
"pcre2_match_context_create_8": {},
|
||||||
|
"pcre2_match_context_free_8": {},
|
||||||
|
"pcre2_match_data_create_8": {},
|
||||||
|
"pcre2_match_data_create_from_pattern_8": {},
|
||||||
|
"pcre2_match_data_free_8": {},
|
||||||
|
"pcre2_pattern_convert_8": {},
|
||||||
|
"pcre2_pattern_info_8": {},
|
||||||
|
"pcre2_serialize_decode_8": {},
|
||||||
|
"pcre2_serialize_encode_8": {},
|
||||||
|
"pcre2_serialize_free_8": {},
|
||||||
|
"pcre2_serialize_get_number_of_codes_8": {},
|
||||||
|
"pcre2_set_bsr_8": {},
|
||||||
|
"pcre2_set_callout_8": {},
|
||||||
|
"pcre2_set_character_tables_8": {},
|
||||||
|
"pcre2_set_compile_extra_options_8": {},
|
||||||
|
"pcre2_set_compile_recursion_guard_8": {},
|
||||||
|
"pcre2_set_depth_limit_8": {},
|
||||||
|
"pcre2_set_glob_escape_8": {},
|
||||||
|
"pcre2_set_glob_separator_8": {},
|
||||||
|
"pcre2_set_heap_limit_8": {},
|
||||||
|
"pcre2_set_match_limit_8": {},
|
||||||
|
"pcre2_set_max_pattern_length_8": {},
|
||||||
|
"pcre2_set_newline_8": {},
|
||||||
|
"pcre2_set_offset_limit_8": {},
|
||||||
|
"pcre2_set_parens_nest_limit_8": {},
|
||||||
|
"pcre2_set_recursion_limit_8": {},
|
||||||
|
"pcre2_set_recursion_memory_management_8": {},
|
||||||
|
"pcre2_set_substitute_callout_8": {},
|
||||||
|
"pcre2_substitute_8": {},
|
||||||
|
"pcre2_substring_copy_byname_8": {},
|
||||||
|
"pcre2_substring_copy_bynumber_8": {},
|
||||||
|
"pcre2_substring_free_8": {},
|
||||||
|
"pcre2_substring_get_byname_8": {},
|
||||||
|
"pcre2_substring_get_bynumber_8": {},
|
||||||
|
"pcre2_substring_length_byname_8": {},
|
||||||
|
"pcre2_substring_length_bynumber_8": {},
|
||||||
|
"pcre2_substring_list_free_8": {},
|
||||||
|
"pcre2_substring_list_get_8": {},
|
||||||
|
"pcre2_substring_nametable_scan_8": {},
|
||||||
|
"pcre2_substring_number_from_name_8": {},
|
||||||
|
}
|
|
@ -0,0 +1,128 @@
|
||||||
|
// Code generated by 'ccgo -o pcre2.go -pkgname lib -trace-translation-units -export-externs X -export-defines D -export-fields F -export-structs S -export-typedefs T pcre.json .libs/libpcre2-8.a', DO NOT EDIT.
|
||||||
|
|
||||||
|
package lib
|
||||||
|
|
||||||
|
var CAPI = map[string]struct{}{
|
||||||
|
"_pcre2_OP_lengths_8": {},
|
||||||
|
"_pcre2_auto_possessify_8": {},
|
||||||
|
"_pcre2_callout_end_delims_8": {},
|
||||||
|
"_pcre2_callout_start_delims_8": {},
|
||||||
|
"_pcre2_check_escape_8": {},
|
||||||
|
"_pcre2_default_compile_context_8": {},
|
||||||
|
"_pcre2_default_convert_context_8": {},
|
||||||
|
"_pcre2_default_match_context_8": {},
|
||||||
|
"_pcre2_default_tables_8": {},
|
||||||
|
"_pcre2_extuni_8": {},
|
||||||
|
"_pcre2_find_bracket_8": {},
|
||||||
|
"_pcre2_hspace_list_8": {},
|
||||||
|
"_pcre2_is_newline_8": {},
|
||||||
|
"_pcre2_jit_free_8": {},
|
||||||
|
"_pcre2_jit_free_rodata_8": {},
|
||||||
|
"_pcre2_jit_get_size_8": {},
|
||||||
|
"_pcre2_jit_get_target_8": {},
|
||||||
|
"_pcre2_memctl_malloc_8": {},
|
||||||
|
"_pcre2_ord2utf_8": {},
|
||||||
|
"_pcre2_script_run_8": {},
|
||||||
|
"_pcre2_strcmp_8": {},
|
||||||
|
"_pcre2_strcmp_c8_8": {},
|
||||||
|
"_pcre2_strcpy_c8_8": {},
|
||||||
|
"_pcre2_strlen_8": {},
|
||||||
|
"_pcre2_strncmp_8": {},
|
||||||
|
"_pcre2_strncmp_c8_8": {},
|
||||||
|
"_pcre2_study_8": {},
|
||||||
|
"_pcre2_ucd_boolprop_sets_8": {},
|
||||||
|
"_pcre2_ucd_caseless_sets_8": {},
|
||||||
|
"_pcre2_ucd_digit_sets_8": {},
|
||||||
|
"_pcre2_ucd_records_8": {},
|
||||||
|
"_pcre2_ucd_script_sets_8": {},
|
||||||
|
"_pcre2_ucd_stage1_8": {},
|
||||||
|
"_pcre2_ucd_stage2_8": {},
|
||||||
|
"_pcre2_ucp_gbtable_8": {},
|
||||||
|
"_pcre2_ucp_gentype_8": {},
|
||||||
|
"_pcre2_unicode_version_8": {},
|
||||||
|
"_pcre2_utf8_table1": {},
|
||||||
|
"_pcre2_utf8_table1_size": {},
|
||||||
|
"_pcre2_utf8_table2": {},
|
||||||
|
"_pcre2_utf8_table3": {},
|
||||||
|
"_pcre2_utf8_table4": {},
|
||||||
|
"_pcre2_utt_8": {},
|
||||||
|
"_pcre2_utt_names_8": {},
|
||||||
|
"_pcre2_utt_size_8": {},
|
||||||
|
"_pcre2_valid_utf_8": {},
|
||||||
|
"_pcre2_vspace_list_8": {},
|
||||||
|
"_pcre2_was_newline_8": {},
|
||||||
|
"_pcre2_xclass_8": {},
|
||||||
|
"pcre2_callout_enumerate_8": {},
|
||||||
|
"pcre2_code_copy_8": {},
|
||||||
|
"pcre2_code_copy_with_tables_8": {},
|
||||||
|
"pcre2_code_free_8": {},
|
||||||
|
"pcre2_compile_8": {},
|
||||||
|
"pcre2_compile_context_copy_8": {},
|
||||||
|
"pcre2_compile_context_create_8": {},
|
||||||
|
"pcre2_compile_context_free_8": {},
|
||||||
|
"pcre2_config_8": {},
|
||||||
|
"pcre2_convert_context_copy_8": {},
|
||||||
|
"pcre2_convert_context_create_8": {},
|
||||||
|
"pcre2_convert_context_free_8": {},
|
||||||
|
"pcre2_converted_pattern_free_8": {},
|
||||||
|
"pcre2_dfa_match_8": {},
|
||||||
|
"pcre2_general_context_copy_8": {},
|
||||||
|
"pcre2_general_context_create_8": {},
|
||||||
|
"pcre2_general_context_free_8": {},
|
||||||
|
"pcre2_get_error_message_8": {},
|
||||||
|
"pcre2_get_mark_8": {},
|
||||||
|
"pcre2_get_match_data_size_8": {},
|
||||||
|
"pcre2_get_ovector_count_8": {},
|
||||||
|
"pcre2_get_ovector_pointer_8": {},
|
||||||
|
"pcre2_get_startchar_8": {},
|
||||||
|
"pcre2_jit_compile_8": {},
|
||||||
|
"pcre2_jit_free_unused_memory_8": {},
|
||||||
|
"pcre2_jit_match_8": {},
|
||||||
|
"pcre2_jit_stack_assign_8": {},
|
||||||
|
"pcre2_jit_stack_create_8": {},
|
||||||
|
"pcre2_jit_stack_free_8": {},
|
||||||
|
"pcre2_maketables_8": {},
|
||||||
|
"pcre2_maketables_free_8": {},
|
||||||
|
"pcre2_match_8": {},
|
||||||
|
"pcre2_match_context_copy_8": {},
|
||||||
|
"pcre2_match_context_create_8": {},
|
||||||
|
"pcre2_match_context_free_8": {},
|
||||||
|
"pcre2_match_data_create_8": {},
|
||||||
|
"pcre2_match_data_create_from_pattern_8": {},
|
||||||
|
"pcre2_match_data_free_8": {},
|
||||||
|
"pcre2_pattern_convert_8": {},
|
||||||
|
"pcre2_pattern_info_8": {},
|
||||||
|
"pcre2_serialize_decode_8": {},
|
||||||
|
"pcre2_serialize_encode_8": {},
|
||||||
|
"pcre2_serialize_free_8": {},
|
||||||
|
"pcre2_serialize_get_number_of_codes_8": {},
|
||||||
|
"pcre2_set_bsr_8": {},
|
||||||
|
"pcre2_set_callout_8": {},
|
||||||
|
"pcre2_set_character_tables_8": {},
|
||||||
|
"pcre2_set_compile_extra_options_8": {},
|
||||||
|
"pcre2_set_compile_recursion_guard_8": {},
|
||||||
|
"pcre2_set_depth_limit_8": {},
|
||||||
|
"pcre2_set_glob_escape_8": {},
|
||||||
|
"pcre2_set_glob_separator_8": {},
|
||||||
|
"pcre2_set_heap_limit_8": {},
|
||||||
|
"pcre2_set_match_limit_8": {},
|
||||||
|
"pcre2_set_max_pattern_length_8": {},
|
||||||
|
"pcre2_set_newline_8": {},
|
||||||
|
"pcre2_set_offset_limit_8": {},
|
||||||
|
"pcre2_set_parens_nest_limit_8": {},
|
||||||
|
"pcre2_set_recursion_limit_8": {},
|
||||||
|
"pcre2_set_recursion_memory_management_8": {},
|
||||||
|
"pcre2_set_substitute_callout_8": {},
|
||||||
|
"pcre2_substitute_8": {},
|
||||||
|
"pcre2_substring_copy_byname_8": {},
|
||||||
|
"pcre2_substring_copy_bynumber_8": {},
|
||||||
|
"pcre2_substring_free_8": {},
|
||||||
|
"pcre2_substring_get_byname_8": {},
|
||||||
|
"pcre2_substring_get_bynumber_8": {},
|
||||||
|
"pcre2_substring_length_byname_8": {},
|
||||||
|
"pcre2_substring_length_bynumber_8": {},
|
||||||
|
"pcre2_substring_list_free_8": {},
|
||||||
|
"pcre2_substring_list_get_8": {},
|
||||||
|
"pcre2_substring_nametable_scan_8": {},
|
||||||
|
"pcre2_substring_number_from_name_8": {},
|
||||||
|
}
|
|
@ -0,0 +1,128 @@
|
||||||
|
// Code generated by 'ccgo -o pcre2_linux_riscv64.go -pkgname lib -trace-translation-units -export-externs X -export-defines D -export-fields F -export-structs S -export-typedefs T pcre.json .libs/libpcre2-8.a', DO NOT EDIT.
|
||||||
|
|
||||||
|
package lib
|
||||||
|
|
||||||
|
var CAPI = map[string]struct{}{
|
||||||
|
"_pcre2_OP_lengths_8": {},
|
||||||
|
"_pcre2_auto_possessify_8": {},
|
||||||
|
"_pcre2_callout_end_delims_8": {},
|
||||||
|
"_pcre2_callout_start_delims_8": {},
|
||||||
|
"_pcre2_check_escape_8": {},
|
||||||
|
"_pcre2_default_compile_context_8": {},
|
||||||
|
"_pcre2_default_convert_context_8": {},
|
||||||
|
"_pcre2_default_match_context_8": {},
|
||||||
|
"_pcre2_default_tables_8": {},
|
||||||
|
"_pcre2_extuni_8": {},
|
||||||
|
"_pcre2_find_bracket_8": {},
|
||||||
|
"_pcre2_hspace_list_8": {},
|
||||||
|
"_pcre2_is_newline_8": {},
|
||||||
|
"_pcre2_jit_free_8": {},
|
||||||
|
"_pcre2_jit_free_rodata_8": {},
|
||||||
|
"_pcre2_jit_get_size_8": {},
|
||||||
|
"_pcre2_jit_get_target_8": {},
|
||||||
|
"_pcre2_memctl_malloc_8": {},
|
||||||
|
"_pcre2_ord2utf_8": {},
|
||||||
|
"_pcre2_script_run_8": {},
|
||||||
|
"_pcre2_strcmp_8": {},
|
||||||
|
"_pcre2_strcmp_c8_8": {},
|
||||||
|
"_pcre2_strcpy_c8_8": {},
|
||||||
|
"_pcre2_strlen_8": {},
|
||||||
|
"_pcre2_strncmp_8": {},
|
||||||
|
"_pcre2_strncmp_c8_8": {},
|
||||||
|
"_pcre2_study_8": {},
|
||||||
|
"_pcre2_ucd_boolprop_sets_8": {},
|
||||||
|
"_pcre2_ucd_caseless_sets_8": {},
|
||||||
|
"_pcre2_ucd_digit_sets_8": {},
|
||||||
|
"_pcre2_ucd_records_8": {},
|
||||||
|
"_pcre2_ucd_script_sets_8": {},
|
||||||
|
"_pcre2_ucd_stage1_8": {},
|
||||||
|
"_pcre2_ucd_stage2_8": {},
|
||||||
|
"_pcre2_ucp_gbtable_8": {},
|
||||||
|
"_pcre2_ucp_gentype_8": {},
|
||||||
|
"_pcre2_unicode_version_8": {},
|
||||||
|
"_pcre2_utf8_table1": {},
|
||||||
|
"_pcre2_utf8_table1_size": {},
|
||||||
|
"_pcre2_utf8_table2": {},
|
||||||
|
"_pcre2_utf8_table3": {},
|
||||||
|
"_pcre2_utf8_table4": {},
|
||||||
|
"_pcre2_utt_8": {},
|
||||||
|
"_pcre2_utt_names_8": {},
|
||||||
|
"_pcre2_utt_size_8": {},
|
||||||
|
"_pcre2_valid_utf_8": {},
|
||||||
|
"_pcre2_vspace_list_8": {},
|
||||||
|
"_pcre2_was_newline_8": {},
|
||||||
|
"_pcre2_xclass_8": {},
|
||||||
|
"pcre2_callout_enumerate_8": {},
|
||||||
|
"pcre2_code_copy_8": {},
|
||||||
|
"pcre2_code_copy_with_tables_8": {},
|
||||||
|
"pcre2_code_free_8": {},
|
||||||
|
"pcre2_compile_8": {},
|
||||||
|
"pcre2_compile_context_copy_8": {},
|
||||||
|
"pcre2_compile_context_create_8": {},
|
||||||
|
"pcre2_compile_context_free_8": {},
|
||||||
|
"pcre2_config_8": {},
|
||||||
|
"pcre2_convert_context_copy_8": {},
|
||||||
|
"pcre2_convert_context_create_8": {},
|
||||||
|
"pcre2_convert_context_free_8": {},
|
||||||
|
"pcre2_converted_pattern_free_8": {},
|
||||||
|
"pcre2_dfa_match_8": {},
|
||||||
|
"pcre2_general_context_copy_8": {},
|
||||||
|
"pcre2_general_context_create_8": {},
|
||||||
|
"pcre2_general_context_free_8": {},
|
||||||
|
"pcre2_get_error_message_8": {},
|
||||||
|
"pcre2_get_mark_8": {},
|
||||||
|
"pcre2_get_match_data_size_8": {},
|
||||||
|
"pcre2_get_ovector_count_8": {},
|
||||||
|
"pcre2_get_ovector_pointer_8": {},
|
||||||
|
"pcre2_get_startchar_8": {},
|
||||||
|
"pcre2_jit_compile_8": {},
|
||||||
|
"pcre2_jit_free_unused_memory_8": {},
|
||||||
|
"pcre2_jit_match_8": {},
|
||||||
|
"pcre2_jit_stack_assign_8": {},
|
||||||
|
"pcre2_jit_stack_create_8": {},
|
||||||
|
"pcre2_jit_stack_free_8": {},
|
||||||
|
"pcre2_maketables_8": {},
|
||||||
|
"pcre2_maketables_free_8": {},
|
||||||
|
"pcre2_match_8": {},
|
||||||
|
"pcre2_match_context_copy_8": {},
|
||||||
|
"pcre2_match_context_create_8": {},
|
||||||
|
"pcre2_match_context_free_8": {},
|
||||||
|
"pcre2_match_data_create_8": {},
|
||||||
|
"pcre2_match_data_create_from_pattern_8": {},
|
||||||
|
"pcre2_match_data_free_8": {},
|
||||||
|
"pcre2_pattern_convert_8": {},
|
||||||
|
"pcre2_pattern_info_8": {},
|
||||||
|
"pcre2_serialize_decode_8": {},
|
||||||
|
"pcre2_serialize_encode_8": {},
|
||||||
|
"pcre2_serialize_free_8": {},
|
||||||
|
"pcre2_serialize_get_number_of_codes_8": {},
|
||||||
|
"pcre2_set_bsr_8": {},
|
||||||
|
"pcre2_set_callout_8": {},
|
||||||
|
"pcre2_set_character_tables_8": {},
|
||||||
|
"pcre2_set_compile_extra_options_8": {},
|
||||||
|
"pcre2_set_compile_recursion_guard_8": {},
|
||||||
|
"pcre2_set_depth_limit_8": {},
|
||||||
|
"pcre2_set_glob_escape_8": {},
|
||||||
|
"pcre2_set_glob_separator_8": {},
|
||||||
|
"pcre2_set_heap_limit_8": {},
|
||||||
|
"pcre2_set_match_limit_8": {},
|
||||||
|
"pcre2_set_max_pattern_length_8": {},
|
||||||
|
"pcre2_set_newline_8": {},
|
||||||
|
"pcre2_set_offset_limit_8": {},
|
||||||
|
"pcre2_set_parens_nest_limit_8": {},
|
||||||
|
"pcre2_set_recursion_limit_8": {},
|
||||||
|
"pcre2_set_recursion_memory_management_8": {},
|
||||||
|
"pcre2_set_substitute_callout_8": {},
|
||||||
|
"pcre2_substitute_8": {},
|
||||||
|
"pcre2_substring_copy_byname_8": {},
|
||||||
|
"pcre2_substring_copy_bynumber_8": {},
|
||||||
|
"pcre2_substring_free_8": {},
|
||||||
|
"pcre2_substring_get_byname_8": {},
|
||||||
|
"pcre2_substring_get_bynumber_8": {},
|
||||||
|
"pcre2_substring_length_byname_8": {},
|
||||||
|
"pcre2_substring_length_bynumber_8": {},
|
||||||
|
"pcre2_substring_list_free_8": {},
|
||||||
|
"pcre2_substring_list_get_8": {},
|
||||||
|
"pcre2_substring_nametable_scan_8": {},
|
||||||
|
"pcre2_substring_number_from_name_8": {},
|
||||||
|
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,665 @@
|
||||||
|
// Package pcre is a library that provides pcre2 regular expressions
|
||||||
|
// in pure Go, allowing for features such as cross-compiling.
|
||||||
|
//
|
||||||
|
// The lib directory contains source code automatically translated from
|
||||||
|
// pcre2's C source code for each supported architecture and/or OS.
|
||||||
|
// This package wraps the automatically-translated source to provide a
|
||||||
|
// safe interface as close to Go's regexp library as possible.
|
||||||
|
package pcre
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
|
"sync"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"go.arsenm.dev/pcre/lib"
|
||||||
|
|
||||||
|
"modernc.org/libc"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Regexp represents a pcre2 regular expression
|
||||||
|
type Regexp struct {
|
||||||
|
mtx *sync.Mutex
|
||||||
|
expr string
|
||||||
|
re uintptr
|
||||||
|
tls *libc.TLS
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compile runs CompileOpts with no options.
|
||||||
|
//
|
||||||
|
// Close() should be called on the returned expression
|
||||||
|
// once it is no longer needed.
|
||||||
|
func Compile(pattern string) (*Regexp, error) {
|
||||||
|
return CompileOpts(pattern, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CompileOpts compiles the provided pattern using the given options.
|
||||||
|
//
|
||||||
|
// Close() should be called on the returned expression
|
||||||
|
// once it is no longer needed.
|
||||||
|
func CompileOpts(pattern string, options CompileOption) (*Regexp, error) {
|
||||||
|
tls := libc.NewTLS()
|
||||||
|
|
||||||
|
// Get C string of pattern
|
||||||
|
cPattern, err := libc.CString(pattern)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Free the string when done
|
||||||
|
defer libc.Xfree(tls, cPattern)
|
||||||
|
|
||||||
|
// Allocate new error
|
||||||
|
cErr := allocError(tls)
|
||||||
|
// Free error when done
|
||||||
|
defer libc.Xfree(tls, cErr)
|
||||||
|
|
||||||
|
// Get error offsets
|
||||||
|
errPtr := addErrCodeOffset(cErr)
|
||||||
|
errOffsetPtr := addErrOffsetOffset(cErr)
|
||||||
|
|
||||||
|
// Convert pattern length to size_t type
|
||||||
|
cPatLen := lib.Tsize_t(len(pattern))
|
||||||
|
|
||||||
|
// Compile expression
|
||||||
|
r := lib.Xpcre2_compile_8(tls, cPattern, cPatLen, uint32(options), errPtr, errOffsetPtr, 0)
|
||||||
|
if r == 0 {
|
||||||
|
return nil, ptrToError(tls, cErr)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create regexp instance
|
||||||
|
regex := Regexp{
|
||||||
|
expr: pattern,
|
||||||
|
mtx: &sync.Mutex{},
|
||||||
|
re: r,
|
||||||
|
tls: tls,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure resources are freed if GC collects the
|
||||||
|
// regular expression.
|
||||||
|
runtime.SetFinalizer(®ex, func(r *Regexp) error {
|
||||||
|
return r.Close()
|
||||||
|
})
|
||||||
|
|
||||||
|
return ®ex, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MustCompile compiles the given pattern and panics
|
||||||
|
// if there was an error
|
||||||
|
//
|
||||||
|
// Close() should be called on the returned expression
|
||||||
|
// once it is no longer needed.
|
||||||
|
func MustCompile(pattern string) *Regexp {
|
||||||
|
rgx, err := Compile(pattern)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return rgx
|
||||||
|
}
|
||||||
|
|
||||||
|
// MustCompileOpts compiles the given pattern with the given
|
||||||
|
// options and panics if there was an error.
|
||||||
|
//
|
||||||
|
// Close() should be called on the returned expression
|
||||||
|
// once it is no longer needed.
|
||||||
|
func MustCompileOpts(pattern string, options CompileOption) *Regexp {
|
||||||
|
rgx, err := CompileOpts(pattern, options)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return rgx
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find returns the leftmost match of the regular expression.
|
||||||
|
// A return value of nil indicates no match.
|
||||||
|
func (r *Regexp) Find(b []byte) []byte {
|
||||||
|
matches, err := r.match(b, 0, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if len(matches) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
match := matches[0]
|
||||||
|
return b[match[0]:match[1]]
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindIndex returns a two-element slice of integers
|
||||||
|
// representing the location of the leftmost match of the
|
||||||
|
// regular expression.
|
||||||
|
func (r *Regexp) FindIndex(b []byte) []int {
|
||||||
|
matches, err := r.match(b, 0, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if len(matches) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
match := matches[0]
|
||||||
|
|
||||||
|
return []int{int(match[0]), int(match[1])}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindAll returns all matches of the regular expression.
|
||||||
|
// A return value of nil indicates no match.
|
||||||
|
func (r *Regexp) FindAll(b []byte, n int) [][]byte {
|
||||||
|
matches, err := r.match(b, 0, true)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if len(matches) == 0 || n == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if n > 0 && len(matches) > n {
|
||||||
|
matches = matches[:n]
|
||||||
|
}
|
||||||
|
|
||||||
|
var out [][]byte
|
||||||
|
for _, match := range matches {
|
||||||
|
out = append(out, b[match[0]:match[1]])
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindAll returns indices of all matches of the
|
||||||
|
// regular expression. A return value of nil indicates
|
||||||
|
// no match.
|
||||||
|
func (r *Regexp) FindAllIndex(b []byte, n int) [][]int {
|
||||||
|
matches, err := r.match(b, 0, true)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if len(matches) == 0 || n == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if n > 0 && len(matches) > n {
|
||||||
|
matches = matches[:n]
|
||||||
|
}
|
||||||
|
|
||||||
|
var out [][]int
|
||||||
|
for _, match := range matches {
|
||||||
|
out = append(out, []int{int(match[0]), int(match[1])})
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindSubmatch returns a slice containing the match as the
|
||||||
|
// first element, and the submatches as the subsequent elements.
|
||||||
|
func (r *Regexp) FindSubmatch(b []byte) [][]byte {
|
||||||
|
matches, err := r.match(b, 0, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if len(matches) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
match := matches[0]
|
||||||
|
|
||||||
|
out := make([][]byte, len(match))
|
||||||
|
for i := 0; i < len(match); i += 2 {
|
||||||
|
out[i] = b[match[i]:match[i+1]]
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindSubmatchIndex returns a slice of index pairs representing
|
||||||
|
// the match and submatches, if any.
|
||||||
|
func (r *Regexp) FindSubmatchIndex(b []byte) []int {
|
||||||
|
matches, err := r.match(b, 0, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if len(matches) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
match := matches[0]
|
||||||
|
|
||||||
|
out := make([]int, len(match))
|
||||||
|
for index, offset := range match {
|
||||||
|
out[index] = int(offset)
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindAllSubmatch returns a slice of all matches and submatches
|
||||||
|
// of the regular expression. It will return no more than n matches.
|
||||||
|
// If n < 0, it will return all matches.
|
||||||
|
func (r *Regexp) FindAllSubmatch(b []byte, n int) [][][]byte {
|
||||||
|
matches, err := r.match(b, 0, true)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if len(matches) == 0 || n == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if n > 0 && len(matches) > n {
|
||||||
|
matches = matches[:n]
|
||||||
|
}
|
||||||
|
|
||||||
|
out := make([][][]byte, len(matches))
|
||||||
|
for index, match := range matches {
|
||||||
|
var outMatch [][]byte
|
||||||
|
|
||||||
|
for i := 0; i < len(match); i += 2 {
|
||||||
|
outMatch = append(outMatch, b[match[i]:match[i+1]])
|
||||||
|
}
|
||||||
|
|
||||||
|
out[index] = outMatch
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindAllSubmatch returns a slice of all indeces representing the
|
||||||
|
// locations of matches and submatches, if any, of the regular expression.
|
||||||
|
// It will return no more than n matches. If n < 0, it will return all matches.
|
||||||
|
func (r *Regexp) FindAllSubmatchIndex(b []byte, n int) [][]int {
|
||||||
|
matches, err := r.match(b, 0, true)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if len(matches) == 0 || n == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if n > 0 && len(matches) > n {
|
||||||
|
matches = matches[:n]
|
||||||
|
}
|
||||||
|
|
||||||
|
out := make([][]int, len(matches))
|
||||||
|
for index, match := range matches {
|
||||||
|
offsets := make([]int, len(match))
|
||||||
|
|
||||||
|
for index, offset := range match {
|
||||||
|
offsets[index] = int(offset)
|
||||||
|
}
|
||||||
|
|
||||||
|
out[index] = offsets
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindString is the String version of Find
|
||||||
|
func (r *Regexp) FindString(s string) string {
|
||||||
|
return string(r.Find([]byte(s)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindStringIndex is the String version of FindIndex
|
||||||
|
func (r *Regexp) FindStringIndex(s string) []int {
|
||||||
|
return r.FindIndex([]byte(s))
|
||||||
|
}
|
||||||
|
|
||||||
|
// FinAllString is the String version of FindAll
|
||||||
|
func (r *Regexp) FindAllString(s string, n int) []string {
|
||||||
|
matches := r.FindAll([]byte(s), n)
|
||||||
|
out := make([]string, len(matches))
|
||||||
|
for index, match := range matches {
|
||||||
|
out[index] = string(match)
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindAllStringIndex is the String version of FindIndex
|
||||||
|
func (r *Regexp) FindAllStringIndex(s string, n int) [][]int {
|
||||||
|
return r.FindAllIndex([]byte(s), n)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindStringSubmatch is the string version of FindSubmatch
|
||||||
|
func (r *Regexp) FindStringSubmatch(s string) []string {
|
||||||
|
matches := r.FindSubmatch([]byte(s))
|
||||||
|
|
||||||
|
out := make([]string, len(matches))
|
||||||
|
for index, match := range matches {
|
||||||
|
out[index] = string(match)
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindStringSubmatchIndex is the String version of FindSubmatchIndex
|
||||||
|
func (r *Regexp) FindStringSubmatchIndex(s string) []int {
|
||||||
|
return r.FindSubmatchIndex([]byte(s))
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindAllStringSubmatch is the String version of FindAllSubmatch
|
||||||
|
func (r *Regexp) FindAllStringSubmatch(s string, n int) [][]string {
|
||||||
|
matches := r.FindAllSubmatch([]byte(s), n)
|
||||||
|
|
||||||
|
out := make([][]string, len(matches))
|
||||||
|
for index, match := range matches {
|
||||||
|
outMatch := make([]string, len(match))
|
||||||
|
|
||||||
|
for index, byteMatch := range match {
|
||||||
|
outMatch[index] = string(byteMatch)
|
||||||
|
}
|
||||||
|
|
||||||
|
out[index] = outMatch
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindAllStringSubmatchIndex is the String version of FindAllSubmatchIndex
|
||||||
|
func (r *Regexp) FindAllStringSubmatchIndex(s string, n int) [][]int {
|
||||||
|
return r.FindAllSubmatchIndex([]byte(s), n)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Match reports whether b contains a match of the regular expression
|
||||||
|
func (r *Regexp) Match(b []byte) bool {
|
||||||
|
return r.Find(b) != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MatchString is the String version of Match
|
||||||
|
func (r *Regexp) MatchString(s string) bool {
|
||||||
|
return r.Find([]byte(s)) != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NumSubexp returns the number of parenthesized subexpressions
|
||||||
|
// in the regular expression.
|
||||||
|
func (r *Regexp) NumSubexp() int {
|
||||||
|
return int(r.patternInfo(lib.DPCRE2_INFO_CAPTURECOUNT))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReplaceAll returns a copy of src, replacing matches of the
|
||||||
|
// regular expression with the replacement text repl.
|
||||||
|
// Inside repl, $ signs are interpreted as in Expand,
|
||||||
|
// so for instance $1 represents the text of the first
|
||||||
|
// submatch.
|
||||||
|
func (r *Regexp) ReplaceAll(src, repl []byte) []byte {
|
||||||
|
matches, err := r.match(src, 0, true)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if len(matches) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
out := make([]byte, len(src))
|
||||||
|
copy(out, src)
|
||||||
|
|
||||||
|
var diff int64
|
||||||
|
for _, match := range matches {
|
||||||
|
replStr := os.Expand(string(repl), func(s string) string {
|
||||||
|
i, err := strconv.Atoi(s)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there given match does not exist, return empty string
|
||||||
|
if i == 0 || len(match) < (2*i)+1 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return match
|
||||||
|
return string(src[match[2*i]:match[(2*i)+1]])
|
||||||
|
})
|
||||||
|
// Replace replacement string with expanded string
|
||||||
|
repl := []byte(replStr)
|
||||||
|
|
||||||
|
// Replace bytes with new replacement string
|
||||||
|
diff, out = replaceBytes(out, repl, match[0], match[1], diff)
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReplaceAllFunc returns a copy of src in which all matches of the
|
||||||
|
// regular expression have been replaced by the return value of function
|
||||||
|
// repl applied to the matched byte slice. The replacement returned by
|
||||||
|
// repl is substituted directly, without using Expand.
|
||||||
|
func (r *Regexp) ReplaceAllFunc(src []byte, repl func([]byte) []byte) []byte {
|
||||||
|
matches, err := r.match(src, 0, true)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if len(matches) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
out := make([]byte, len(src))
|
||||||
|
copy(out, src)
|
||||||
|
|
||||||
|
var diff int64
|
||||||
|
for _, match := range matches {
|
||||||
|
replBytes := repl(src[match[0]:match[1]])
|
||||||
|
diff, out = replaceBytes(out, replBytes, match[0], match[1], diff)
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReplaceAllLiteral returns a copy of src, replacing matches of
|
||||||
|
// the regular expression with the replacement bytes repl.
|
||||||
|
// The replacement is substituted directly, without using Expand.
|
||||||
|
func (r *Regexp) ReplaceAllLiteral(src, repl []byte) []byte {
|
||||||
|
matches, err := r.match(src, 0, true)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if len(matches) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
out := make([]byte, len(src))
|
||||||
|
copy(out, src)
|
||||||
|
|
||||||
|
var diff int64
|
||||||
|
for _, match := range matches {
|
||||||
|
diff, out = replaceBytes(out, repl, match[0], match[1], diff)
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReplaceAllString is the String version of ReplaceAll
|
||||||
|
func (r *Regexp) ReplaceAllString(src, repl string) string {
|
||||||
|
return string(r.ReplaceAll([]byte(src), []byte(repl)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReplaceAllStringFunc is the String version of ReplaceAllFunc
|
||||||
|
func (r *Regexp) ReplaceAllStringFunc(src string, repl func(string) string) string {
|
||||||
|
return string(r.ReplaceAllFunc([]byte(src), func(b []byte) []byte {
|
||||||
|
return []byte(repl(string(b)))
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReplaceAllLiteralString is the String version of ReplaceAllLiteral
|
||||||
|
func (r *Regexp) ReplaceAllLiteralString(src, repl string) string {
|
||||||
|
return string(r.ReplaceAllLiteral([]byte(src), []byte(repl)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Split slices s into substrings separated by the
|
||||||
|
// expression and returns a slice of the substrings
|
||||||
|
// between those expression matches.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
// s := regexp.MustCompile("a*").Split("abaabaccadaaae", 5)
|
||||||
|
// // s: ["", "b", "b", "c", "cadaaae"]
|
||||||
|
// The count determines the number of substrings to return:
|
||||||
|
// n > 0: at most n substrings; the last substring will be the unsplit remainder.
|
||||||
|
// n == 0: the result is nil (zero substrings)
|
||||||
|
// n < 0: all substrings
|
||||||
|
func (r *Regexp) Split(s string, n int) []string {
|
||||||
|
if n == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(r.expr) > 0 && len(s) == 0 {
|
||||||
|
return []string{""}
|
||||||
|
}
|
||||||
|
|
||||||
|
matches := r.FindAllStringIndex(s, n)
|
||||||
|
strings := make([]string, 0, len(matches))
|
||||||
|
|
||||||
|
beg := 0
|
||||||
|
end := 0
|
||||||
|
for _, match := range matches {
|
||||||
|
if n > 0 && len(strings) >= n-1 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
end = match[0]
|
||||||
|
if match[1] != 0 {
|
||||||
|
strings = append(strings, s[beg:end])
|
||||||
|
}
|
||||||
|
beg = match[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
if end != len(s) {
|
||||||
|
strings = append(strings, s[beg:])
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the text of the regular expression
|
||||||
|
// used for compilation.
|
||||||
|
func (r *Regexp) String() string {
|
||||||
|
return r.expr
|
||||||
|
}
|
||||||
|
|
||||||
|
// SubexpIndex returns the index of the subexpression
|
||||||
|
// with the given name, or -1 if there is no subexpression
|
||||||
|
// with that name.
|
||||||
|
func (r *Regexp) SubexpIndex(name string) int {
|
||||||
|
r.mtx.Lock()
|
||||||
|
defer r.mtx.Unlock()
|
||||||
|
|
||||||
|
// Get C string of name
|
||||||
|
cName, err := libc.CString(name)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get substring index from name
|
||||||
|
ret := lib.Xpcre2_substring_number_from_name_8(r.tls, r.re, cName)
|
||||||
|
|
||||||
|
// If no substring error returned, return -1.
|
||||||
|
// If a different error is returned, panic.
|
||||||
|
if ret == lib.DPCRE2_ERROR_NOSUBSTRING {
|
||||||
|
return -1
|
||||||
|
} else if ret < 0 {
|
||||||
|
panic(codeToError(r.tls, ret))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the index of the subexpression
|
||||||
|
return int(ret)
|
||||||
|
}
|
||||||
|
|
||||||
|
// replaceBytes replaces the bytes at a given location, and returns a new
|
||||||
|
// offset, based on how much bigger or smaller the slice got after replacement
|
||||||
|
func replaceBytes(src, repl []byte, sOff, eOff lib.Tsize_t, diff int64) (int64, []byte) {
|
||||||
|
var out []byte
|
||||||
|
out = append(
|
||||||
|
src[:int64(sOff)+diff],
|
||||||
|
append(
|
||||||
|
repl,
|
||||||
|
src[int64(eOff)+diff:]...,
|
||||||
|
)...,
|
||||||
|
)
|
||||||
|
|
||||||
|
return diff + int64(len(out)-len(src)), out
|
||||||
|
}
|
||||||
|
|
||||||
|
// match calls the underlying pcre match functions. It re-runs the functions
|
||||||
|
// until no matches are found if multi is set to true.
|
||||||
|
func (r *Regexp) match(b []byte, options uint32, multi bool) ([][]lib.Tsize_t, error) {
|
||||||
|
r.mtx.Lock()
|
||||||
|
defer r.mtx.Unlock()
|
||||||
|
|
||||||
|
// Create a C pointer to the subject
|
||||||
|
sp := unsafe.Pointer(&b[0])
|
||||||
|
cSubject := uintptr(sp)
|
||||||
|
// Convert the size of the subject to a C size_t type
|
||||||
|
cSubjectLen := lib.Tsize_t(len(b))
|
||||||
|
|
||||||
|
// Create match data using the pattern to figure out the buffer size
|
||||||
|
md := lib.Xpcre2_match_data_create_from_pattern_8(r.tls, r.re, 0)
|
||||||
|
if md == 0 {
|
||||||
|
panic("error creating match data")
|
||||||
|
}
|
||||||
|
// Free the match data at the end of the function
|
||||||
|
defer lib.Xpcre2_match_data_free_8(r.tls, md)
|
||||||
|
|
||||||
|
var offset lib.Tsize_t
|
||||||
|
var out [][]lib.Tsize_t
|
||||||
|
// While the offset is less than the length of the subject
|
||||||
|
for offset < cSubjectLen {
|
||||||
|
// Execute expression on subject
|
||||||
|
ret := lib.Xpcre2_match_8(r.tls, r.re, cSubject, cSubjectLen, offset, options, md, 0)
|
||||||
|
if ret < 0 {
|
||||||
|
// If no match found, break
|
||||||
|
if ret == lib.DPCRE2_ERROR_NOMATCH {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, codeToError(r.tls, ret)
|
||||||
|
} else {
|
||||||
|
// Get amount of pairs in output vector
|
||||||
|
pairAmt := lib.Xpcre2_get_ovector_count_8(r.tls, md)
|
||||||
|
// Get pointer to output vector
|
||||||
|
ovec := lib.Xpcre2_get_ovector_pointer_8(r.tls, md)
|
||||||
|
// Create a Go slice using the output vector as the underlying array
|
||||||
|
slice := unsafe.Slice((*lib.Tsize_t)(unsafe.Pointer(ovec)), pairAmt*2)
|
||||||
|
|
||||||
|
// Create a new slice and copy the elements from the slice
|
||||||
|
// This is required because the match data will be freed in
|
||||||
|
// a defer, and that would cause a panic every time the slice
|
||||||
|
// is used later.
|
||||||
|
matches := make([]lib.Tsize_t, len(slice))
|
||||||
|
copy(matches, slice)
|
||||||
|
|
||||||
|
// If the two indices are the same (empty string), and the match is not
|
||||||
|
// immediately after another match, add it to the output and increment the
|
||||||
|
// offset. Otherwise, increment the offset and ignore the match.
|
||||||
|
if slice[0] == slice[1] && len(out) > 0 && slice[0] != out[len(out)-1][1] {
|
||||||
|
out = append(out, matches)
|
||||||
|
offset = slice[1] + 1
|
||||||
|
continue
|
||||||
|
} else if slice[0] == slice[1] {
|
||||||
|
offset = slice[1] + 1
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the match to the output
|
||||||
|
out = append(out, matches)
|
||||||
|
// Set the next offset to the end index of the match
|
||||||
|
offset = matches[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// If multiple matches disabled, break
|
||||||
|
if !multi {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// patternInfo calls the underlying pcre pattern info function
|
||||||
|
// and returns information about the compiled regular expression
|
||||||
|
func (r *Regexp) patternInfo(what uint32) (out uint32) {
|
||||||
|
// Create a C pointer to the output integer
|
||||||
|
cOut := uintptr(unsafe.Pointer(&out))
|
||||||
|
// Get information about the compiled pattern
|
||||||
|
lib.Xpcre2_pattern_info_8(r.tls, r.re, what, cOut)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close frees resources used by the regular expression.
|
||||||
|
func (r *Regexp) Close() error {
|
||||||
|
if r == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close thread-local storage
|
||||||
|
defer r.tls.Close()
|
||||||
|
|
||||||
|
// Free the compiled code
|
||||||
|
lib.Xpcre2_code_free_8(r.tls, r.re)
|
||||||
|
// Set regular expression to null
|
||||||
|
r.re = 0
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,236 @@
|
||||||
|
package pcre_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"go.arsenm.dev/pcre"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCompileError(t *testing.T) {
|
||||||
|
r, err := pcre.Compile("(")
|
||||||
|
if err == nil {
|
||||||
|
t.Error("expected error, got nil")
|
||||||
|
}
|
||||||
|
defer r.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMatch(t *testing.T) {
|
||||||
|
r := pcre.MustCompile(`\d+ (?=USD)`)
|
||||||
|
defer r.Close()
|
||||||
|
|
||||||
|
matches := r.MatchString("9000 USD")
|
||||||
|
if !matches {
|
||||||
|
t.Error("expected 9000 USD to match")
|
||||||
|
}
|
||||||
|
|
||||||
|
matches = r.MatchString("9000 RUB")
|
||||||
|
if matches {
|
||||||
|
t.Error("expected 9000 RUB not to match")
|
||||||
|
}
|
||||||
|
|
||||||
|
matches = r.MatchString("800 USD")
|
||||||
|
if !matches {
|
||||||
|
t.Error("expected 800 USD to match")
|
||||||
|
}
|
||||||
|
|
||||||
|
matches = r.MatchString("700 CAD")
|
||||||
|
if matches {
|
||||||
|
t.Error("expected 700 CAD not to match")
|
||||||
|
}
|
||||||
|
|
||||||
|
matches = r.Match([]byte("8 USD"))
|
||||||
|
if !matches {
|
||||||
|
t.Error("expected 8 USD to match")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMatchUngreedy(t *testing.T) {
|
||||||
|
r := pcre.MustCompileOpts(`Hello, (.+)\.`, pcre.Ungreedy)
|
||||||
|
defer r.Close()
|
||||||
|
|
||||||
|
submatches := r.FindAllStringSubmatch("Hello, World. Hello, pcre2.", 1)
|
||||||
|
if submatches[0][1] != "World" {
|
||||||
|
t.Errorf("expected World, got %s", submatches[0][1])
|
||||||
|
}
|
||||||
|
|
||||||
|
matches := r.MatchString("hello, world.")
|
||||||
|
if matches {
|
||||||
|
t.Error("expected lowercase 'hello, world' not to match")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReplace(t *testing.T) {
|
||||||
|
r := pcre.MustCompile(`(\d+)\.\d+`)
|
||||||
|
defer r.Close()
|
||||||
|
|
||||||
|
testStr := "123.54321 Test"
|
||||||
|
|
||||||
|
newStr := r.ReplaceAllString(testStr, "${1}.12345")
|
||||||
|
if newStr != "123.12345 Test" {
|
||||||
|
t.Errorf(`expected "123.12345 Test", got "%s"`, newStr)
|
||||||
|
}
|
||||||
|
|
||||||
|
newStr = r.ReplaceAllString(testStr, "${9}.12345")
|
||||||
|
if newStr != ".12345 Test" {
|
||||||
|
t.Errorf(`expected ".12345 Test", got "%s"`, newStr)
|
||||||
|
}
|
||||||
|
|
||||||
|
newStr = r.ReplaceAllString(testStr, "${hi}.12345")
|
||||||
|
if newStr != ".12345 Test" {
|
||||||
|
t.Errorf(`expected ".12345 Test", got "%s"`, newStr)
|
||||||
|
}
|
||||||
|
|
||||||
|
newStr = r.ReplaceAllLiteralString(testStr, "${1}.12345")
|
||||||
|
if newStr != "${1}.12345 Test" {
|
||||||
|
t.Errorf(`expected "${1}.12345 Test", got "%s"`, newStr)
|
||||||
|
}
|
||||||
|
|
||||||
|
newStr = r.ReplaceAllStringFunc(testStr, func(s string) string {
|
||||||
|
return strings.Replace(s, ".", ",", -1)
|
||||||
|
})
|
||||||
|
if newStr != "123,54321 Test" {
|
||||||
|
t.Errorf(`expected "123,54321 Test", got "%s"`, newStr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSplit(t *testing.T) {
|
||||||
|
r := pcre.MustCompile("a*")
|
||||||
|
defer r.Close()
|
||||||
|
|
||||||
|
split := r.Split("abaabaccadaaae", 5)
|
||||||
|
expected := [5]string{"", "b", "b", "c", "cadaaae"}
|
||||||
|
|
||||||
|
if *(*[5]string)(split) != expected {
|
||||||
|
t.Errorf("expected %v, got %v", expected, split)
|
||||||
|
}
|
||||||
|
|
||||||
|
split = r.Split("", 0)
|
||||||
|
if split != nil {
|
||||||
|
t.Errorf("expected nil, got %v", split)
|
||||||
|
}
|
||||||
|
|
||||||
|
split = r.Split("", 5)
|
||||||
|
if split[0] != "" {
|
||||||
|
t.Errorf(`expected []string{""}, got %v`, split)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFind(t *testing.T) {
|
||||||
|
r := pcre.MustCompile(`(\d+)`)
|
||||||
|
defer r.Close()
|
||||||
|
|
||||||
|
testStr := "3 times 4 is 12"
|
||||||
|
|
||||||
|
matches := r.FindAllString(testStr, -1)
|
||||||
|
if len(matches) != 3 {
|
||||||
|
t.Errorf("expected length 3, got %d", len(matches))
|
||||||
|
}
|
||||||
|
|
||||||
|
matches = r.FindAllString(testStr, 2)
|
||||||
|
if len(matches) != 2 {
|
||||||
|
t.Errorf("expected length 2, got %d", len(matches))
|
||||||
|
}
|
||||||
|
if matches[0] != "3" || matches[1] != "4" {
|
||||||
|
t.Errorf("expected [3 4], got %v", matches)
|
||||||
|
}
|
||||||
|
|
||||||
|
index := r.FindStringIndex(testStr)
|
||||||
|
if index[0] != 0 || index[1] != 1 {
|
||||||
|
t.Errorf("expected [0 1], got %v", index)
|
||||||
|
}
|
||||||
|
|
||||||
|
submatch := r.FindStringSubmatch(testStr)
|
||||||
|
if submatch[0] != "3" {
|
||||||
|
t.Errorf("expected 3, got %s", submatch[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
index = r.FindStringSubmatchIndex(testStr)
|
||||||
|
if *(*[4]int)(index) != [4]int{0, 1, 0, 1} {
|
||||||
|
t.Errorf("expected [0 1 0 1], got %v", index)
|
||||||
|
}
|
||||||
|
|
||||||
|
submatches := r.FindAllStringSubmatchIndex(testStr, 2)
|
||||||
|
if len(submatches) != 2 {
|
||||||
|
t.Errorf("expected length 2, got %d", len(submatches))
|
||||||
|
}
|
||||||
|
|
||||||
|
expected := [2][4]int{{0, 1, 0, 1}, {8, 9, 8, 9}}
|
||||||
|
if *(*[4]int)(submatches[0]) != expected[0] {
|
||||||
|
t.Errorf("expected %v, got %v", expected[0], submatches[0])
|
||||||
|
}
|
||||||
|
if *(*[4]int)(submatches[1]) != expected[1] {
|
||||||
|
t.Errorf("expected %v, got %v", expected[0], submatches[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSubexpIndex(t *testing.T) {
|
||||||
|
r := pcre.MustCompile(`(?P<number>\d)`)
|
||||||
|
defer r.Close()
|
||||||
|
|
||||||
|
index := r.SubexpIndex("number")
|
||||||
|
if index != 1 {
|
||||||
|
t.Errorf("expected 1, got %d", index)
|
||||||
|
}
|
||||||
|
|
||||||
|
index = r.SubexpIndex("string")
|
||||||
|
if index != -1 {
|
||||||
|
t.Errorf("expected -1, got %d", index)
|
||||||
|
}
|
||||||
|
|
||||||
|
num := r.NumSubexp()
|
||||||
|
if num != 1 {
|
||||||
|
t.Errorf("expected 1, got %d", num)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestConcurrency(t *testing.T) {
|
||||||
|
r := pcre.MustCompile(`\d*`)
|
||||||
|
defer r.Close()
|
||||||
|
|
||||||
|
wg := &sync.WaitGroup{}
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
|
||||||
|
found := r.FindString("Test string 12345")
|
||||||
|
if found != "12345" {
|
||||||
|
t.Errorf("expected 12345, got %s", found)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
|
||||||
|
matched := r.MatchString("Hello")
|
||||||
|
if matched {
|
||||||
|
t.Errorf("Expected Hello not to match")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
|
||||||
|
matched := r.MatchString("54321")
|
||||||
|
if !matched {
|
||||||
|
t.Errorf("expected 54321 to match")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestString(t *testing.T) {
|
||||||
|
const expr = `()`
|
||||||
|
|
||||||
|
r := pcre.MustCompile(expr)
|
||||||
|
defer r.Close()
|
||||||
|
|
||||||
|
if r.String() != expr {
|
||||||
|
t.Errorf("expected %s, got %s", expr, r.String())
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package pcre
|
||||||
|
|
||||||
|
import "go.arsenm.dev/pcre/lib"
|
||||||
|
|
||||||
|
type CompileOption uint32
|
||||||
|
|
||||||
|
// Compile option bits
|
||||||
|
const (
|
||||||
|
Anchored = CompileOption(lib.DPCRE2_ANCHORED)
|
||||||
|
AllowEmptyClass = CompileOption(lib.DPCRE2_ALLOW_EMPTY_CLASS)
|
||||||
|
AltBsux = CompileOption(lib.DPCRE2_ALT_BSUX)
|
||||||
|
AltCircumflex = CompileOption(lib.DPCRE2_ALT_CIRCUMFLEX)
|
||||||
|
AltVerbnames = CompileOption(lib.DPCRE2_ALT_VERBNAMES)
|
||||||
|
AutoCallout = CompileOption(lib.DPCRE2_AUTO_CALLOUT)
|
||||||
|
Caseless = CompileOption(lib.DPCRE2_CASELESS)
|
||||||
|
DollarEndOnly = CompileOption(lib.DPCRE2_DOLLAR_ENDONLY)
|
||||||
|
DotAll = CompileOption(lib.DPCRE2_DOTALL)
|
||||||
|
DupNames = CompileOption(lib.DPCRE2_DUPNAMES)
|
||||||
|
EndAnchored = CompileOption(lib.DPCRE2_ENDANCHORED)
|
||||||
|
Extended = CompileOption(lib.DPCRE2_EXTENDED)
|
||||||
|
FirstLine = CompileOption(lib.DPCRE2_FIRSTLINE)
|
||||||
|
Literal = CompileOption(lib.DPCRE2_LITERAL)
|
||||||
|
MatchInvalidUTF = CompileOption(lib.DPCRE2_MATCH_INVALID_UTF)
|
||||||
|
MactchUnsetBackref = CompileOption(lib.DPCRE2_MATCH_UNSET_BACKREF)
|
||||||
|
Multiline = CompileOption(lib.DPCRE2_MULTILINE)
|
||||||
|
NeverBackslashC = CompileOption(lib.DPCRE2_NEVER_BACKSLASH_C)
|
||||||
|
NeverUCP = CompileOption(lib.DPCRE2_NEVER_UCP)
|
||||||
|
NeverUTF = CompileOption(lib.DPCRE2_NEVER_UTF)
|
||||||
|
NoAutoCapture = CompileOption(lib.DPCRE2_NO_AUTO_CAPTURE)
|
||||||
|
NoAutoPossess = CompileOption(lib.DPCRE2_NO_AUTO_POSSESS)
|
||||||
|
NoDotStarAnchor = CompileOption(lib.DPCRE2_NO_DOTSTAR_ANCHOR)
|
||||||
|
NoStartOptimize = CompileOption(lib.DPCRE2_NO_START_OPTIMIZE)
|
||||||
|
NoUTFCheck = CompileOption(lib.DPCRE2_NO_UTF_CHECK)
|
||||||
|
UCP = CompileOption(lib.DPCRE2_UCP)
|
||||||
|
Ungreedy = CompileOption(lib.DPCRE2_UNGREEDY)
|
||||||
|
UseOffsetLimit = CompileOption(lib.DPCRE2_USE_OFFSET_LIMIT)
|
||||||
|
UTF = CompileOption(lib.DPCRE2_UTF)
|
||||||
|
)
|
Loading…
Reference in New Issue