File: | /rootdir/_build/../src/bteregex.cc |
Warning: | line 192, column 1 This statement is never executed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* |
2 | * Copyright © 2015 Christian Persch |
3 | * |
4 | * This library is free software; you can redistribute it and/or |
5 | * modify it under the terms of the GNU Lesser General Public |
6 | * License as published by the Free Software Foundation; either |
7 | * version 2.1 of the License, or (at your option) any later version. |
8 | * |
9 | * This library is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | * Lesser General Public License for more details. |
13 | * |
14 | * You should have received a copy of the GNU General Public License |
15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | */ |
17 | |
18 | /** |
19 | * SECTION: bte-regex |
20 | * @short_description: Regex for matching and searching. Uses PCRE2 internally. |
21 | * |
22 | * Since: 0.46 |
23 | */ |
24 | |
25 | #include "config.h" |
26 | |
27 | #include <exception> |
28 | |
29 | #include "btemacros.h" |
30 | #include "bteenums.h" |
31 | #include "bteregex.h" |
32 | #include "btepcre2.h" |
33 | |
34 | #include "regex.hh" |
35 | #include "bteregexinternal.hh" |
36 | #include "glib-glue.hh" |
37 | #include "cxx-utils.hh" |
38 | |
39 | #define IMPL(wrapper)(regex_from_wrapper(wrapper)) (regex_from_wrapper(wrapper)) |
40 | |
41 | /* Type registration */ |
42 | |
43 | #pragma GCC diagnostic push |
44 | #if defined(__GNUC__4) && !defined(__clang__1) |
45 | #pragma GCC diagnostic ignored "-Wcast-function-type" |
46 | #endif |
47 | G_DEFINE_BOXED_TYPE(BteRegex, bte_regex,static GType bte_regex_get_type_once (void); GType bte_regex_get_type (void) { static gsize static_g_define_type_id = 0; if ((__extension__ ({ static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); (void) (0 ? (gpointer ) *(&static_g_define_type_id) : __null); (!(__extension__ ({ static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); gpointer gapg_temp_newval ; gpointer *gapg_temp_atomic = (gpointer *)(&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id )); }))) { GType g_define_type_id = bte_regex_get_type_once ( ); (__extension__ ({ static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id) = (g_define_type_id) ) : (void) 0; g_once_init_leave ((&static_g_define_type_id ), (gsize) (g_define_type_id)); })); } return static_g_define_type_id ; } __attribute__ ((__noinline__)) static GType bte_regex_get_type_once (void) { GType g_define_type_id = g_boxed_type_register_static (g_intern_static_string ("BteRegex"), (GBoxedCopyFunc) bte_regex_ref , (GBoxedFreeFunc) (GBoxedFreeFunc)bte_regex_unref); { {{};} } return g_define_type_id; } |
48 | bte_regex_ref, (GBoxedFreeFunc)bte_regex_unref)static GType bte_regex_get_type_once (void); GType bte_regex_get_type (void) { static gsize static_g_define_type_id = 0; if ((__extension__ ({ static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); (void) (0 ? (gpointer ) *(&static_g_define_type_id) : __null); (!(__extension__ ({ static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); gpointer gapg_temp_newval ; gpointer *gapg_temp_atomic = (gpointer *)(&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id )); }))) { GType g_define_type_id = bte_regex_get_type_once ( ); (__extension__ ({ static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id) = (g_define_type_id) ) : (void) 0; g_once_init_leave ((&static_g_define_type_id ), (gsize) (g_define_type_id)); })); } return static_g_define_type_id ; } __attribute__ ((__noinline__)) static GType bte_regex_get_type_once (void) { GType g_define_type_id = g_boxed_type_register_static (g_intern_static_string ("BteRegex"), (GBoxedCopyFunc) bte_regex_ref , (GBoxedFreeFunc) (GBoxedFreeFunc)bte_regex_unref); { {{};} } return g_define_type_id; } |
49 | #pragma GCC diagnostic pop |
50 | |
51 | G_DEFINE_QUARK(bte-regex-error, bte_regex_error)GQuark bte_regex_error_quark (void) { static GQuark q; if (__builtin_expect (__extension__ ({ int _g_boolean_var_; if (q == 0) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 0)) q = g_quark_from_static_string ("bte-regex-error"); return q; } |
52 | |
53 | /** |
54 | * bte_regex_ref: |
55 | * @regex: (transfer none): a #BteRegex |
56 | * |
57 | * Increases the reference count of @regex by one. |
58 | * |
59 | * Returns: @regex |
60 | */ |
61 | BteRegex * |
62 | bte_regex_ref(BteRegex *regex) noexcept |
63 | { |
64 | g_return_val_if_fail(regex != nullptr, nullptr)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (regex != nullptr) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning ("BTE", ((const char*) (__PRETTY_FUNCTION__)), "regex != nullptr" ); return (nullptr); } } while (0); |
65 | |
66 | return wrapper_from_regex(IMPL(regex)(regex_from_wrapper(regex))->ref()); |
67 | } |
68 | |
69 | /** |
70 | * bte_regex_unref: |
71 | * @regex: (transfer full): a #BteRegex |
72 | * |
73 | * Decreases the reference count of @regex by one, and frees @regex |
74 | * if the refcount reaches zero. |
75 | * |
76 | * Returns: %NULL |
77 | */ |
78 | BteRegex * |
79 | bte_regex_unref(BteRegex* regex) noexcept |
80 | { |
81 | g_return_val_if_fail(regex != nullptr, nullptr)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (regex != nullptr) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning ("BTE", ((const char*) (__PRETTY_FUNCTION__)), "regex != nullptr" ); return (nullptr); } } while (0); |
82 | |
83 | IMPL(regex)(regex_from_wrapper(regex))->unref(); |
84 | return nullptr; |
85 | } |
86 | |
87 | static BteRegex* |
88 | bte_regex_new(bte::base::Regex::Purpose purpose, |
89 | std::string_view const& pattern, |
90 | uint32_t flags, |
91 | GError** error) noexcept |
92 | try |
93 | { |
94 | return wrapper_from_regex(bte::base::Regex::compile(purpose, pattern, flags, error)); |
95 | } |
96 | catch (...) |
97 | { |
98 | bte::glib::set_error_from_exception(error); |
99 | return nullptr; |
100 | } |
101 | |
102 | /** |
103 | * bte_regex_new_for_match: |
104 | * @pattern: a regex pattern string |
105 | * @pattern_length: the length of @pattern in bytes, or -1 if the |
106 | * string is NUL-terminated and the length is unknown |
107 | * @flags: PCRE2 compile flags |
108 | * @error: (allow-none): return location for a #GError, or %NULL |
109 | * |
110 | * Compiles @pattern into a regex for use as a match regex |
111 | * with bte_terminal_match_add_regex() or |
112 | * bte_terminal_event_check_regex_simple(). |
113 | * |
114 | * See man:pcre2pattern(3) for information |
115 | * about the supported regex language. |
116 | * |
117 | * The regex will be compiled using %PCRE2_UTF and possibly other flags, in |
118 | * addition to the flags supplied in @flags. |
119 | * |
120 | * Returns: (transfer full): a newly created #BteRegex, or %NULL with @error filled in |
121 | */ |
122 | BteRegex * |
123 | bte_regex_new_for_match(const char *pattern, |
124 | gssize pattern_length, |
125 | guint32 flags, |
126 | GError **error) noexcept |
127 | try |
128 | { |
129 | auto const len = size_t{pattern_length == -1 ? strlen(pattern) : size_t(pattern_length)}; |
130 | return bte_regex_new(bte::base::Regex::Purpose::eMatch, |
131 | {pattern, len}, |
132 | flags, |
133 | error); |
134 | } |
135 | catch (...) |
136 | { |
137 | bte::glib::set_error_from_exception(error); |
138 | return nullptr; |
139 | } |
140 | |
141 | /** |
142 | * bte_regex_new_for_search: |
143 | * @pattern: a regex pattern string |
144 | * @pattern_length: the length of @pattern in bytes, or -1 if the |
145 | * string is NUL-terminated and the length is unknown |
146 | * @flags: PCRE2 compile flags |
147 | * @error: (allow-none): return location for a #GError, or %NULL |
148 | * |
149 | * Compiles @pattern into a regex for use as a search regex |
150 | * with bte_terminal_search_set_regex(). |
151 | * |
152 | * See man:pcre2pattern(3) for information |
153 | * about the supported regex language. |
154 | * |
155 | * The regex will be compiled using %PCRE2_UTF and possibly other flags, in |
156 | * addition to the flags supplied in @flags. |
157 | * |
158 | * Returns: (transfer full): a newly created #BteRegex, or %NULL with @error filled in |
159 | */ |
160 | BteRegex * |
161 | bte_regex_new_for_search(const char *pattern, |
162 | gssize pattern_length, |
163 | guint32 flags, |
164 | GError **error) noexcept |
165 | try |
166 | { |
167 | auto const len = size_t{pattern_length == -1 ? strlen(pattern) : size_t(pattern_length)}; |
168 | return bte_regex_new(bte::base::Regex::Purpose::eSearch, |
169 | {pattern, len}, |
170 | flags, |
171 | error); |
172 | } |
173 | catch (...) |
174 | { |
175 | bte::glib::set_error_from_exception(error); |
176 | return nullptr; |
177 | } |
178 | |
179 | /** |
180 | * bte_regex_jit: |
181 | * @regex: a #BteRegex |
182 | * |
183 | * If the platform supports JITing, JIT compiles @regex. |
184 | * |
185 | * Returns: %TRUE if JITing succeeded (or PCRE2 was built without |
186 | * JIT support), or %FALSE with @error filled in |
187 | */ |
188 | gboolean |
189 | bte_regex_jit(BteRegex *regex, |
190 | guint flags, |
191 | GError **error) noexcept |
192 | try |
This statement is never executed | |
193 | { |
194 | g_return_val_if_fail(regex != nullptr, false)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (regex != nullptr) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning ("BTE", ((const char*) (__PRETTY_FUNCTION__)), "regex != nullptr" ); return (false); } } while (0); |
195 | |
196 | return IMPL(regex)(regex_from_wrapper(regex))->jit(flags, error); |
197 | } |
198 | catch (...) |
199 | { |
200 | return bte::glib::set_error_from_exception(error); |
201 | } |
202 | |
203 | bool |
204 | _bte_regex_has_purpose(BteRegex *regex, |
205 | bte::base::Regex::Purpose purpose) |
206 | { |
207 | g_return_val_if_fail(regex != nullptr, false)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (regex != nullptr) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning ("BTE", ((const char*) (__PRETTY_FUNCTION__)), "regex != nullptr" ); return (false); } } while (0); |
208 | |
209 | return IMPL(regex)(regex_from_wrapper(regex))->has_purpose(purpose); |
210 | } |
211 | |
212 | bool |
213 | _bte_regex_has_multiline_compile_flag(BteRegex *regex) |
214 | { |
215 | g_return_val_if_fail(regex != nullptr, 0)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (regex != nullptr) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning ("BTE", ((const char*) (__PRETTY_FUNCTION__)), "regex != nullptr" ); return (0); } } while (0); |
216 | |
217 | return IMPL(regex)(regex_from_wrapper(regex))->has_compile_flags(PCRE2_MULTILINE0x00000400u); |
218 | } |
219 | |
220 | /** |
221 | * bte_regex_substitute: |
222 | * @regex: a #BteRegex |
223 | * @subject: the subject string |
224 | * @replacement: the replacement string |
225 | * @flags: PCRE2 match flags |
226 | * @error: (nullable): return location for a #GError, or %NULL |
227 | * |
228 | * See man:pcre2api(3) on pcre2_substitute() for more information. |
229 | * |
230 | * Returns: (transfer full): the substituted string, or %NULL |
231 | * if an error occurred |
232 | * |
233 | * Since: 0.56 |
234 | */ |
235 | char * |
236 | bte_regex_substitute(BteRegex *regex, |
237 | const char *subject, |
238 | const char *replacement, |
239 | guint32 flags, |
240 | GError **error) noexcept |
241 | try |
242 | { |
243 | g_return_val_if_fail(regex != nullptr, nullptr)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (regex != nullptr) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning ("BTE", ((const char*) (__PRETTY_FUNCTION__)), "regex != nullptr" ); return (nullptr); } } while (0); |
244 | g_return_val_if_fail(subject != nullptr, nullptr)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (subject != nullptr) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning ("BTE", ((const char*) (__PRETTY_FUNCTION__)), "subject != nullptr" ); return (nullptr); } } while (0); |
245 | g_return_val_if_fail(replacement != nullptr, nullptr)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (replacement != nullptr) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning ("BTE", ((const char*) (__PRETTY_FUNCTION__)), "replacement != nullptr" ); return (nullptr); } } while (0); |
246 | g_return_val_if_fail (!(flags & PCRE2_SUBSTITUTE_OVERFLOW_LENGTH), nullptr)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (!(flags & 0x00001000u)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning ("BTE", ((const char*) (__PRETTY_FUNCTION__)), "!(flags & PCRE2_SUBSTITUTE_OVERFLOW_LENGTH)" ); return (nullptr); } } while (0); |
247 | |
248 | auto const r = IMPL(regex)(regex_from_wrapper(regex))->substitute(subject, replacement, flags, error); |
249 | return r ? g_strndup(r->c_str(), r->size()) : nullptr; |
250 | } |
251 | catch (...) |
252 | { |
253 | bte::glib::set_error_from_exception(error); |
254 | return nullptr; |
255 | } |