forked from Elara6331/pcre
Initial Commit
This commit is contained in:
commit
406de00b82
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -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.
|
94
LICENSE-PCRE2
Normal file
94
LICENSE-PCRE2
Normal file
@ -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
|
42
README.md
Normal file
42
README.md
Normal file
@ -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.
|
82
error.go
Normal file
82
error.go
Normal file
@ -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)
|
||||||
|
}
|
14
go.mod
Normal file
14
go.mod
Normal file
@ -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
|
||||||
|
)
|
55
go.sum
Normal file
55
go.sum
Normal file
@ -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=
|
128
lib/capi_linux_386.go
Normal file
128
lib/capi_linux_386.go
Normal file
@ -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": {},
|
||||||
|
}
|
128
lib/capi_linux_amd64.go
Normal file
128
lib/capi_linux_amd64.go
Normal file
@ -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": {},
|
||||||
|
}
|
128
lib/capi_linux_arm.go
Normal file
128
lib/capi_linux_arm.go
Normal file
@ -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": {},
|
||||||
|
}
|
128
lib/capi_linux_arm64.go
Normal file
128
lib/capi_linux_arm64.go
Normal file
@ -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": {},
|
||||||
|
}
|
128
lib/capi_linux_riscv64.go
Normal file
128
lib/capi_linux_riscv64.go
Normal file
@ -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": {},
|
||||||
|
}
|
70944
lib/pcre2_linux_386.go
Normal file
70944
lib/pcre2_linux_386.go
Normal file
File diff suppressed because one or more lines are too long
70962
lib/pcre2_linux_amd64.go
Normal file
70962
lib/pcre2_linux_amd64.go
Normal file
File diff suppressed because one or more lines are too long
70944
lib/pcre2_linux_arm.go
Normal file
70944
lib/pcre2_linux_arm.go
Normal file
File diff suppressed because one or more lines are too long
70962
lib/pcre2_linux_arm64.go
Normal file
70962
lib/pcre2_linux_arm64.go
Normal file
File diff suppressed because one or more lines are too long
70961
lib/pcre2_linux_riscv64.go
Normal file
70961
lib/pcre2_linux_riscv64.go
Normal file
File diff suppressed because one or more lines are too long
665
pcre.go
Normal file
665
pcre.go
Normal file
@ -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
|
||||||
|
}
|
236
pcre_test.go
Normal file
236
pcre_test.go
Normal file
@ -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())
|
||||||
|
}
|
||||||
|
}
|
38
types.go
Normal file
38
types.go
Normal file
@ -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
Block a user