PyPcre 0.2.2__tar.gz → 0.2.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pypcre-0.2.2 → pypcre-0.2.4}/PKG-INFO +26 -10
- {pypcre-0.2.2 → pypcre-0.2.4}/PyPcre.egg-info/PKG-INFO +26 -10
- {pypcre-0.2.2 → pypcre-0.2.4}/PyPcre.egg-info/SOURCES.txt +3 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/README.md +25 -9
- {pypcre-0.2.2 → pypcre-0.2.4}/pcre/__init__.py +24 -2
- {pypcre-0.2.2 → pypcre-0.2.4}/pcre/pcre.py +0 -6
- {pypcre-0.2.2 → pypcre-0.2.4}/pcre_ext/cache.c +0 -18
- pypcre-0.2.4/pcre_ext/jit_support.c +151 -0
- pypcre-0.2.4/pcre_ext/pattern_cache.c +347 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/pcre_ext/pcre2.c +21 -797
- {pypcre-0.2.2 → pypcre-0.2.4}/pcre_ext/pcre2_module.h +24 -0
- pypcre-0.2.4/pcre_ext/string_helpers.c +370 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/pcre_ext/util.c +18 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/pyproject.toml +1 -1
- {pypcre-0.2.2 → pypcre-0.2.4}/setup.py +6 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/setup_utils.py +152 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/tests/test_api_parity.py +41 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/tests/test_clobber.py +0 -3
- {pypcre-0.2.2 → pypcre-0.2.4}/tests/test_module.py +0 -4
- {pypcre-0.2.2 → pypcre-0.2.4}/LICENSE +0 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/MANIFEST.in +0 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/PyPcre.egg-info/dependency_links.txt +0 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/PyPcre.egg-info/top_level.txt +0 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/pcre/cache.py +0 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/pcre/error.py +0 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/pcre/flags.py +0 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/pcre/re_compat.py +0 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/pcre/threads.py +0 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/pcre_ext/atomic_compat.h +0 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/pcre_ext/error.c +0 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/pcre_ext/flag.c +0 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/pcre_ext/memory.c +0 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/pcre_ext/pcre2.h +0 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/setup.cfg +0 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/tests/test_accuracy.py +0 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/tests/test_basic.py +0 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/tests/test_bench_string.py +0 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/tests/test_benchmark.py +0 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/tests/test_bytes.py +0 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/tests/test_cache.py +0 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/tests/test_clobber_thread.py +0 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/tests/test_core.py +0 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/tests/test_errors.py +0 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/tests/test_flags.py +0 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/tests/test_jit.py +0 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/tests/test_memory.py +0 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/tests/test_pattern.py +0 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/tests/test_simd.py +0 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/tests/test_threaded_backend.py +0 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/tests/test_transformers_regex.py +0 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/tests/test_utf8.py +0 -0
- {pypcre-0.2.2 → pypcre-0.2.4}/tests/test_version.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyPcre
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.4
|
|
4
4
|
Summary: Modern, GIL-friendly, Fast Python bindings for PCRE2 with auto caching and JIT of compiled patterns.
|
|
5
5
|
Author-email: ModelCloud <qubitium@modelcloud.ai>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -32,7 +32,7 @@ Dynamic: license-file
|
|
|
32
32
|
|
|
33
33
|
# PyPcre (Python Pcre2 Binding)
|
|
34
34
|
|
|
35
|
-
Python bindings for the
|
|
35
|
+
Modern `nogil` Python bindings for the Pcre2 library with `stdlib.re` api compatibility.
|
|
36
36
|
|
|
37
37
|
<p align="center">
|
|
38
38
|
<a href="https://github.com/ModelCloud/PyPcre/releases" style="text-decoration:none;"><img alt="GitHub release" src="https://img.shields.io/github/release/ModelCloud/Pcre.svg"></a>
|
|
@@ -43,7 +43,7 @@ Python bindings for the system PCRE2 library with a familiar `re`-style API.
|
|
|
43
43
|
</p>
|
|
44
44
|
|
|
45
45
|
## Latest News
|
|
46
|
-
* 10/
|
|
46
|
+
* 10/12/2025 [0.2.3](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.3): 🤗 Full `GIL=0` compliance for Python >= 3.13T. Reduced cache thread contention. Improved performance for all api. Expanded ci testing coverage. FreeBSD, Solaris, and Windows compatibility validated.
|
|
47
47
|
* 10/09/2025 [0.1.0](https://github.com/ModelCloud/PyPcre/releases/tag/v0.1.0): 🎉 First release. Thread safe, auto JIT, auto pattern caching and optimistic linking to system library for fast install.
|
|
48
48
|
|
|
49
49
|
## Why PyPcre:
|
|
@@ -64,9 +64,29 @@ pip install PyPcre
|
|
|
64
64
|
|
|
65
65
|
The package prioritizes linking against the `libpcre2-8` shared library in system for fast install and max security protection which gets latest patches from OS. See [Building](#building) for manual build details.
|
|
66
66
|
|
|
67
|
+
## Platform Support (Validated):
|
|
68
|
+
|
|
69
|
+
`Linux`, `MacOS`, `Windows`, `WSL`, `FreeBSD`, `Solaris`
|
|
70
|
+
|
|
71
|
+
|
|
67
72
|
## Usage
|
|
68
73
|
|
|
69
|
-
|
|
74
|
+
|
|
75
|
+
If you already rely on the standard library `re`, migrating is as
|
|
76
|
+
simple as changing your import:
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
import pcre as re
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
The module-level entry points (`match`, `search`, `fullmatch`, `findall`,
|
|
83
|
+
`finditer`, `split`, `sub`, `subn`, `compile`, `escape`, `purge`) expose the
|
|
84
|
+
same call signatures as their `re` counterparts, making existing code work
|
|
85
|
+
unchanged. Every standard flag with a PCRE2 equivalent—`IGNORECASE`,
|
|
86
|
+
`MULTILINE`, `DOTALL`, `VERBOSE`, `ASCII`, and friends—is supported via the
|
|
87
|
+
re-exported constants and the `pcre.Flag` enum.
|
|
88
|
+
|
|
89
|
+
### Sample Usage
|
|
70
90
|
|
|
71
91
|
```python
|
|
72
92
|
from pcre import match, search, findall, compile, Flag
|
|
@@ -78,15 +98,11 @@ pattern = compile(rb"\d+", flags=Flag.MULTILINE)
|
|
|
78
98
|
numbers = pattern.findall(b"line 1\nline 22")
|
|
79
99
|
```
|
|
80
100
|
|
|
81
|
-
`pcre` mirrors the core helpers from Python’s standard library `re` module
|
|
82
|
-
`match`, `search`, `fullmatch`, `finditer`, `findall`, and `compile
|
|
101
|
+
`pcre` mirrors the core helpers from Python’s standard library `re` module
|
|
102
|
+
`match`, `search`, `fullmatch`, `finditer`, `findall`, and `compile` while
|
|
83
103
|
exposing PCRE2’s extended flag set through the Pythonic `Flag` enum
|
|
84
104
|
(`Flag.CASELESS`, `Flag.MULTILINE`, `Flag.UTF`, ...).
|
|
85
105
|
|
|
86
|
-
### Platform Support:
|
|
87
|
-
|
|
88
|
-
Linux, MacOS, Windows, WSL, FreeBSD, Solaris
|
|
89
|
-
|
|
90
106
|
### Stdlib `re` compatibility
|
|
91
107
|
|
|
92
108
|
- Module-level helpers and the `Pattern` class follow the same call shapes as
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyPcre
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.4
|
|
4
4
|
Summary: Modern, GIL-friendly, Fast Python bindings for PCRE2 with auto caching and JIT of compiled patterns.
|
|
5
5
|
Author-email: ModelCloud <qubitium@modelcloud.ai>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -32,7 +32,7 @@ Dynamic: license-file
|
|
|
32
32
|
|
|
33
33
|
# PyPcre (Python Pcre2 Binding)
|
|
34
34
|
|
|
35
|
-
Python bindings for the
|
|
35
|
+
Modern `nogil` Python bindings for the Pcre2 library with `stdlib.re` api compatibility.
|
|
36
36
|
|
|
37
37
|
<p align="center">
|
|
38
38
|
<a href="https://github.com/ModelCloud/PyPcre/releases" style="text-decoration:none;"><img alt="GitHub release" src="https://img.shields.io/github/release/ModelCloud/Pcre.svg"></a>
|
|
@@ -43,7 +43,7 @@ Python bindings for the system PCRE2 library with a familiar `re`-style API.
|
|
|
43
43
|
</p>
|
|
44
44
|
|
|
45
45
|
## Latest News
|
|
46
|
-
* 10/
|
|
46
|
+
* 10/12/2025 [0.2.3](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.3): 🤗 Full `GIL=0` compliance for Python >= 3.13T. Reduced cache thread contention. Improved performance for all api. Expanded ci testing coverage. FreeBSD, Solaris, and Windows compatibility validated.
|
|
47
47
|
* 10/09/2025 [0.1.0](https://github.com/ModelCloud/PyPcre/releases/tag/v0.1.0): 🎉 First release. Thread safe, auto JIT, auto pattern caching and optimistic linking to system library for fast install.
|
|
48
48
|
|
|
49
49
|
## Why PyPcre:
|
|
@@ -64,9 +64,29 @@ pip install PyPcre
|
|
|
64
64
|
|
|
65
65
|
The package prioritizes linking against the `libpcre2-8` shared library in system for fast install and max security protection which gets latest patches from OS. See [Building](#building) for manual build details.
|
|
66
66
|
|
|
67
|
+
## Platform Support (Validated):
|
|
68
|
+
|
|
69
|
+
`Linux`, `MacOS`, `Windows`, `WSL`, `FreeBSD`, `Solaris`
|
|
70
|
+
|
|
71
|
+
|
|
67
72
|
## Usage
|
|
68
73
|
|
|
69
|
-
|
|
74
|
+
|
|
75
|
+
If you already rely on the standard library `re`, migrating is as
|
|
76
|
+
simple as changing your import:
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
import pcre as re
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
The module-level entry points (`match`, `search`, `fullmatch`, `findall`,
|
|
83
|
+
`finditer`, `split`, `sub`, `subn`, `compile`, `escape`, `purge`) expose the
|
|
84
|
+
same call signatures as their `re` counterparts, making existing code work
|
|
85
|
+
unchanged. Every standard flag with a PCRE2 equivalent—`IGNORECASE`,
|
|
86
|
+
`MULTILINE`, `DOTALL`, `VERBOSE`, `ASCII`, and friends—is supported via the
|
|
87
|
+
re-exported constants and the `pcre.Flag` enum.
|
|
88
|
+
|
|
89
|
+
### Sample Usage
|
|
70
90
|
|
|
71
91
|
```python
|
|
72
92
|
from pcre import match, search, findall, compile, Flag
|
|
@@ -78,15 +98,11 @@ pattern = compile(rb"\d+", flags=Flag.MULTILINE)
|
|
|
78
98
|
numbers = pattern.findall(b"line 1\nline 22")
|
|
79
99
|
```
|
|
80
100
|
|
|
81
|
-
`pcre` mirrors the core helpers from Python’s standard library `re` module
|
|
82
|
-
`match`, `search`, `fullmatch`, `finditer`, `findall`, and `compile
|
|
101
|
+
`pcre` mirrors the core helpers from Python’s standard library `re` module
|
|
102
|
+
`match`, `search`, `fullmatch`, `finditer`, `findall`, and `compile` while
|
|
83
103
|
exposing PCRE2’s extended flag set through the Pythonic `Flag` enum
|
|
84
104
|
(`Flag.CASELESS`, `Flag.MULTILINE`, `Flag.UTF`, ...).
|
|
85
105
|
|
|
86
|
-
### Platform Support:
|
|
87
|
-
|
|
88
|
-
Linux, MacOS, Windows, WSL, FreeBSD, Solaris
|
|
89
|
-
|
|
90
106
|
### Stdlib `re` compatibility
|
|
91
107
|
|
|
92
108
|
- Module-level helpers and the `Pattern` class follow the same call shapes as
|
|
@@ -19,10 +19,13 @@ pcre_ext/atomic_compat.h
|
|
|
19
19
|
pcre_ext/cache.c
|
|
20
20
|
pcre_ext/error.c
|
|
21
21
|
pcre_ext/flag.c
|
|
22
|
+
pcre_ext/jit_support.c
|
|
22
23
|
pcre_ext/memory.c
|
|
24
|
+
pcre_ext/pattern_cache.c
|
|
23
25
|
pcre_ext/pcre2.c
|
|
24
26
|
pcre_ext/pcre2.h
|
|
25
27
|
pcre_ext/pcre2_module.h
|
|
28
|
+
pcre_ext/string_helpers.c
|
|
26
29
|
pcre_ext/util.c
|
|
27
30
|
tests/test_accuracy.py
|
|
28
31
|
tests/test_api_parity.py
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
# PyPcre (Python Pcre2 Binding)
|
|
9
9
|
|
|
10
|
-
Python bindings for the
|
|
10
|
+
Modern `nogil` Python bindings for the Pcre2 library with `stdlib.re` api compatibility.
|
|
11
11
|
|
|
12
12
|
<p align="center">
|
|
13
13
|
<a href="https://github.com/ModelCloud/PyPcre/releases" style="text-decoration:none;"><img alt="GitHub release" src="https://img.shields.io/github/release/ModelCloud/Pcre.svg"></a>
|
|
@@ -18,7 +18,7 @@ Python bindings for the system PCRE2 library with a familiar `re`-style API.
|
|
|
18
18
|
</p>
|
|
19
19
|
|
|
20
20
|
## Latest News
|
|
21
|
-
* 10/
|
|
21
|
+
* 10/12/2025 [0.2.3](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.3): 🤗 Full `GIL=0` compliance for Python >= 3.13T. Reduced cache thread contention. Improved performance for all api. Expanded ci testing coverage. FreeBSD, Solaris, and Windows compatibility validated.
|
|
22
22
|
* 10/09/2025 [0.1.0](https://github.com/ModelCloud/PyPcre/releases/tag/v0.1.0): 🎉 First release. Thread safe, auto JIT, auto pattern caching and optimistic linking to system library for fast install.
|
|
23
23
|
|
|
24
24
|
## Why PyPcre:
|
|
@@ -39,9 +39,29 @@ pip install PyPcre
|
|
|
39
39
|
|
|
40
40
|
The package prioritizes linking against the `libpcre2-8` shared library in system for fast install and max security protection which gets latest patches from OS. See [Building](#building) for manual build details.
|
|
41
41
|
|
|
42
|
+
## Platform Support (Validated):
|
|
43
|
+
|
|
44
|
+
`Linux`, `MacOS`, `Windows`, `WSL`, `FreeBSD`, `Solaris`
|
|
45
|
+
|
|
46
|
+
|
|
42
47
|
## Usage
|
|
43
48
|
|
|
44
|
-
|
|
49
|
+
|
|
50
|
+
If you already rely on the standard library `re`, migrating is as
|
|
51
|
+
simple as changing your import:
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
import pcre as re
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
The module-level entry points (`match`, `search`, `fullmatch`, `findall`,
|
|
58
|
+
`finditer`, `split`, `sub`, `subn`, `compile`, `escape`, `purge`) expose the
|
|
59
|
+
same call signatures as their `re` counterparts, making existing code work
|
|
60
|
+
unchanged. Every standard flag with a PCRE2 equivalent—`IGNORECASE`,
|
|
61
|
+
`MULTILINE`, `DOTALL`, `VERBOSE`, `ASCII`, and friends—is supported via the
|
|
62
|
+
re-exported constants and the `pcre.Flag` enum.
|
|
63
|
+
|
|
64
|
+
### Sample Usage
|
|
45
65
|
|
|
46
66
|
```python
|
|
47
67
|
from pcre import match, search, findall, compile, Flag
|
|
@@ -53,15 +73,11 @@ pattern = compile(rb"\d+", flags=Flag.MULTILINE)
|
|
|
53
73
|
numbers = pattern.findall(b"line 1\nline 22")
|
|
54
74
|
```
|
|
55
75
|
|
|
56
|
-
`pcre` mirrors the core helpers from Python’s standard library `re` module
|
|
57
|
-
`match`, `search`, `fullmatch`, `finditer`, `findall`, and `compile
|
|
76
|
+
`pcre` mirrors the core helpers from Python’s standard library `re` module
|
|
77
|
+
`match`, `search`, `fullmatch`, `finditer`, `findall`, and `compile` while
|
|
58
78
|
exposing PCRE2’s extended flag set through the Pythonic `Flag` enum
|
|
59
79
|
(`Flag.CASELESS`, `Flag.MULTILINE`, `Flag.UTF`, ...).
|
|
60
80
|
|
|
61
|
-
### Platform Support:
|
|
62
|
-
|
|
63
|
-
Linux, MacOS, Windows, WSL, FreeBSD, Solaris
|
|
64
|
-
|
|
65
81
|
### Stdlib `re` compatibility
|
|
66
82
|
|
|
67
83
|
- Module-level helpers and the `Pattern` class follow the same call shapes as
|
|
@@ -32,7 +32,6 @@ from .pcre import (
|
|
|
32
32
|
finditer,
|
|
33
33
|
fullmatch,
|
|
34
34
|
match,
|
|
35
|
-
module_fullmatch,
|
|
36
35
|
parallel_map,
|
|
37
36
|
search,
|
|
38
37
|
split,
|
|
@@ -80,6 +79,28 @@ def escape(pattern: Any) -> Any:
|
|
|
80
79
|
return _std_re.escape(pattern)
|
|
81
80
|
|
|
82
81
|
|
|
82
|
+
# Compat: expose stdlib-style flag constants so migrating `re` users can
|
|
83
|
+
# continue referencing familiar names. Prefer `pcre.Flag` for new code.
|
|
84
|
+
_FLAG_ZERO = Flag(0)
|
|
85
|
+
_FLAG_COMPAT_ALIASES = {
|
|
86
|
+
"IGNORECASE": Flag.CASELESS,
|
|
87
|
+
"I": Flag.CASELESS,
|
|
88
|
+
"MULTILINE": Flag.MULTILINE,
|
|
89
|
+
"M": Flag.MULTILINE,
|
|
90
|
+
"DOTALL": Flag.DOTALL,
|
|
91
|
+
"S": Flag.DOTALL,
|
|
92
|
+
"VERBOSE": Flag.EXTENDED,
|
|
93
|
+
"X": Flag.EXTENDED,
|
|
94
|
+
"ASCII": Flag.NO_UTF | Flag.NO_UCP,
|
|
95
|
+
"A": Flag.NO_UTF | Flag.NO_UCP,
|
|
96
|
+
"UNICODE": _FLAG_ZERO,
|
|
97
|
+
"U": _FLAG_ZERO,
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
for _alias, _flag in _FLAG_COMPAT_ALIASES.items():
|
|
101
|
+
globals()[_alias] = _flag
|
|
102
|
+
|
|
103
|
+
|
|
83
104
|
__all__ = [
|
|
84
105
|
"Pattern",
|
|
85
106
|
"Match",
|
|
@@ -97,7 +118,6 @@ __all__ = [
|
|
|
97
118
|
"match",
|
|
98
119
|
"search",
|
|
99
120
|
"fullmatch",
|
|
100
|
-
"module_fullmatch",
|
|
101
121
|
"finditer",
|
|
102
122
|
"findall",
|
|
103
123
|
"parallel_map",
|
|
@@ -113,6 +133,8 @@ __all__ = [
|
|
|
113
133
|
"ERRORS_BY_MACRO",
|
|
114
134
|
]
|
|
115
135
|
|
|
136
|
+
__all__ += list(_FLAG_COMPAT_ALIASES.keys())
|
|
137
|
+
|
|
116
138
|
__all__ += list(_error_module.__all__)
|
|
117
139
|
__all__ += _EXPORTED_ERROR_CLASSES
|
|
118
140
|
|
|
@@ -556,12 +556,6 @@ def fullmatch(pattern: Any, string: Any, flags: FlagInput = 0) -> Match | None:
|
|
|
556
556
|
return compile(pattern, flags=flags).fullmatch(string)
|
|
557
557
|
|
|
558
558
|
|
|
559
|
-
def module_fullmatch(pattern: Any, string: Any, flags: FlagInput = 0) -> Match | None:
|
|
560
|
-
"""Compat helper for code expecting a distinct module-level fullmatch."""
|
|
561
|
-
|
|
562
|
-
return fullmatch(pattern, string, flags=flags)
|
|
563
|
-
|
|
564
|
-
|
|
565
559
|
def finditer(pattern: Any, string: Any, flags: FlagInput = 0) -> Iterable[Match]:
|
|
566
560
|
return compile(pattern, flags=flags).finditer(string)
|
|
567
561
|
|
|
@@ -70,24 +70,6 @@ required_ovector_pairs(PatternObject *self)
|
|
|
70
70
|
return required;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
static int
|
|
74
|
-
env_flag_is_true(const char *value)
|
|
75
|
-
{
|
|
76
|
-
if (value == NULL || value[0] == '\0') {
|
|
77
|
-
return 0;
|
|
78
|
-
}
|
|
79
|
-
switch (value[0]) {
|
|
80
|
-
case '0':
|
|
81
|
-
case 'f':
|
|
82
|
-
case 'F':
|
|
83
|
-
case 'n':
|
|
84
|
-
case 'N':
|
|
85
|
-
return 0;
|
|
86
|
-
default:
|
|
87
|
-
return 1;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
73
|
static inline ThreadCacheState *
|
|
92
74
|
thread_cache_state_get(void)
|
|
93
75
|
{
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2025 ModelCloud.ai
|
|
2
|
+
// SPDX-FileCopyrightText: 2025 qubitium@modelcloud.ai
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
// Contact: qubitium@modelcloud.ai, x.com/qubitium
|
|
5
|
+
|
|
6
|
+
#include "pcre2_module.h"
|
|
7
|
+
|
|
8
|
+
static PyThread_type_lock jit_serial_lock = NULL;
|
|
9
|
+
|
|
10
|
+
#if defined(PCRE_EXT_HAVE_ATOMICS)
|
|
11
|
+
static ATOMIC_VAR(int) default_jit_enabled = ATOMIC_VAR_INIT(1);
|
|
12
|
+
#else
|
|
13
|
+
static int default_jit_enabled = 1;
|
|
14
|
+
static PyThread_type_lock default_jit_lock = NULL;
|
|
15
|
+
#endif
|
|
16
|
+
|
|
17
|
+
int
|
|
18
|
+
jit_support_initialize(int force_serial_lock)
|
|
19
|
+
{
|
|
20
|
+
#if !defined(PCRE_EXT_HAVE_ATOMICS)
|
|
21
|
+
if (default_jit_lock == NULL) {
|
|
22
|
+
default_jit_lock = PyThread_allocate_lock();
|
|
23
|
+
if (default_jit_lock == NULL) {
|
|
24
|
+
PyErr_NoMemory();
|
|
25
|
+
return -1;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
#endif
|
|
29
|
+
if (force_serial_lock) {
|
|
30
|
+
if (jit_serial_lock == NULL) {
|
|
31
|
+
jit_serial_lock = PyThread_allocate_lock();
|
|
32
|
+
if (jit_serial_lock == NULL) {
|
|
33
|
+
PyErr_NoMemory();
|
|
34
|
+
return -1;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return 0;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
void
|
|
42
|
+
jit_support_teardown(void)
|
|
43
|
+
{
|
|
44
|
+
#if !defined(PCRE_EXT_HAVE_ATOMICS)
|
|
45
|
+
if (default_jit_lock != NULL) {
|
|
46
|
+
PyThread_free_lock(default_jit_lock);
|
|
47
|
+
default_jit_lock = NULL;
|
|
48
|
+
}
|
|
49
|
+
#endif
|
|
50
|
+
if (jit_serial_lock != NULL) {
|
|
51
|
+
PyThread_free_lock(jit_serial_lock);
|
|
52
|
+
jit_serial_lock = NULL;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
void
|
|
57
|
+
jit_guard_acquire(void)
|
|
58
|
+
{
|
|
59
|
+
if (jit_serial_lock != NULL) {
|
|
60
|
+
PyThread_acquire_lock(jit_serial_lock, 1);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
void
|
|
65
|
+
jit_guard_release(void)
|
|
66
|
+
{
|
|
67
|
+
if (jit_serial_lock != NULL) {
|
|
68
|
+
PyThread_release_lock(jit_serial_lock);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
int
|
|
73
|
+
default_jit_get(void)
|
|
74
|
+
{
|
|
75
|
+
#if defined(PCRE_EXT_HAVE_ATOMICS)
|
|
76
|
+
if (jit_serial_lock != NULL) {
|
|
77
|
+
jit_guard_acquire();
|
|
78
|
+
int value = atomic_load_explicit(&default_jit_enabled, memory_order_acquire);
|
|
79
|
+
jit_guard_release();
|
|
80
|
+
return value;
|
|
81
|
+
}
|
|
82
|
+
return atomic_load_explicit(&default_jit_enabled, memory_order_acquire);
|
|
83
|
+
#else
|
|
84
|
+
PyThread_acquire_lock(default_jit_lock, 1);
|
|
85
|
+
int value = default_jit_enabled;
|
|
86
|
+
PyThread_release_lock(default_jit_lock);
|
|
87
|
+
return value;
|
|
88
|
+
#endif
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
void
|
|
92
|
+
default_jit_set(int value)
|
|
93
|
+
{
|
|
94
|
+
#if defined(PCRE_EXT_HAVE_ATOMICS)
|
|
95
|
+
if (jit_serial_lock != NULL) {
|
|
96
|
+
jit_guard_acquire();
|
|
97
|
+
atomic_store_explicit(&default_jit_enabled, value, memory_order_release);
|
|
98
|
+
jit_guard_release();
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
atomic_store_explicit(&default_jit_enabled, value, memory_order_release);
|
|
102
|
+
#else
|
|
103
|
+
PyThread_acquire_lock(default_jit_lock, 1);
|
|
104
|
+
default_jit_enabled = value;
|
|
105
|
+
PyThread_release_lock(default_jit_lock);
|
|
106
|
+
#endif
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
int
|
|
110
|
+
pattern_jit_get(PatternObject *pattern)
|
|
111
|
+
{
|
|
112
|
+
#if defined(PCRE_EXT_HAVE_ATOMICS)
|
|
113
|
+
if (jit_serial_lock != NULL) {
|
|
114
|
+
jit_guard_acquire();
|
|
115
|
+
int value = atomic_load_explicit(&pattern->jit_enabled, memory_order_acquire);
|
|
116
|
+
jit_guard_release();
|
|
117
|
+
return value;
|
|
118
|
+
}
|
|
119
|
+
return atomic_load_explicit(&pattern->jit_enabled, memory_order_acquire);
|
|
120
|
+
#else
|
|
121
|
+
if (pattern->jit_lock != NULL) {
|
|
122
|
+
PyThread_acquire_lock(pattern->jit_lock, 1);
|
|
123
|
+
int value = pattern->jit_enabled;
|
|
124
|
+
PyThread_release_lock(pattern->jit_lock);
|
|
125
|
+
return value;
|
|
126
|
+
}
|
|
127
|
+
return pattern->jit_enabled;
|
|
128
|
+
#endif
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
void
|
|
132
|
+
pattern_jit_set(PatternObject *pattern, int value)
|
|
133
|
+
{
|
|
134
|
+
#if defined(PCRE_EXT_HAVE_ATOMICS)
|
|
135
|
+
if (jit_serial_lock != NULL) {
|
|
136
|
+
jit_guard_acquire();
|
|
137
|
+
atomic_store_explicit(&pattern->jit_enabled, value, memory_order_release);
|
|
138
|
+
jit_guard_release();
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
atomic_store_explicit(&pattern->jit_enabled, value, memory_order_release);
|
|
142
|
+
#else
|
|
143
|
+
if (pattern->jit_lock != NULL) {
|
|
144
|
+
PyThread_acquire_lock(pattern->jit_lock, 1);
|
|
145
|
+
pattern->jit_enabled = value;
|
|
146
|
+
PyThread_release_lock(pattern->jit_lock);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
pattern->jit_enabled = value;
|
|
150
|
+
#endif
|
|
151
|
+
}
|