Branch data Line data Source code
1 : : /*
2 : : * Copyright (C) 2005 - 2006, Marco Barisione <marco@barisione.org>
3 : : * Copyright (C) 2010 Red Hat, Inc.
4 : : * Copyright (C) 2022, Marco Trevisan <marco.trevisan@canonical.com>
5 : : *
6 : : * SPDX-License-Identifier: LGPL-2.1-or-later
7 : : *
8 : : * This library is free software; you can redistribute it and/or
9 : : * modify it under the terms of the GNU Lesser General Public
10 : : * License as published by the Free Software Foundation; either
11 : : * version 2.1 of the License, or (at your option) any later version.
12 : : *
13 : : * This library is distributed in the hope that it will be useful,
14 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 : : * Lesser General Public License for more details.
17 : : *
18 : : * You should have received a copy of the GNU Lesser General Public
19 : : * License along with this library; if not, see <http://www.gnu.org/licenses/>.
20 : : */
21 : :
22 : : #undef G_DISABLE_ASSERT
23 : : #undef G_LOG_DOMAIN
24 : :
25 : : #include "config.h"
26 : :
27 : : #include <string.h>
28 : : #include <locale.h>
29 : : #include "glib.h"
30 : :
31 : : #define PCRE2_CODE_UNIT_WIDTH 8
32 : : #include <pcre2.h>
33 : :
34 : : /* U+20AC EURO SIGN (symbol, currency) */
35 : : #define EURO "\xe2\x82\xac"
36 : : /* U+00E0 LATIN SMALL LETTER A WITH GRAVE (letter, lowercase) */
37 : : #define AGRAVE "\xc3\xa0"
38 : : /* U+00C0 LATIN CAPITAL LETTER A WITH GRAVE (letter, uppercase) */
39 : : #define AGRAVE_UPPER "\xc3\x80"
40 : : /* U+00E8 LATIN SMALL LETTER E WITH GRAVE (letter, lowercase) */
41 : : #define EGRAVE "\xc3\xa8"
42 : : /* U+00F2 LATIN SMALL LETTER O WITH GRAVE (letter, lowercase) */
43 : : #define OGRAVE "\xc3\xb2"
44 : : /* U+014B LATIN SMALL LETTER ENG (letter, lowercase) */
45 : : #define ENG "\xc5\x8b"
46 : : /* U+0127 LATIN SMALL LETTER H WITH STROKE (letter, lowercase) */
47 : : #define HSTROKE "\xc4\xa7"
48 : : /* U+0634 ARABIC LETTER SHEEN (letter, other) */
49 : : #define SHEEN "\xd8\xb4"
50 : : /* U+1374 ETHIOPIC NUMBER THIRTY (number, other) */
51 : : #define ETH30 "\xe1\x8d\xb4"
52 : :
53 : : /* A random value use to mark untouched integer variables. */
54 : : #define UNTOUCHED -559038737
55 : :
56 : : /* Lengths of test strings in JIT stack tests */
57 : : #define TEST_STRING_LEN 20000
58 : : #define LARGE_TEST_STRING_LEN 200000
59 : :
60 : : static gint total;
61 : :
62 : : typedef struct {
63 : : const gchar *pattern;
64 : : GRegexCompileFlags compile_opts;
65 : : GRegexMatchFlags match_opts;
66 : : gint expected_error;
67 : : gboolean check_flags;
68 : : GRegexCompileFlags real_compile_opts;
69 : : GRegexMatchFlags real_match_opts;
70 : : } TestNewData;
71 : :
72 : : static void
73 : 39 : test_new (gconstpointer d)
74 : : {
75 : 39 : const TestNewData *data = d;
76 : : GRegex *regex;
77 : 39 : GError *error = NULL;
78 : :
79 : 39 : regex = g_regex_new (data->pattern, data->compile_opts, data->match_opts, &error);
80 : 39 : g_assert (regex != NULL);
81 : 39 : g_assert_no_error (error);
82 : 39 : g_assert_cmpstr (data->pattern, ==, g_regex_get_pattern (regex));
83 : :
84 [ + + ]: 39 : if (data->check_flags)
85 : : {
86 : 17 : g_assert_cmphex (g_regex_get_compile_flags (regex), ==, data->real_compile_opts);
87 : 17 : g_assert_cmphex (g_regex_get_match_flags (regex), ==, data->real_match_opts);
88 : : }
89 : :
90 : 39 : g_regex_unref (regex);
91 : 39 : }
92 : :
93 : : #define TEST_NEW(_pattern, _compile_opts, _match_opts) { \
94 : : TestNewData *data; \
95 : : gchar *path; \
96 : : data = g_new0 (TestNewData, 1); \
97 : : data->pattern = _pattern; \
98 : : data->compile_opts = _compile_opts; \
99 : : data->match_opts = _match_opts; \
100 : : data->expected_error = 0; \
101 : : data->check_flags = FALSE; \
102 : : path = g_strdup_printf ("/regex/new/%d", ++total); \
103 : : g_test_add_data_func_full (path, data, test_new, g_free); \
104 : : g_free (path); \
105 : : }
106 : :
107 : : #define TEST_NEW_CHECK_FLAGS(_pattern, _compile_opts, _match_opts, _real_compile_opts, _real_match_opts) { \
108 : : TestNewData *data; \
109 : : gchar *path; \
110 : : data = g_new0 (TestNewData, 1); \
111 : : data->pattern = _pattern; \
112 : : data->compile_opts = _compile_opts; \
113 : : data->match_opts = _match_opts; \
114 : : data->expected_error = 0; \
115 : : data->check_flags = TRUE; \
116 : : data->real_compile_opts = _real_compile_opts; \
117 : : data->real_match_opts = _real_match_opts; \
118 : : path = g_strdup_printf ("/regex/new-check-flags/%d", ++total); \
119 : : g_test_add_data_func_full (path, data, test_new, g_free); \
120 : : g_free (path); \
121 : : }
122 : :
123 : : static void
124 : 52 : test_new_fail (gconstpointer d)
125 : : {
126 : 52 : const TestNewData *data = d;
127 : : GRegex *regex;
128 : 52 : GError *error = NULL;
129 : :
130 : 52 : regex = g_regex_new (data->pattern, data->compile_opts, data->match_opts, &error);
131 : :
132 : 52 : g_assert (regex == NULL);
133 : 52 : g_assert_error (error, G_REGEX_ERROR, data->expected_error);
134 : 52 : g_error_free (error);
135 : 52 : }
136 : :
137 : : #define TEST_NEW_FAIL(_pattern, _compile_opts, _expected_error) { \
138 : : TestNewData *data; \
139 : : gchar *path; \
140 : : data = g_new0 (TestNewData, 1); \
141 : : data->pattern = _pattern; \
142 : : data->compile_opts = _compile_opts; \
143 : : data->match_opts = 0; \
144 : : data->expected_error = _expected_error; \
145 : : path = g_strdup_printf ("/regex/new-fail/%d", ++total); \
146 : : g_test_add_data_func_full (path, data, test_new_fail, g_free); \
147 : : g_free (path); \
148 : : }
149 : :
150 : : typedef struct {
151 : : const gchar *pattern;
152 : : const gchar *string;
153 : : GRegexCompileFlags compile_opts;
154 : : GRegexMatchFlags match_opts;
155 : : gboolean expected;
156 : : gssize string_len;
157 : : gint start_position;
158 : : GRegexMatchFlags match_opts2;
159 : : } TestMatchData;
160 : :
161 : : static void
162 : 150 : test_match_simple (gconstpointer d)
163 : : {
164 : 150 : const TestMatchData *data = d;
165 : : gboolean match;
166 : :
167 : 150 : match = g_regex_match_simple (data->pattern, data->string, data->compile_opts, data->match_opts);
168 : 150 : g_assert_cmpint (match, ==, data->expected);
169 : 150 : }
170 : :
171 : : #define TEST_MATCH_SIMPLE_NAMED(_name, _pattern, _string, _compile_opts, _match_opts, _expected) { \
172 : : TestMatchData *data; \
173 : : gchar *path; \
174 : : data = g_new0 (TestMatchData, 1); \
175 : : data->pattern = _pattern; \
176 : : data->string = _string; \
177 : : data->compile_opts = _compile_opts; \
178 : : data->match_opts = _match_opts; \
179 : : data->expected = _expected; \
180 : : total++; \
181 : : if (data->compile_opts & G_REGEX_OPTIMIZE) \
182 : : path = g_strdup_printf ("/regex/match-%s-optimized/%d", _name, total); \
183 : : else \
184 : : path = g_strdup_printf ("/regex/match-%s/%d", _name, total); \
185 : : g_test_add_data_func_full (path, data, test_match_simple, g_free); \
186 : : g_free (path); \
187 : : data = g_memdup2 (data, sizeof (TestMatchData)); \
188 : : if (data->compile_opts & G_REGEX_OPTIMIZE) \
189 : : { \
190 : : data->compile_opts &= ~G_REGEX_OPTIMIZE; \
191 : : path = g_strdup_printf ("/regex/match-%s/%d", _name, total); \
192 : : } \
193 : : else \
194 : : { \
195 : : data->compile_opts |= G_REGEX_OPTIMIZE; \
196 : : path = g_strdup_printf ("/regex/match-%s-optimized/%d", _name, total); \
197 : : } \
198 : : g_test_add_data_func_full (path, data, test_match_simple, g_free); \
199 : : g_free (path); \
200 : : }
201 : :
202 : : #define TEST_MATCH_SIMPLE(_pattern, _string, _compile_opts, _match_opts, _expected) \
203 : : TEST_MATCH_SIMPLE_NAMED("simple", _pattern, _string, _compile_opts, _match_opts, _expected)
204 : : #define TEST_MATCH_NOTEMPTY(_pattern, _string, _expected) \
205 : : TEST_MATCH_SIMPLE_NAMED("notempty", _pattern, _string, 0, G_REGEX_MATCH_NOTEMPTY, _expected)
206 : : #define TEST_MATCH_NOTEMPTY_ATSTART(_pattern, _string, _expected) \
207 : : TEST_MATCH_SIMPLE_NAMED("notempty-atstart", _pattern, _string, 0, G_REGEX_MATCH_NOTEMPTY_ATSTART, _expected)
208 : :
209 : : static char *
210 : 164 : compile_options_to_string (GRegexCompileFlags compile_flags)
211 : : {
212 : 164 : GStrvBuilder *builder = g_strv_builder_new();
213 : : GStrv strv;
214 : : char *ret;
215 : :
216 : : if (compile_flags & G_REGEX_DEFAULT)
217 : : g_strv_builder_add (builder, "default");
218 [ + + ]: 164 : if (compile_flags & G_REGEX_CASELESS)
219 : 10 : g_strv_builder_add (builder, "caseless");
220 [ + + ]: 164 : if (compile_flags & G_REGEX_MULTILINE)
221 : 78 : g_strv_builder_add (builder, "multiline");
222 [ - + ]: 164 : if (compile_flags & G_REGEX_DOTALL)
223 : 0 : g_strv_builder_add (builder, "dotall");
224 [ + + ]: 164 : if (compile_flags & G_REGEX_EXTENDED)
225 : 10 : g_strv_builder_add (builder, "extended");
226 [ - + ]: 164 : if (compile_flags & G_REGEX_ANCHORED)
227 : 0 : g_strv_builder_add (builder, "anchored");
228 [ - + ]: 164 : if (compile_flags & G_REGEX_DOLLAR_ENDONLY)
229 : 0 : g_strv_builder_add (builder, "dollar-endonly");
230 [ - + ]: 164 : if (compile_flags & G_REGEX_UNGREEDY)
231 : 0 : g_strv_builder_add (builder, "ungreedy");
232 [ + + ]: 164 : if (compile_flags & G_REGEX_RAW)
233 : 4 : g_strv_builder_add (builder, "raw");
234 [ - + ]: 164 : if (compile_flags & G_REGEX_NO_AUTO_CAPTURE)
235 : 0 : g_strv_builder_add (builder, "no-auto-capture");
236 [ + + ]: 164 : if (compile_flags & G_REGEX_OPTIMIZE)
237 : 82 : g_strv_builder_add (builder, "optimize");
238 [ + + ]: 164 : if (compile_flags & G_REGEX_FIRSTLINE)
239 : 2 : g_strv_builder_add (builder, "firstline");
240 [ - + ]: 164 : if (compile_flags & G_REGEX_DUPNAMES)
241 : 0 : g_strv_builder_add (builder, "dupnames");
242 [ + + ]: 164 : if (compile_flags & G_REGEX_NEWLINE_CR)
243 : 32 : g_strv_builder_add (builder, "newline-cr");
244 [ + + ]: 164 : if (compile_flags & G_REGEX_NEWLINE_LF)
245 : 12 : g_strv_builder_add (builder, "newline-lf");
246 [ + + ]: 164 : if (compile_flags & G_REGEX_NEWLINE_CRLF)
247 : 38 : g_strv_builder_add (builder, "newline-crlf");
248 [ + + ]: 164 : if (compile_flags & G_REGEX_NEWLINE_ANYCRLF)
249 : 32 : g_strv_builder_add (builder, "newline-anycrlf");
250 [ - + ]: 164 : if (compile_flags & G_REGEX_BSR_ANYCRLF)
251 : 0 : g_strv_builder_add (builder, "bsr-anycrlf");
252 : :
253 : 164 : strv = g_strv_builder_end (builder);
254 : 164 : ret = g_strjoinv ("|", strv);
255 : :
256 : 164 : g_strfreev (strv);
257 : 164 : g_strv_builder_unref (builder);
258 : :
259 : 164 : return ret;
260 : : }
261 : :
262 : : static char *
263 : 328 : match_options_to_string (GRegexMatchFlags match_flags)
264 : : {
265 : 328 : GStrvBuilder *builder = g_strv_builder_new();
266 : : GStrv strv;
267 : : char *ret;
268 : :
269 : : if (match_flags & G_REGEX_MATCH_DEFAULT)
270 : : g_strv_builder_add (builder, "default");
271 [ + + ]: 328 : if (match_flags & G_REGEX_MATCH_ANCHORED)
272 : 20 : g_strv_builder_add (builder, "anchored");
273 [ - + ]: 328 : if (match_flags & G_REGEX_MATCH_NOTBOL)
274 : 0 : g_strv_builder_add (builder, "notbol");
275 [ - + ]: 328 : if (match_flags & G_REGEX_MATCH_NOTEOL)
276 : 0 : g_strv_builder_add (builder, "noteol");
277 [ - + ]: 328 : if (match_flags & G_REGEX_MATCH_NOTEMPTY)
278 : 0 : g_strv_builder_add (builder, "notempty");
279 [ - + ]: 328 : if (match_flags & G_REGEX_MATCH_PARTIAL)
280 : 0 : g_strv_builder_add (builder, "partial");
281 [ + + ]: 328 : if (match_flags & G_REGEX_MATCH_NEWLINE_CR)
282 : 28 : g_strv_builder_add (builder, "newline-cr");
283 [ + + ]: 328 : if (match_flags & G_REGEX_MATCH_NEWLINE_LF)
284 : 24 : g_strv_builder_add (builder, "newline-lf");
285 [ + + ]: 328 : if (match_flags & G_REGEX_MATCH_NEWLINE_CRLF)
286 : 40 : g_strv_builder_add (builder, "newline-crlf");
287 [ + + ]: 328 : if (match_flags & G_REGEX_MATCH_NEWLINE_ANY)
288 : 14 : g_strv_builder_add (builder, "newline-any");
289 [ + + ]: 328 : if (match_flags & G_REGEX_MATCH_NEWLINE_ANYCRLF)
290 : 36 : g_strv_builder_add (builder, "newline-anycrlf");
291 [ - + ]: 328 : if (match_flags & G_REGEX_MATCH_BSR_ANYCRLF)
292 : 0 : g_strv_builder_add (builder, "bsr-anycrlf");
293 [ - + ]: 328 : if (match_flags & G_REGEX_MATCH_BSR_ANY)
294 : 0 : g_strv_builder_add (builder, "bsr-any");
295 [ - + ]: 328 : if (match_flags & G_REGEX_MATCH_PARTIAL_SOFT)
296 : 0 : g_strv_builder_add (builder, "partial-soft");
297 [ - + ]: 328 : if (match_flags & G_REGEX_MATCH_PARTIAL_HARD)
298 : 0 : g_strv_builder_add (builder, "partial-hard");
299 [ - + ]: 328 : if (match_flags & G_REGEX_MATCH_NOTEMPTY_ATSTART)
300 : 0 : g_strv_builder_add (builder, "notempty-atstart");
301 : :
302 : 328 : strv = g_strv_builder_end (builder);
303 : 328 : ret = g_strjoinv ("|", strv);
304 : :
305 : 328 : g_strfreev (strv);
306 : 328 : g_strv_builder_unref (builder);
307 : :
308 : 328 : return ret;
309 : : }
310 : :
311 : : static void
312 : 164 : test_match (gconstpointer d)
313 : : {
314 : 164 : const TestMatchData *data = d;
315 : : GRegex *regex;
316 : : gboolean match;
317 : 164 : GError *error = NULL;
318 : : gchar *compile_opts_str;
319 : : gchar *match_opts_str;
320 : : gchar *match_opts2_str;
321 : :
322 : 164 : regex = g_regex_new (data->pattern, data->compile_opts, data->match_opts, &error);
323 : 164 : g_assert (regex != NULL);
324 : 164 : g_assert_no_error (error);
325 : :
326 : 164 : match = g_regex_match_full (regex, data->string, data->string_len,
327 : 164 : data->start_position, data->match_opts2, NULL, NULL);
328 : :
329 : 164 : compile_opts_str = compile_options_to_string (data->compile_opts);
330 : 164 : match_opts_str = match_options_to_string (data->match_opts);
331 : 164 : match_opts2_str = match_options_to_string (data->match_opts2);
332 : :
333 [ + + ]: 164 : if (data->expected)
334 : : {
335 [ - + ]: 92 : if (!match)
336 [ # # ]: 0 : g_error ("Regex '%s' (with compile options '%s' and "
337 : : "match options '%s') should have matched '%.*s' "
338 : : "(of length %d, at position %d, with match options '%s') but did not",
339 : : data->pattern, compile_opts_str, match_opts_str,
340 : : data->string_len == -1 ? (int) strlen (data->string) :
341 : : (int) data->string_len,
342 : : data->string, (int) data->string_len,
343 : : data->start_position, match_opts2_str);
344 : :
345 : 92 : g_assert_cmpint (match, ==, TRUE);
346 : : }
347 : : else
348 : : {
349 [ - + ]: 72 : if (match)
350 [ # # ]: 0 : g_error ("Regex '%s' (with compile options '%s' and "
351 : : "match options '%s') should not have matched '%.*s' "
352 : : "(of length %d, at position %d, with match options '%s') but did",
353 : : data->pattern, compile_opts_str, match_opts_str,
354 : : data->string_len == -1 ? (int) strlen (data->string) :
355 : : (int) data->string_len,
356 : : data->string, (int) data->string_len,
357 : : data->start_position, match_opts2_str);
358 : : }
359 : :
360 [ + + + + ]: 164 : if (data->string_len == -1 && data->start_position == 0)
361 : : {
362 : 152 : match = g_regex_match (regex, data->string, data->match_opts2, NULL);
363 : 152 : g_assert_cmpint (match, ==, data->expected);
364 : : }
365 : :
366 : 164 : g_free (compile_opts_str);
367 : 164 : g_free (match_opts_str);
368 : 164 : g_free (match_opts2_str);
369 : 164 : g_regex_unref (regex);
370 : 164 : }
371 : :
372 : : #define TEST_MATCH(_pattern, _compile_opts, _match_opts, _string, \
373 : : _string_len, _start_position, _match_opts2, _expected) { \
374 : : TestMatchData *data; \
375 : : gchar *path; \
376 : : data = g_new0 (TestMatchData, 1); \
377 : : data->pattern = _pattern; \
378 : : data->compile_opts = _compile_opts; \
379 : : data->match_opts = _match_opts; \
380 : : data->string = _string; \
381 : : data->string_len = _string_len; \
382 : : data->start_position = _start_position; \
383 : : data->match_opts2 = _match_opts2; \
384 : : data->expected = _expected; \
385 : : total++; \
386 : : if (data->compile_opts & G_REGEX_OPTIMIZE) \
387 : : path = g_strdup_printf ("/regex/match-optimized/%d", total); \
388 : : else \
389 : : path = g_strdup_printf ("/regex/match/%d", total); \
390 : : g_test_add_data_func_full (path, data, test_match, g_free); \
391 : : g_free (path); \
392 : : data = g_memdup2 (data, sizeof (TestMatchData)); \
393 : : if (data->compile_opts & G_REGEX_OPTIMIZE) \
394 : : { \
395 : : data->compile_opts &= ~G_REGEX_OPTIMIZE; \
396 : : path = g_strdup_printf ("/regex/match/%d", total); \
397 : : } \
398 : : else \
399 : : { \
400 : : data->compile_opts |= G_REGEX_OPTIMIZE; \
401 : : path = g_strdup_printf ("/regex/match-optimized/%d", total); \
402 : : } \
403 : : g_test_add_data_func_full (path, data, test_match, g_free); \
404 : : g_free (path); \
405 : : }
406 : :
407 : : struct _Match
408 : : {
409 : : gchar *string;
410 : : gint start, end;
411 : : };
412 : : typedef struct _Match Match;
413 : :
414 : : static void
415 : 43 : free_match (gpointer data)
416 : : {
417 : 43 : Match *match = data;
418 [ - + ]: 43 : if (match == NULL)
419 : 0 : return;
420 : 43 : g_free (match->string);
421 : 43 : g_free (match);
422 : : }
423 : :
424 : : typedef struct {
425 : : const gchar *pattern;
426 : : const gchar *string;
427 : : gssize string_len;
428 : : gint start_position;
429 : : GSList *expected;
430 : : } TestMatchNextData;
431 : :
432 : : static void
433 : 24 : test_match_next (gconstpointer d)
434 : : {
435 : 24 : const TestMatchNextData *data = d;
436 : : GRegex *regex;
437 : : GMatchInfo *match_info;
438 : : GSList *matches;
439 : : GSList *l_exp, *l_match;
440 : :
441 : 24 : regex = g_regex_new (data->pattern, G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL);
442 : :
443 : 24 : g_assert (regex != NULL);
444 : :
445 : 24 : g_regex_match_full (regex, data->string, data->string_len,
446 : 24 : data->start_position, 0, &match_info, NULL);
447 : 24 : matches = NULL;
448 [ + + ]: 67 : while (g_match_info_matches (match_info))
449 : : {
450 : 43 : Match *match = g_new0 (Match, 1);
451 : 43 : match->string = g_match_info_fetch (match_info, 0);
452 : 43 : match->start = UNTOUCHED;
453 : 43 : match->end = UNTOUCHED;
454 : 43 : g_match_info_fetch_pos (match_info, 0, &match->start, &match->end);
455 : 43 : matches = g_slist_prepend (matches, match);
456 : 43 : g_match_info_next (match_info, NULL);
457 : : }
458 : 24 : g_assert (regex == g_match_info_get_regex (match_info));
459 : 24 : g_assert_cmpstr (data->string, ==, g_match_info_get_string (match_info));
460 : 24 : g_match_info_free (match_info);
461 : 24 : matches = g_slist_reverse (matches);
462 : :
463 : 24 : g_assert_cmpint (g_slist_length (matches), ==, g_slist_length (data->expected));
464 : :
465 : 24 : l_exp = data->expected;
466 : 24 : l_match = matches;
467 [ + + ]: 67 : while (l_exp != NULL)
468 : : {
469 : 43 : Match *exp = l_exp->data;
470 : 43 : Match *match = l_match->data;
471 : :
472 : 43 : g_assert_cmpstr (exp->string, ==, match->string);
473 : 43 : g_assert_cmpint (exp->start, ==, match->start);
474 : 43 : g_assert_cmpint (exp->end, ==, match->end);
475 : :
476 [ + - ]: 43 : l_exp = g_slist_next (l_exp);
477 [ + - ]: 43 : l_match = g_slist_next (l_match);
478 : : }
479 : :
480 : 24 : g_regex_unref (regex);
481 : 24 : g_slist_free_full (matches, free_match);
482 : 24 : }
483 : :
484 : : static void
485 : 24 : free_match_next_data (gpointer _data)
486 : : {
487 : 24 : TestMatchNextData *data = _data;
488 : :
489 : 24 : g_slist_free_full (data->expected, g_free);
490 : 24 : g_free (data);
491 : 24 : }
492 : :
493 : : #define TEST_MATCH_NEXT0(_pattern, _string, _string_len, _start_position) { \
494 : : TestMatchNextData *data; \
495 : : gchar *path; \
496 : : data = g_new0 (TestMatchNextData, 1); \
497 : : data->pattern = _pattern; \
498 : : data->string = _string; \
499 : : data->string_len = _string_len; \
500 : : data->start_position = _start_position; \
501 : : data->expected = NULL; \
502 : : path = g_strdup_printf ("/regex/match/next0/%d", ++total); \
503 : : g_test_add_data_func_full (path, data, test_match_next, free_match_next_data); \
504 : : g_free (path); \
505 : : }
506 : :
507 : : #define TEST_MATCH_NEXT1(_pattern, _string, _string_len, _start_position, \
508 : : t1, s1, e1) { \
509 : : TestMatchNextData *data; \
510 : : Match *match; \
511 : : gchar *path; \
512 : : data = g_new0 (TestMatchNextData, 1); \
513 : : data->pattern = _pattern; \
514 : : data->string = _string; \
515 : : data->string_len = _string_len; \
516 : : data->start_position = _start_position; \
517 : : match = g_new0 (Match, 1); \
518 : : match->string = t1; \
519 : : match->start = s1; \
520 : : match->end = e1; \
521 : : data->expected = g_slist_append (NULL, match); \
522 : : path = g_strdup_printf ("/regex/match/next1/%d", ++total); \
523 : : g_test_add_data_func_full (path, data, test_match_next, free_match_next_data); \
524 : : g_free (path); \
525 : : }
526 : :
527 : : #define TEST_MATCH_NEXT2(_pattern, _string, _string_len, _start_position, \
528 : : t1, s1, e1, t2, s2, e2) { \
529 : : TestMatchNextData *data; \
530 : : Match *match; \
531 : : gchar *path; \
532 : : data = g_new0 (TestMatchNextData, 1); \
533 : : data->pattern = _pattern; \
534 : : data->string = _string; \
535 : : data->string_len = _string_len; \
536 : : data->start_position = _start_position; \
537 : : match = g_new0 (Match, 1); \
538 : : match->string = t1; \
539 : : match->start = s1; \
540 : : match->end = e1; \
541 : : data->expected = g_slist_append (NULL, match); \
542 : : match = g_new0 (Match, 1); \
543 : : match->string = t2; \
544 : : match->start = s2; \
545 : : match->end = e2; \
546 : : data->expected = g_slist_append (data->expected, match); \
547 : : path = g_strdup_printf ("/regex/match/next2/%d", ++total); \
548 : : g_test_add_data_func_full (path, data, test_match_next, free_match_next_data); \
549 : : g_free (path); \
550 : : }
551 : :
552 : : #define TEST_MATCH_NEXT3(_pattern, _string, _string_len, _start_position, \
553 : : t1, s1, e1, t2, s2, e2, t3, s3, e3) { \
554 : : TestMatchNextData *data; \
555 : : Match *match; \
556 : : gchar *path; \
557 : : data = g_new0 (TestMatchNextData, 1); \
558 : : data->pattern = _pattern; \
559 : : data->string = _string; \
560 : : data->string_len = _string_len; \
561 : : data->start_position = _start_position; \
562 : : match = g_new0 (Match, 1); \
563 : : match->string = t1; \
564 : : match->start = s1; \
565 : : match->end = e1; \
566 : : data->expected = g_slist_append (NULL, match); \
567 : : match = g_new0 (Match, 1); \
568 : : match->string = t2; \
569 : : match->start = s2; \
570 : : match->end = e2; \
571 : : data->expected = g_slist_append (data->expected, match); \
572 : : match = g_new0 (Match, 1); \
573 : : match->string = t3; \
574 : : match->start = s3; \
575 : : match->end = e3; \
576 : : data->expected = g_slist_append (data->expected, match); \
577 : : path = g_strdup_printf ("/regex/match/next3/%d", ++total); \
578 : : g_test_add_data_func_full (path, data, test_match_next, free_match_next_data); \
579 : : g_free (path); \
580 : : }
581 : :
582 : : #define TEST_MATCH_NEXT4(_pattern, _string, _string_len, _start_position, \
583 : : t1, s1, e1, t2, s2, e2, t3, s3, e3, t4, s4, e4) { \
584 : : TestMatchNextData *data; \
585 : : Match *match; \
586 : : gchar *path; \
587 : : data = g_new0 (TestMatchNextData, 1); \
588 : : data->pattern = _pattern; \
589 : : data->string = _string; \
590 : : data->string_len = _string_len; \
591 : : data->start_position = _start_position; \
592 : : match = g_new0 (Match, 1); \
593 : : match->string = t1; \
594 : : match->start = s1; \
595 : : match->end = e1; \
596 : : data->expected = g_slist_append (NULL, match); \
597 : : match = g_new0 (Match, 1); \
598 : : match->string = t2; \
599 : : match->start = s2; \
600 : : match->end = e2; \
601 : : data->expected = g_slist_append (data->expected, match); \
602 : : match = g_new0 (Match, 1); \
603 : : match->string = t3; \
604 : : match->start = s3; \
605 : : match->end = e3; \
606 : : data->expected = g_slist_append (data->expected, match); \
607 : : match = g_new0 (Match, 1); \
608 : : match->string = t4; \
609 : : match->start = s4; \
610 : : match->end = e4; \
611 : : data->expected = g_slist_append (data->expected, match); \
612 : : path = g_strdup_printf ("/regex/match/next4/%d", ++total); \
613 : : g_test_add_data_func_full (path, data, test_match_next, free_match_next_data); \
614 : : g_free (path); \
615 : : }
616 : :
617 : : typedef struct {
618 : : const gchar *pattern;
619 : : const gchar *string;
620 : : gint start_position;
621 : : GRegexCompileFlags compile_flags;
622 : : GRegexMatchFlags match_opts;
623 : : gint expected_count;
624 : : } TestMatchCountData;
625 : :
626 : : static void
627 : 20 : test_match_count (gconstpointer d)
628 : : {
629 : 20 : const TestMatchCountData *data = d;
630 : : GRegex *regex;
631 : : GMatchInfo *match_info;
632 : : gint count;
633 : :
634 : 20 : regex = g_regex_new (data->pattern, data->compile_flags,
635 : : G_REGEX_MATCH_DEFAULT, NULL);
636 : :
637 : 20 : g_assert (regex != NULL);
638 : :
639 : 20 : g_regex_match_full (regex, data->string, -1, data->start_position,
640 : 20 : data->match_opts, &match_info, NULL);
641 : 20 : count = g_match_info_get_match_count (match_info);
642 : :
643 : 20 : g_assert_cmpint (count, ==, data->expected_count);
644 : :
645 : 20 : g_match_info_ref (match_info);
646 : 20 : g_match_info_unref (match_info);
647 : 20 : g_match_info_unref (match_info);
648 : 20 : g_regex_unref (regex);
649 : 20 : }
650 : :
651 : : #define TEST_MATCH_COUNT(_pattern, _string, _start_position, _match_opts, _expected_count) { \
652 : : TestMatchCountData *data; \
653 : : gchar *path; \
654 : : data = g_new0 (TestMatchCountData, 1); \
655 : : data->pattern = _pattern; \
656 : : data->string = _string; \
657 : : data->start_position = _start_position; \
658 : : data->match_opts = _match_opts; \
659 : : data->expected_count = _expected_count; \
660 : : data->compile_flags = G_REGEX_DEFAULT; \
661 : : total++; \
662 : : path = g_strdup_printf ("/regex/match/count/%d", total); \
663 : : g_test_add_data_func_full (path, data, test_match_count, g_free); \
664 : : g_free (path); \
665 : : data = g_memdup2 (data, sizeof (TestMatchCountData)); \
666 : : data->compile_flags |= G_REGEX_OPTIMIZE; \
667 : : path = g_strdup_printf ("/regex/match/count-optimized/%d", total); \
668 : : g_test_add_data_func_full (path, data, test_match_count, g_free); \
669 : : g_free (path); \
670 : : }
671 : :
672 : : static void
673 : 44 : test_partial (gconstpointer d)
674 : : {
675 : 44 : const TestMatchData *data = d;
676 : : GRegex *regex;
677 : : GMatchInfo *match_info;
678 : :
679 : 44 : regex = g_regex_new (data->pattern, data->compile_opts, G_REGEX_MATCH_DEFAULT, NULL);
680 : :
681 : 44 : g_assert (regex != NULL);
682 : :
683 : 44 : g_regex_match (regex, data->string, data->match_opts, &match_info);
684 : :
685 : 44 : g_assert_cmpint (data->expected, ==, g_match_info_is_partial_match (match_info));
686 : :
687 [ + + ]: 44 : if (data->expected)
688 : : {
689 : 28 : g_assert (!g_match_info_fetch_pos (match_info, 0, NULL, NULL));
690 : 28 : g_assert (!g_match_info_fetch_pos (match_info, 1, NULL, NULL));
691 : : }
692 : :
693 : 44 : g_match_info_free (match_info);
694 : 44 : g_regex_unref (regex);
695 : 44 : }
696 : :
697 : : #define TEST_PARTIAL_FULL(_pattern, _string, _compile_opts, _match_opts, _expected) { \
698 : : TestMatchData *data; \
699 : : gchar *path; \
700 : : data = g_new0 (TestMatchData, 1); \
701 : : data->pattern = _pattern; \
702 : : data->string = _string; \
703 : : data->compile_opts = _compile_opts; \
704 : : data->match_opts = _match_opts; \
705 : : data->expected = _expected; \
706 : : total++; \
707 : : if (data->compile_opts & G_REGEX_OPTIMIZE) \
708 : : path = g_strdup_printf ("/regex/match/partial-optimized/%d", total); \
709 : : else \
710 : : path = g_strdup_printf ("/regex/match/partial%d", total); \
711 : : g_test_add_data_func_full (path, data, test_partial, g_free); \
712 : : g_free (path); \
713 : : data = g_memdup2 (data, sizeof (TestMatchData)); \
714 : : if (data->compile_opts & G_REGEX_OPTIMIZE) \
715 : : { \
716 : : data->compile_opts &= ~G_REGEX_OPTIMIZE; \
717 : : path = g_strdup_printf ("/regex/match/partial%d", total); \
718 : : } \
719 : : else \
720 : : { \
721 : : data->compile_opts |= G_REGEX_OPTIMIZE; \
722 : : path = g_strdup_printf ("/regex/match/partial-optimized/%d", total); \
723 : : } \
724 : : g_test_add_data_func_full (path, data, test_partial, g_free); \
725 : : g_free (path); \
726 : : }
727 : :
728 : : #define TEST_PARTIAL(_pattern, _string, _compile_opts, _expected) TEST_PARTIAL_FULL(_pattern, _string, _compile_opts, G_REGEX_MATCH_PARTIAL, _expected)
729 : :
730 : : typedef struct {
731 : : const gchar *pattern;
732 : : const gchar *string;
733 : : GRegexCompileFlags compile_flags;
734 : : gint start_position;
735 : : gint sub_n;
736 : : const gchar *expected_sub;
737 : : gint expected_start;
738 : : gint expected_end;
739 : : } TestSubData;
740 : :
741 : : static void
742 : 26 : test_sub_pattern (gconstpointer d)
743 : : {
744 : 26 : const TestSubData *data = d;
745 : : GRegex *regex;
746 : : GMatchInfo *match_info;
747 : : gchar *sub_expr;
748 : 26 : gint start = UNTOUCHED, end = UNTOUCHED;
749 : :
750 : 26 : regex = g_regex_new (data->pattern, data->compile_flags, G_REGEX_MATCH_DEFAULT, NULL);
751 : :
752 : 26 : g_assert (regex != NULL);
753 : :
754 : 26 : g_regex_match_full (regex, data->string, -1, data->start_position, 0, &match_info, NULL);
755 : :
756 : 26 : sub_expr = g_match_info_fetch (match_info, data->sub_n);
757 : 26 : g_assert_cmpstr (sub_expr, ==, data->expected_sub);
758 : 26 : g_free (sub_expr);
759 : :
760 : 26 : g_match_info_fetch_pos (match_info, data->sub_n, &start, &end);
761 : 26 : g_assert_cmpint (start, ==, data->expected_start);
762 : 26 : g_assert_cmpint (end, ==, data->expected_end);
763 : :
764 : 26 : g_match_info_free (match_info);
765 : 26 : g_regex_unref (regex);
766 : 26 : }
767 : :
768 : : #define TEST_SUB_PATTERN(_pattern, _string, _start_position, _sub_n, _expected_sub, \
769 : : _expected_start, _expected_end) { \
770 : : TestSubData *data; \
771 : : gchar *path; \
772 : : data = g_new0 (TestSubData, 1); \
773 : : data->pattern = _pattern; \
774 : : data->string = _string; \
775 : : data->start_position = _start_position; \
776 : : data->sub_n = _sub_n; \
777 : : data->expected_sub = _expected_sub; \
778 : : data->expected_start = _expected_start; \
779 : : data->expected_end = _expected_end; \
780 : : data->compile_flags = G_REGEX_DEFAULT; \
781 : : total++; \
782 : : path = g_strdup_printf ("/regex/match/subpattern/%d", total); \
783 : : g_test_add_data_func_full (path, data, test_sub_pattern, g_free); \
784 : : g_free (path); \
785 : : data = g_memdup2 (data, sizeof (TestSubData)); \
786 : : data->compile_flags = G_REGEX_OPTIMIZE; \
787 : : path = g_strdup_printf ("/regex/match/subpattern-optimized/%d", total); \
788 : : g_test_add_data_func_full (path, data, test_sub_pattern, g_free); \
789 : : g_free (path); \
790 : : }
791 : :
792 : : typedef struct {
793 : : const gchar *pattern;
794 : : GRegexCompileFlags flags;
795 : : const gchar *string;
796 : : gint start_position;
797 : : const gchar *sub_name;
798 : : const gchar *expected_sub;
799 : : gint expected_start;
800 : : gint expected_end;
801 : : } TestNamedSubData;
802 : :
803 : : static void
804 : 19 : test_named_sub_pattern (gconstpointer d)
805 : : {
806 : 19 : const TestNamedSubData *data = d;
807 : : GRegex *regex;
808 : : GMatchInfo *match_info;
809 : 19 : gint start = UNTOUCHED, end = UNTOUCHED;
810 : : gchar *sub_expr;
811 : :
812 : 19 : regex = g_regex_new (data->pattern, data->flags, G_REGEX_MATCH_DEFAULT, NULL);
813 : :
814 : 19 : g_assert (regex != NULL);
815 : :
816 : 19 : g_regex_match_full (regex, data->string, -1, data->start_position, 0, &match_info, NULL);
817 : 19 : sub_expr = g_match_info_fetch_named (match_info, data->sub_name);
818 : 19 : g_assert_cmpstr (sub_expr, ==, data->expected_sub);
819 : 19 : g_free (sub_expr);
820 : :
821 : 19 : g_match_info_fetch_named_pos (match_info, data->sub_name, &start, &end);
822 : 19 : g_assert_cmpint (start, ==, data->expected_start);
823 : 19 : g_assert_cmpint (end, ==, data->expected_end);
824 : :
825 : 19 : g_match_info_free (match_info);
826 : 19 : g_regex_unref (regex);
827 : 19 : }
828 : :
829 : : #define TEST_NAMED_SUB_PATTERN(_pattern, _string, _start_position, _sub_name, \
830 : : _expected_sub, _expected_start, _expected_end) { \
831 : : TestNamedSubData *data; \
832 : : gchar *path; \
833 : : data = g_new0 (TestNamedSubData, 1); \
834 : : data->pattern = _pattern; \
835 : : data->string = _string; \
836 : : data->flags = 0; \
837 : : data->start_position = _start_position; \
838 : : data->sub_name = _sub_name; \
839 : : data->expected_sub = _expected_sub; \
840 : : data->expected_start = _expected_start; \
841 : : data->expected_end = _expected_end; \
842 : : path = g_strdup_printf ("/regex/match/named/subpattern/%d", ++total); \
843 : : g_test_add_data_func_full (path, data, test_named_sub_pattern, g_free); \
844 : : g_free (path); \
845 : : }
846 : :
847 : : #define TEST_NAMED_SUB_PATTERN_DUPNAMES(_pattern, _string, _start_position, _sub_name, \
848 : : _expected_sub, _expected_start, _expected_end) { \
849 : : TestNamedSubData *data; \
850 : : gchar *path; \
851 : : data = g_new0 (TestNamedSubData, 1); \
852 : : data->pattern = _pattern; \
853 : : data->string = _string; \
854 : : data->flags = G_REGEX_DUPNAMES; \
855 : : data->start_position = _start_position; \
856 : : data->sub_name = _sub_name; \
857 : : data->expected_sub = _expected_sub; \
858 : : data->expected_start = _expected_start; \
859 : : data->expected_end = _expected_end; \
860 : : path = g_strdup_printf ("/regex/match/subpattern/named/dupnames/%d", ++total); \
861 : : g_test_add_data_func_full (path, data, test_named_sub_pattern, g_free); \
862 : : g_free (path); \
863 : : }
864 : :
865 : : typedef struct {
866 : : const gchar *pattern;
867 : : const gchar *string;
868 : : GSList *expected;
869 : : gint start_position;
870 : : gint max_tokens;
871 : : } TestFetchAllData;
872 : :
873 : : static void
874 : 13 : test_fetch_all (gconstpointer d)
875 : : {
876 : 13 : const TestFetchAllData *data = d;
877 : : GRegex *regex;
878 : : GMatchInfo *match_info;
879 : : GSList *l_exp;
880 : : gchar **matches;
881 : : gint match_count;
882 : : gint i;
883 : :
884 : 13 : regex = g_regex_new (data->pattern, G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL);
885 : :
886 : 13 : g_assert (regex != NULL);
887 : :
888 : 13 : g_regex_match (regex, data->string, 0, &match_info);
889 : 13 : matches = g_match_info_fetch_all (match_info);
890 [ + + ]: 13 : if (matches)
891 : 11 : match_count = g_strv_length (matches);
892 : : else
893 : 2 : match_count = 0;
894 : :
895 : 13 : g_assert_cmpint (match_count, ==, g_slist_length (data->expected));
896 : :
897 : 13 : l_exp = data->expected;
898 [ + - + + ]: 37 : for (i = 0; l_exp != NULL; i++, l_exp = g_slist_next (l_exp))
899 : : {
900 : 24 : g_assert_nonnull (matches);
901 : 24 : g_assert_cmpstr (l_exp->data, ==, matches[i]);
902 : : }
903 : :
904 : 13 : g_match_info_free (match_info);
905 : 13 : g_regex_unref (regex);
906 : 13 : g_strfreev (matches);
907 : 13 : }
908 : :
909 : : static void
910 : 58 : free_fetch_all_data (gpointer _data)
911 : : {
912 : 58 : TestFetchAllData *data = _data;
913 : :
914 : 58 : g_slist_free (data->expected);
915 : 58 : g_free (data);
916 : 58 : }
917 : :
918 : : #define TEST_FETCH_ALL0(_pattern, _string) { \
919 : : TestFetchAllData *data; \
920 : : gchar *path; \
921 : : data = g_new0 (TestFetchAllData, 1); \
922 : : data->pattern = _pattern; \
923 : : data->string = _string; \
924 : : data->expected = NULL; \
925 : : path = g_strdup_printf ("/regex/fetch-all0/%d", ++total); \
926 : : g_test_add_data_func_full (path, data, test_fetch_all, free_fetch_all_data); \
927 : : g_free (path); \
928 : : }
929 : :
930 : : #define TEST_FETCH_ALL1(_pattern, _string, e1) { \
931 : : TestFetchAllData *data; \
932 : : gchar *path; \
933 : : data = g_new0 (TestFetchAllData, 1); \
934 : : data->pattern = _pattern; \
935 : : data->string = _string; \
936 : : data->expected = g_slist_append (NULL, e1); \
937 : : path = g_strdup_printf ("/regex/fetch-all1/%d", ++total); \
938 : : g_test_add_data_func_full (path, data, test_fetch_all, free_fetch_all_data); \
939 : : g_free (path); \
940 : : }
941 : :
942 : : #define TEST_FETCH_ALL2(_pattern, _string, e1, e2) { \
943 : : TestFetchAllData *data; \
944 : : gchar *path; \
945 : : data = g_new0 (TestFetchAllData, 1); \
946 : : data->pattern = _pattern; \
947 : : data->string = _string; \
948 : : data->expected = g_slist_append (NULL, e1); \
949 : : data->expected = g_slist_append (data->expected, e2); \
950 : : path = g_strdup_printf ("/regex/fetch-all2/%d", ++total); \
951 : : g_test_add_data_func_full (path, data, test_fetch_all, free_fetch_all_data); \
952 : : g_free (path); \
953 : : }
954 : :
955 : : #define TEST_FETCH_ALL3(_pattern, _string, e1, e2, e3) { \
956 : : TestFetchAllData *data; \
957 : : gchar *path; \
958 : : data = g_new0 (TestFetchAllData, 1); \
959 : : data->pattern = _pattern; \
960 : : data->string = _string; \
961 : : data->expected = g_slist_append (NULL, e1); \
962 : : data->expected = g_slist_append (data->expected, e2); \
963 : : data->expected = g_slist_append (data->expected, e3); \
964 : : path = g_strdup_printf ("/regex/fetch-all3/%d", ++total); \
965 : : g_test_add_data_func_full (path, data, test_fetch_all, free_fetch_all_data); \
966 : : g_free (path); \
967 : : }
968 : :
969 : : static void
970 : 18 : test_split_simple (gconstpointer d)
971 : : {
972 : 18 : const TestFetchAllData *data = d;
973 : : GSList *l_exp;
974 : : gchar **tokens;
975 : : gint token_count;
976 : : gint i;
977 : :
978 : 18 : tokens = g_regex_split_simple (data->pattern, data->string,
979 : : G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT);
980 [ + + ]: 18 : if (tokens)
981 : 16 : token_count = g_strv_length (tokens);
982 : : else
983 : 2 : token_count = 0;
984 : :
985 : 18 : g_assert_cmpint (token_count, ==, g_slist_length (data->expected));
986 : :
987 : 18 : l_exp = data->expected;
988 [ + - + + ]: 53 : for (i = 0; l_exp != NULL; i++, l_exp = g_slist_next (l_exp))
989 : : {
990 : 35 : g_assert_nonnull (tokens);
991 : 35 : g_assert_cmpstr (l_exp->data, ==, tokens[i]);
992 : : }
993 : :
994 : 18 : g_strfreev (tokens);
995 : 18 : }
996 : :
997 : : #define TEST_SPLIT_SIMPLE0(_pattern, _string) { \
998 : : TestFetchAllData *data; \
999 : : gchar *path; \
1000 : : data = g_new0 (TestFetchAllData, 1); \
1001 : : data->pattern = _pattern; \
1002 : : data->string = _string; \
1003 : : data->expected = NULL; \
1004 : : path = g_strdup_printf ("/regex/split/simple0/%d", ++total); \
1005 : : g_test_add_data_func_full (path, data, test_split_simple, free_fetch_all_data); \
1006 : : g_free (path); \
1007 : : }
1008 : :
1009 : : #define TEST_SPLIT_SIMPLE1(_pattern, _string, e1) { \
1010 : : TestFetchAllData *data; \
1011 : : gchar *path; \
1012 : : data = g_new0 (TestFetchAllData, 1); \
1013 : : data->pattern = _pattern; \
1014 : : data->string = _string; \
1015 : : data->expected = g_slist_append (NULL, e1); \
1016 : : path = g_strdup_printf ("/regex/split/simple1/%d", ++total); \
1017 : : g_test_add_data_func_full (path, data, test_split_simple, free_fetch_all_data); \
1018 : : g_free (path); \
1019 : : }
1020 : :
1021 : : #define TEST_SPLIT_SIMPLE2(_pattern, _string, e1, e2) { \
1022 : : TestFetchAllData *data; \
1023 : : gchar *path; \
1024 : : data = g_new0 (TestFetchAllData, 1); \
1025 : : data->pattern = _pattern; \
1026 : : data->string = _string; \
1027 : : data->expected = g_slist_append (NULL, e1); \
1028 : : data->expected = g_slist_append (data->expected, e2); \
1029 : : path = g_strdup_printf ("/regex/split/simple2/%d", ++total); \
1030 : : g_test_add_data_func_full (path, data, test_split_simple, free_fetch_all_data); \
1031 : : g_free (path); \
1032 : : }
1033 : :
1034 : : #define TEST_SPLIT_SIMPLE3(_pattern, _string, e1, e2, e3) { \
1035 : : TestFetchAllData *data; \
1036 : : gchar *path; \
1037 : : data = g_new0 (TestFetchAllData, 1); \
1038 : : data->pattern = _pattern; \
1039 : : data->string = _string; \
1040 : : data->expected = g_slist_append (NULL, e1); \
1041 : : data->expected = g_slist_append (data->expected, e2); \
1042 : : data->expected = g_slist_append (data->expected, e3); \
1043 : : path = g_strdup_printf ("/regex/split/simple3/%d", ++total); \
1044 : : g_test_add_data_func_full (path, data, test_split_simple, free_fetch_all_data); \
1045 : : g_free (path); \
1046 : : }
1047 : :
1048 : : static void
1049 : 27 : test_split_full (gconstpointer d)
1050 : : {
1051 : 27 : const TestFetchAllData *data = d;
1052 : : GRegex *regex;
1053 : : GSList *l_exp;
1054 : : gchar **tokens;
1055 : : gint token_count;
1056 : : gint i;
1057 : :
1058 : 27 : regex = g_regex_new (data->pattern, G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL);
1059 : :
1060 : 27 : g_assert (regex != NULL);
1061 : :
1062 : 27 : tokens = g_regex_split_full (regex, data->string, -1, data->start_position,
1063 : 27 : 0, data->max_tokens, NULL);
1064 [ + - ]: 27 : if (tokens)
1065 : 27 : token_count = g_strv_length (tokens);
1066 : : else
1067 : 0 : token_count = 0;
1068 : :
1069 : 27 : g_assert_cmpint (token_count, ==, g_slist_length (data->expected));
1070 : :
1071 : 27 : l_exp = data->expected;
1072 [ + - + + ]: 76 : for (i = 0; l_exp != NULL; i++, l_exp = g_slist_next (l_exp))
1073 : : {
1074 : 49 : g_assert_nonnull (tokens);
1075 : 49 : g_assert_cmpstr (l_exp->data, ==, tokens[i]);
1076 : : }
1077 : :
1078 : 27 : g_regex_unref (regex);
1079 : 27 : g_strfreev (tokens);
1080 : 27 : }
1081 : :
1082 : : static void
1083 : 15 : test_split (gconstpointer d)
1084 : : {
1085 : 15 : const TestFetchAllData *data = d;
1086 : : GRegex *regex;
1087 : : GSList *l_exp;
1088 : : gchar **tokens;
1089 : : gint token_count;
1090 : : gint i;
1091 : :
1092 : 15 : regex = g_regex_new (data->pattern, G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL);
1093 : :
1094 : 15 : g_assert (regex != NULL);
1095 : :
1096 : 15 : tokens = g_regex_split (regex, data->string, 0);
1097 [ + - ]: 15 : if (tokens)
1098 : 15 : token_count = g_strv_length (tokens);
1099 : : else
1100 : 0 : token_count = 0;
1101 : :
1102 : 15 : g_assert_cmpint (token_count, ==, g_slist_length (data->expected));
1103 : :
1104 : 15 : l_exp = data->expected;
1105 [ + - + + ]: 47 : for (i = 0; l_exp != NULL; i++, l_exp = g_slist_next (l_exp))
1106 : : {
1107 : 32 : g_assert_nonnull (tokens);
1108 : 32 : g_assert_cmpstr (l_exp->data, ==, tokens[i]);
1109 : : }
1110 : :
1111 : 15 : g_regex_unref (regex);
1112 : 15 : g_strfreev (tokens);
1113 : 15 : }
1114 : :
1115 : : #define TEST_SPLIT0(_pattern, _string, _start_position, _max_tokens) { \
1116 : : TestFetchAllData *data; \
1117 : : gchar *path; \
1118 : : data = g_new0 (TestFetchAllData, 1); \
1119 : : data->pattern = _pattern; \
1120 : : data->string = _string; \
1121 : : data->start_position = _start_position; \
1122 : : data->max_tokens = _max_tokens; \
1123 : : data->expected = NULL; \
1124 : : if (_start_position == 0 && _max_tokens <= 0) { \
1125 : : path = g_strdup_printf ("/regex/split0/%d", ++total); \
1126 : : g_test_add_data_func (path, data, test_split); \
1127 : : g_free (path); \
1128 : : } \
1129 : : path = g_strdup_printf ("/regex/full-split0/%d", ++total); \
1130 : : g_test_add_data_func_full (path, data, test_split_full, free_fetch_all_data); \
1131 : : g_free (path); \
1132 : : }
1133 : :
1134 : : #define TEST_SPLIT1(_pattern, _string, _start_position, _max_tokens, e1) { \
1135 : : TestFetchAllData *data; \
1136 : : gchar *path; \
1137 : : data = g_new0 (TestFetchAllData, 1); \
1138 : : data->pattern = _pattern; \
1139 : : data->string = _string; \
1140 : : data->start_position = _start_position; \
1141 : : data->max_tokens = _max_tokens; \
1142 : : data->expected = NULL; \
1143 : : data->expected = g_slist_append (data->expected, e1); \
1144 : : if (_start_position == 0 && _max_tokens <= 0) { \
1145 : : path = g_strdup_printf ("/regex/split1/%d", ++total); \
1146 : : g_test_add_data_func (path, data, test_split); \
1147 : : g_free (path); \
1148 : : } \
1149 : : path = g_strdup_printf ("/regex/full-split1/%d", ++total); \
1150 : : g_test_add_data_func_full (path, data, test_split_full, free_fetch_all_data); \
1151 : : g_free (path); \
1152 : : }
1153 : :
1154 : : #define TEST_SPLIT2(_pattern, _string, _start_position, _max_tokens, e1, e2) { \
1155 : : TestFetchAllData *data; \
1156 : : gchar *path; \
1157 : : data = g_new0 (TestFetchAllData, 1); \
1158 : : data->pattern = _pattern; \
1159 : : data->string = _string; \
1160 : : data->start_position = _start_position; \
1161 : : data->max_tokens = _max_tokens; \
1162 : : data->expected = NULL; \
1163 : : data->expected = g_slist_append (data->expected, e1); \
1164 : : data->expected = g_slist_append (data->expected, e2); \
1165 : : if (_start_position == 0 && _max_tokens <= 0) { \
1166 : : path = g_strdup_printf ("/regex/split2/%d", ++total); \
1167 : : g_test_add_data_func (path, data, test_split); \
1168 : : g_free (path); \
1169 : : } \
1170 : : path = g_strdup_printf ("/regex/full-split2/%d", ++total); \
1171 : : g_test_add_data_func_full (path, data, test_split_full, free_fetch_all_data); \
1172 : : g_free (path); \
1173 : : }
1174 : :
1175 : : #define TEST_SPLIT3(_pattern, _string, _start_position, _max_tokens, e1, e2, e3) { \
1176 : : TestFetchAllData *data; \
1177 : : gchar *path; \
1178 : : data = g_new0 (TestFetchAllData, 1); \
1179 : : data->pattern = _pattern; \
1180 : : data->string = _string; \
1181 : : data->start_position = _start_position; \
1182 : : data->max_tokens = _max_tokens; \
1183 : : data->expected = NULL; \
1184 : : data->expected = g_slist_append (data->expected, e1); \
1185 : : data->expected = g_slist_append (data->expected, e2); \
1186 : : data->expected = g_slist_append (data->expected, e3); \
1187 : : if (_start_position == 0 && _max_tokens <= 0) { \
1188 : : path = g_strdup_printf ("/regex/split3/%d", ++total); \
1189 : : g_test_add_data_func (path, data, test_split); \
1190 : : g_free (path); \
1191 : : } \
1192 : : path = g_strdup_printf ("/regex/full-split3/%d", ++total); \
1193 : : g_test_add_data_func_full (path, data, test_split_full, free_fetch_all_data); \
1194 : : g_free (path); \
1195 : : }
1196 : :
1197 : : typedef struct {
1198 : : const gchar *string_to_expand;
1199 : : gboolean expected;
1200 : : gboolean expected_refs;
1201 : : } TestCheckReplacementData;
1202 : :
1203 : : static void
1204 : 8 : test_check_replacement (gconstpointer d)
1205 : : {
1206 : 8 : const TestCheckReplacementData *data = d;
1207 : : gboolean has_refs;
1208 : : gboolean result;
1209 : :
1210 : 8 : result = g_regex_check_replacement (data->string_to_expand, &has_refs, NULL);
1211 : 8 : g_assert_cmpint (data->expected, ==, result);
1212 : :
1213 [ + + ]: 8 : if (data->expected)
1214 : 6 : g_assert_cmpint (data->expected_refs, ==, has_refs);
1215 : 8 : }
1216 : :
1217 : : #define TEST_CHECK_REPLACEMENT(_string_to_expand, _expected, _expected_refs) { \
1218 : : TestCheckReplacementData *data; \
1219 : : gchar *path; \
1220 : : data = g_new0 (TestCheckReplacementData, 1); \
1221 : : data->string_to_expand = _string_to_expand; \
1222 : : data->expected = _expected; \
1223 : : data->expected_refs = _expected_refs; \
1224 : : path = g_strdup_printf ("/regex/check-repacement/%d", ++total); \
1225 : : g_test_add_data_func_full (path, data, test_check_replacement, g_free); \
1226 : : g_free (path); \
1227 : : }
1228 : :
1229 : : typedef struct {
1230 : : const gchar *pattern;
1231 : : const gchar *string;
1232 : : const gchar *string_to_expand;
1233 : : gboolean raw;
1234 : : const gchar *expected;
1235 : : } TestExpandData;
1236 : :
1237 : : static void
1238 : 66 : test_expand (gconstpointer d)
1239 : : {
1240 : 66 : const TestExpandData *data = d;
1241 : 66 : GRegex *regex = NULL;
1242 : 66 : GMatchInfo *match_info = NULL;
1243 : : gchar *res;
1244 : 66 : GError *error = NULL;
1245 : :
1246 [ + + ]: 66 : if (data->pattern)
1247 : : {
1248 [ + + ]: 62 : regex = g_regex_new (data->pattern, data->raw ? G_REGEX_RAW : 0,
1249 : : G_REGEX_MATCH_DEFAULT, &error);
1250 : 62 : g_assert_no_error (error);
1251 : 62 : g_regex_match (regex, data->string, 0, &match_info);
1252 : : }
1253 : :
1254 : 66 : res = g_match_info_expand_references (match_info, data->string_to_expand, NULL);
1255 : 66 : g_assert_cmpstr (res, ==, data->expected);
1256 : 66 : g_free (res);
1257 : 66 : g_match_info_free (match_info);
1258 [ + + ]: 66 : if (regex)
1259 : 62 : g_regex_unref (regex);
1260 : 66 : }
1261 : :
1262 : : #define TEST_EXPAND(_pattern, _string, _string_to_expand, _raw, _expected) { \
1263 : : TestExpandData *data; \
1264 : : gchar *path; \
1265 : : data = g_new0 (TestExpandData, 1); \
1266 : : data->pattern = _pattern; \
1267 : : data->string = _string; \
1268 : : data->string_to_expand = _string_to_expand; \
1269 : : data->raw = _raw; \
1270 : : data->expected = _expected; \
1271 : : path = g_strdup_printf ("/regex/expand/%d", ++total); \
1272 : : g_test_add_data_func_full (path, data, test_expand, g_free); \
1273 : : g_free (path); \
1274 : : }
1275 : :
1276 : : typedef struct {
1277 : : const gchar *pattern;
1278 : : const gchar *string;
1279 : : gint start_position;
1280 : : const gchar *replacement;
1281 : : const gchar *expected;
1282 : : GRegexCompileFlags compile_flags;
1283 : : GRegexMatchFlags match_flags;
1284 : : } TestReplaceData;
1285 : :
1286 : : static void
1287 : 56 : test_replace (gconstpointer d)
1288 : : {
1289 : 56 : const TestReplaceData *data = d;
1290 : : GRegex *regex;
1291 : : gchar *res;
1292 : 56 : GError *error = NULL;
1293 : :
1294 : 56 : regex = g_regex_new (data->pattern, data->compile_flags, G_REGEX_MATCH_DEFAULT, &error);
1295 : 56 : g_assert_no_error (error);
1296 : :
1297 : 56 : res = g_regex_replace (regex, data->string, -1, data->start_position,
1298 : 56 : data->replacement, data->match_flags, &error);
1299 : :
1300 : 56 : g_assert_cmpstr (res, ==, data->expected);
1301 : :
1302 [ + + ]: 56 : if (data->expected)
1303 : 52 : g_assert_no_error (error);
1304 : :
1305 : 56 : g_free (res);
1306 : 56 : g_regex_unref (regex);
1307 : 56 : g_clear_error (&error);
1308 : 56 : }
1309 : :
1310 : : #define TEST_REPLACE_OPTIONS(_pattern, _string, _start_position, _replacement, _expected, _compile_flags, _match_flags) { \
1311 : : TestReplaceData *data; \
1312 : : gchar *path; \
1313 : : data = g_new0 (TestReplaceData, 1); \
1314 : : data->pattern = _pattern; \
1315 : : data->string = _string; \
1316 : : data->start_position = _start_position; \
1317 : : data->replacement = _replacement; \
1318 : : data->expected = _expected; \
1319 : : data->compile_flags = _compile_flags; \
1320 : : data->match_flags = _match_flags; \
1321 : : total++; \
1322 : : if (data->compile_flags & G_REGEX_OPTIMIZE) \
1323 : : path = g_strdup_printf ("/regex/replace-optimized/%d", total); \
1324 : : else \
1325 : : path = g_strdup_printf ("/regex/replace/%d", total); \
1326 : : g_test_add_data_func_full (path, data, test_replace, g_free); \
1327 : : g_free (path); \
1328 : : data = g_memdup2 (data, sizeof (TestReplaceData)); \
1329 : : if (data->compile_flags & G_REGEX_OPTIMIZE) \
1330 : : { \
1331 : : data->compile_flags &= ~G_REGEX_OPTIMIZE; \
1332 : : path = g_strdup_printf ("/regex/replace/%d", total); \
1333 : : } \
1334 : : else \
1335 : : { \
1336 : : data->compile_flags |= G_REGEX_OPTIMIZE; \
1337 : : path = g_strdup_printf ("/regex/replace-optimized/%d", total); \
1338 : : } \
1339 : : g_test_add_data_func_full (path, data, test_replace, g_free); \
1340 : : g_free (path); \
1341 : : }
1342 : :
1343 : : #define TEST_REPLACE(_pattern, _string, _start_position, _replacement, _expected) \
1344 : : TEST_REPLACE_OPTIONS (_pattern, _string, _start_position, _replacement, _expected, 0, 0)
1345 : :
1346 : : static void
1347 : 20 : test_replace_lit (gconstpointer d)
1348 : : {
1349 : 20 : const TestReplaceData *data = d;
1350 : : GRegex *regex;
1351 : : gchar *res;
1352 : :
1353 : 20 : regex = g_regex_new (data->pattern, G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL);
1354 : 20 : res = g_regex_replace_literal (regex, data->string, -1, data->start_position,
1355 : 20 : data->replacement, 0, NULL);
1356 : 20 : g_assert_cmpstr (res, ==, data->expected);
1357 : :
1358 : 20 : g_free (res);
1359 : 20 : g_regex_unref (regex);
1360 : 20 : }
1361 : :
1362 : : #define TEST_REPLACE_LIT(_pattern, _string, _start_position, _replacement, _expected) { \
1363 : : TestReplaceData *data; \
1364 : : gchar *path; \
1365 : : data = g_new0 (TestReplaceData, 1); \
1366 : : data->pattern = _pattern; \
1367 : : data->string = _string; \
1368 : : data->start_position = _start_position; \
1369 : : data->replacement = _replacement; \
1370 : : data->expected = _expected; \
1371 : : path = g_strdup_printf ("/regex/replace-literally/%d", ++total); \
1372 : : g_test_add_data_func_full (path, data, test_replace_lit, g_free); \
1373 : : g_free (path); \
1374 : : }
1375 : :
1376 : : typedef struct {
1377 : : const gchar *pattern;
1378 : : const gchar *name;
1379 : : gint expected_num;
1380 : : } TestStringNumData;
1381 : :
1382 : : static void
1383 : 15 : test_get_string_number (gconstpointer d)
1384 : : {
1385 : 15 : const TestStringNumData *data = d;
1386 : : GRegex *regex;
1387 : : gint num;
1388 : :
1389 : 15 : regex = g_regex_new (data->pattern, G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL);
1390 : 15 : num = g_regex_get_string_number (regex, data->name);
1391 : :
1392 : 15 : g_assert_cmpint (num, ==, data->expected_num);
1393 : 15 : g_regex_unref (regex);
1394 : 15 : }
1395 : :
1396 : : #define TEST_GET_STRING_NUMBER(_pattern, _name, _expected_num) { \
1397 : : TestStringNumData *data; \
1398 : : gchar *path; \
1399 : : data = g_new0 (TestStringNumData, 1); \
1400 : : data->pattern = _pattern; \
1401 : : data->name = _name; \
1402 : : data->expected_num = _expected_num; \
1403 : : path = g_strdup_printf ("/regex/string-number/%d", ++total); \
1404 : : g_test_add_data_func_full (path, data, test_get_string_number, g_free); \
1405 : : g_free (path); \
1406 : : }
1407 : :
1408 : : typedef struct {
1409 : : const gchar *string;
1410 : : gint length;
1411 : : const gchar *expected;
1412 : : } TestEscapeData;
1413 : :
1414 : : static void
1415 : 18 : test_escape (gconstpointer d)
1416 : : {
1417 : 18 : const TestEscapeData *data = d;
1418 : : gchar *escaped;
1419 : :
1420 : 18 : escaped = g_regex_escape_string (data->string, data->length);
1421 : :
1422 : 18 : g_assert_cmpstr (escaped, ==, data->expected);
1423 : :
1424 : 18 : g_free (escaped);
1425 : 18 : }
1426 : :
1427 : : #define TEST_ESCAPE(_string, _length, _expected) { \
1428 : : TestEscapeData *data; \
1429 : : gchar *path; \
1430 : : data = g_new0 (TestEscapeData, 1); \
1431 : : data->string = _string; \
1432 : : data->length = _length; \
1433 : : data->expected = _expected; \
1434 : : path = g_strdup_printf ("/regex/escape/%d", ++total); \
1435 : : g_test_add_data_func_full (path, data, test_escape, g_free); \
1436 : : g_free (path); \
1437 : : }
1438 : :
1439 : : static void
1440 : 15 : test_escape_nul (gconstpointer d)
1441 : : {
1442 : 15 : const TestEscapeData *data = d;
1443 : : gchar *escaped;
1444 : :
1445 : 15 : escaped = g_regex_escape_nul (data->string, data->length);
1446 : :
1447 : 15 : g_assert_cmpstr (escaped, ==, data->expected);
1448 : :
1449 : 15 : g_free (escaped);
1450 : 15 : }
1451 : :
1452 : : #define TEST_ESCAPE_NUL(_string, _length, _expected) { \
1453 : : TestEscapeData *data; \
1454 : : gchar *path; \
1455 : : data = g_new0 (TestEscapeData, 1); \
1456 : : data->string = _string; \
1457 : : data->length = _length; \
1458 : : data->expected = _expected; \
1459 : : path = g_strdup_printf ("/regex/escape_nul/%d", ++total); \
1460 : : g_test_add_data_func_full (path, data, test_escape_nul, g_free); \
1461 : : g_free (path); \
1462 : : }
1463 : :
1464 : : typedef struct {
1465 : : const gchar *pattern;
1466 : : const gchar *string;
1467 : : gssize string_len;
1468 : : gint start_position;
1469 : : GSList *expected;
1470 : : } TestMatchAllData;
1471 : :
1472 : : static void
1473 : 15 : test_match_all_full (gconstpointer d)
1474 : : {
1475 : 15 : const TestMatchAllData *data = d;
1476 : : GRegex *regex;
1477 : : GMatchInfo *match_info;
1478 : : GSList *l_exp;
1479 : : gboolean match_ok;
1480 : : gint match_count;
1481 : : gint i;
1482 : :
1483 : 15 : regex = g_regex_new (data->pattern, G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL);
1484 : 15 : match_ok = g_regex_match_all_full (regex, data->string, data->string_len, data->start_position,
1485 : : 0, &match_info, NULL);
1486 : :
1487 [ + + ]: 15 : if (g_slist_length (data->expected) == 0)
1488 : 4 : g_assert (!match_ok);
1489 : : else
1490 : 11 : g_assert (match_ok);
1491 : :
1492 : 15 : match_count = g_match_info_get_match_count (match_info);
1493 : 15 : g_assert_cmpint (match_count, ==, g_slist_length (data->expected));
1494 : :
1495 : 15 : l_exp = data->expected;
1496 [ + + ]: 33 : for (i = 0; i < match_count; i++)
1497 : : {
1498 : : gint start, end;
1499 : : gchar *matched_string;
1500 : 18 : Match *exp = l_exp->data;
1501 : :
1502 : 18 : matched_string = g_match_info_fetch (match_info, i);
1503 : 18 : g_match_info_fetch_pos (match_info, i, &start, &end);
1504 : :
1505 : 18 : g_assert_cmpstr (exp->string, ==, matched_string);
1506 : 18 : g_assert_cmpint (exp->start, ==, start);
1507 : 18 : g_assert_cmpint (exp->end, ==, end);
1508 : :
1509 : 18 : g_free (matched_string);
1510 : :
1511 [ + - ]: 18 : l_exp = g_slist_next (l_exp);
1512 : : }
1513 : :
1514 : 15 : g_match_info_free (match_info);
1515 : 15 : g_regex_unref (regex);
1516 : 15 : }
1517 : :
1518 : : static void
1519 : 10 : test_match_all (gconstpointer d)
1520 : : {
1521 : 10 : const TestMatchAllData *data = d;
1522 : : GRegex *regex;
1523 : : GMatchInfo *match_info;
1524 : : GSList *l_exp;
1525 : : gboolean match_ok;
1526 : : guint i, match_count;
1527 : :
1528 : 10 : regex = g_regex_new (data->pattern, G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL);
1529 : 10 : match_ok = g_regex_match_all (regex, data->string, 0, &match_info);
1530 : :
1531 [ + + ]: 10 : if (g_slist_length (data->expected) == 0)
1532 : 2 : g_assert (!match_ok);
1533 : : else
1534 : 8 : g_assert (match_ok);
1535 : :
1536 : 10 : match_count = g_match_info_get_match_count (match_info);
1537 : 10 : g_assert_cmpint (match_count, >=, 0);
1538 : :
1539 [ - + ]: 10 : if (match_count != g_slist_length (data->expected))
1540 : : {
1541 : 0 : g_message ("regex: %s", data->pattern);
1542 : 0 : g_message ("string: %s", data->string);
1543 : 0 : g_message ("matched strings:");
1544 : :
1545 [ # # ]: 0 : for (i = 0; i < match_count; i++)
1546 : : {
1547 : : gint start, end;
1548 : : gchar *matched_string;
1549 : :
1550 : 0 : matched_string = g_match_info_fetch (match_info, i);
1551 : 0 : g_match_info_fetch_pos (match_info, i, &start, &end);
1552 : 0 : g_message ("%u. %d-%d '%s'", i, start, end, matched_string);
1553 : 0 : g_free (matched_string);
1554 : : }
1555 : :
1556 : 0 : g_message ("expected strings:");
1557 : 0 : i = 0;
1558 : :
1559 [ # # ]: 0 : for (l_exp = data->expected; l_exp != NULL; l_exp = l_exp->next)
1560 : : {
1561 : 0 : Match *exp = l_exp->data;
1562 : :
1563 : 0 : g_message ("%u. %d-%d '%s'", i, exp->start, exp->end, exp->string);
1564 : 0 : i++;
1565 : : }
1566 : :
1567 : 0 : g_error ("match_count not as expected: %u != %d",
1568 : : match_count, g_slist_length (data->expected));
1569 : : }
1570 : :
1571 : 10 : l_exp = data->expected;
1572 [ + + ]: 25 : for (i = 0; i < match_count; i++)
1573 : : {
1574 : : gint start, end;
1575 : : gchar *matched_string;
1576 : 15 : Match *exp = l_exp->data;
1577 : :
1578 : 15 : matched_string = g_match_info_fetch (match_info, i);
1579 : 15 : g_match_info_fetch_pos (match_info, i, &start, &end);
1580 : :
1581 : 15 : g_assert_cmpstr (exp->string, ==, matched_string);
1582 : 15 : g_assert_cmpint (exp->start, ==, start);
1583 : 15 : g_assert_cmpint (exp->end, ==, end);
1584 : :
1585 : 15 : g_free (matched_string);
1586 : :
1587 [ + - ]: 15 : l_exp = g_slist_next (l_exp);
1588 : : }
1589 : :
1590 : 10 : g_match_info_free (match_info);
1591 : 10 : g_regex_unref (regex);
1592 : 10 : }
1593 : :
1594 : : static void
1595 : 15 : free_match_all_data (gpointer _data)
1596 : : {
1597 : 15 : TestMatchAllData *data = _data;
1598 : :
1599 : 15 : g_slist_free_full (data->expected, g_free);
1600 : 15 : g_free (data);
1601 : 15 : }
1602 : :
1603 : : #define TEST_MATCH_ALL0(_pattern, _string, _string_len, _start_position) { \
1604 : : TestMatchAllData *data; \
1605 : : gchar *path; \
1606 : : data = g_new0 (TestMatchAllData, 1); \
1607 : : data->pattern = _pattern; \
1608 : : data->string = _string; \
1609 : : data->string_len = _string_len; \
1610 : : data->start_position = _start_position; \
1611 : : data->expected = NULL; \
1612 : : if (_string_len == -1 && _start_position == 0) { \
1613 : : path = g_strdup_printf ("/regex/match-all0/%d", ++total); \
1614 : : g_test_add_data_func (path, data, test_match_all); \
1615 : : g_free (path); \
1616 : : } \
1617 : : path = g_strdup_printf ("/regex/match-all-full0/%d", ++total); \
1618 : : g_test_add_data_func_full (path, data, test_match_all_full, free_match_all_data); \
1619 : : g_free (path); \
1620 : : }
1621 : :
1622 : : #define TEST_MATCH_ALL1(_pattern, _string, _string_len, _start_position, \
1623 : : t1, s1, e1) { \
1624 : : TestMatchAllData *data; \
1625 : : Match *match; \
1626 : : gchar *path; \
1627 : : data = g_new0 (TestMatchAllData, 1); \
1628 : : data->pattern = _pattern; \
1629 : : data->string = _string; \
1630 : : data->string_len = _string_len; \
1631 : : data->start_position = _start_position; \
1632 : : data->expected = NULL; \
1633 : : match = g_new0 (Match, 1); \
1634 : : match->string = t1; \
1635 : : match->start = s1; \
1636 : : match->end = e1; \
1637 : : data->expected = g_slist_append (data->expected, match); \
1638 : : if (_string_len == -1 && _start_position == 0) { \
1639 : : path = g_strdup_printf ("/regex/match-all1/%d", ++total); \
1640 : : g_test_add_data_func (path, data, test_match_all); \
1641 : : g_free (path); \
1642 : : } \
1643 : : path = g_strdup_printf ("/regex/match-all-full1/%d", ++total); \
1644 : : g_test_add_data_func_full (path, data, test_match_all_full, free_match_all_data); \
1645 : : g_free (path); \
1646 : : }
1647 : :
1648 : : #define TEST_MATCH_ALL2(_pattern, _string, _string_len, _start_position, \
1649 : : t1, s1, e1, t2, s2, e2) { \
1650 : : TestMatchAllData *data; \
1651 : : Match *match; \
1652 : : gchar *path; \
1653 : : data = g_new0 (TestMatchAllData, 1); \
1654 : : data->pattern = _pattern; \
1655 : : data->string = _string; \
1656 : : data->string_len = _string_len; \
1657 : : data->start_position = _start_position; \
1658 : : data->expected = NULL; \
1659 : : match = g_new0 (Match, 1); \
1660 : : match->string = t1; \
1661 : : match->start = s1; \
1662 : : match->end = e1; \
1663 : : data->expected = g_slist_append (data->expected, match); \
1664 : : match = g_new0 (Match, 1); \
1665 : : match->string = t2; \
1666 : : match->start = s2; \
1667 : : match->end = e2; \
1668 : : data->expected = g_slist_append (data->expected, match); \
1669 : : if (_string_len == -1 && _start_position == 0) { \
1670 : : path = g_strdup_printf ("/regex/match-all2/%d", ++total); \
1671 : : g_test_add_data_func (path, data, test_match_all); \
1672 : : g_free (path); \
1673 : : } \
1674 : : path = g_strdup_printf ("/regex/match-all-full2/%d", ++total); \
1675 : : g_test_add_data_func_full (path, data, test_match_all_full, free_match_all_data); \
1676 : : g_free (path); \
1677 : : }
1678 : :
1679 : : #define TEST_MATCH_ALL3(_pattern, _string, _string_len, _start_position, \
1680 : : t1, s1, e1, t2, s2, e2, t3, s3, e3) { \
1681 : : TestMatchAllData *data; \
1682 : : Match *match; \
1683 : : gchar *path; \
1684 : : data = g_new0 (TestMatchAllData, 1); \
1685 : : data->pattern = _pattern; \
1686 : : data->string = _string; \
1687 : : data->string_len = _string_len; \
1688 : : data->start_position = _start_position; \
1689 : : data->expected = NULL; \
1690 : : match = g_new0 (Match, 1); \
1691 : : match->string = t1; \
1692 : : match->start = s1; \
1693 : : match->end = e1; \
1694 : : data->expected = g_slist_append (data->expected, match); \
1695 : : match = g_new0 (Match, 1); \
1696 : : match->string = t2; \
1697 : : match->start = s2; \
1698 : : match->end = e2; \
1699 : : data->expected = g_slist_append (data->expected, match); \
1700 : : match = g_new0 (Match, 1); \
1701 : : match->string = t3; \
1702 : : match->start = s3; \
1703 : : match->end = e3; \
1704 : : data->expected = g_slist_append (data->expected, match); \
1705 : : if (_string_len == -1 && _start_position == 0) { \
1706 : : path = g_strdup_printf ("/regex/match-all3/%d", ++total); \
1707 : : g_test_add_data_func (path, data, test_match_all); \
1708 : : g_free (path); \
1709 : : } \
1710 : : path = g_strdup_printf ("/regex/match-all-full3/%d", ++total); \
1711 : : g_test_add_data_func_full (path, data, test_match_all_full, free_match_all_data); \
1712 : : g_free (path); \
1713 : : }
1714 : :
1715 : : static void
1716 : 1 : test_properties (void)
1717 : : {
1718 : : GRegex *regex;
1719 : : GError *error;
1720 : : gboolean res;
1721 : : GMatchInfo *match;
1722 : : gchar *str;
1723 : :
1724 : 1 : error = NULL;
1725 : 1 : regex = g_regex_new ("\\p{L}\\p{Ll}\\p{Lu}\\p{L&}\\p{N}\\p{Nd}", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
1726 : 1 : res = g_regex_match (regex, "ppPP01", 0, &match);
1727 : 1 : g_assert (res);
1728 : 1 : str = g_match_info_fetch (match, 0);
1729 : 1 : g_assert_cmpstr (str, ==, "ppPP01");
1730 : 1 : g_free (str);
1731 : :
1732 : 1 : g_match_info_free (match);
1733 : 1 : g_regex_unref (regex);
1734 : 1 : }
1735 : :
1736 : : static void
1737 : 1 : test_class (void)
1738 : : {
1739 : : GRegex *regex;
1740 : : GError *error;
1741 : : GMatchInfo *match;
1742 : : gboolean res;
1743 : : gchar *str;
1744 : :
1745 : 1 : error = NULL;
1746 : 1 : regex = g_regex_new ("[abc\\x{0B1E}\\p{Mn}\\x{0391}-\\x{03A9}]", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
1747 : 1 : res = g_regex_match (regex, "a:b:\340\254\236:\333\253:\316\240", 0, &match);
1748 : 1 : g_assert (res);
1749 : 1 : str = g_match_info_fetch (match, 0);
1750 : 1 : g_assert_cmpstr (str, ==, "a");
1751 : 1 : g_free (str);
1752 : 1 : res = g_match_info_next (match, NULL);
1753 : 1 : g_assert (res);
1754 : 1 : str = g_match_info_fetch (match, 0);
1755 : 1 : g_assert_cmpstr (str, ==, "b");
1756 : 1 : g_free (str);
1757 : 1 : res = g_match_info_next (match, NULL);
1758 : 1 : g_assert (res);
1759 : 1 : str = g_match_info_fetch (match, 0);
1760 : 1 : g_assert_cmpstr (str, ==, "\340\254\236");
1761 : 1 : g_free (str);
1762 : 1 : res = g_match_info_next (match, NULL);
1763 : 1 : g_assert (res);
1764 : 1 : str = g_match_info_fetch (match, 0);
1765 : 1 : g_assert_cmpstr (str, ==, "\333\253");
1766 : 1 : g_free (str);
1767 : 1 : res = g_match_info_next (match, NULL);
1768 : 1 : g_assert (res);
1769 : 1 : str = g_match_info_fetch (match, 0);
1770 : 1 : g_assert_cmpstr (str, ==, "\316\240");
1771 : 1 : g_free (str);
1772 : :
1773 : 1 : res = g_match_info_next (match, NULL);
1774 : 1 : g_assert (!res);
1775 : :
1776 : : /* Accessing match again should not crash */
1777 : 1 : g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL,
1778 : : "*match_info->pos >= 0*");
1779 : 1 : g_assert_false (g_match_info_next (match, NULL));
1780 : 1 : g_test_assert_expected_messages ();
1781 : :
1782 : 1 : g_match_info_free (match);
1783 : 1 : g_regex_unref (regex);
1784 : 1 : }
1785 : :
1786 : : /* examples for lookahead assertions taken from pcrepattern(3) */
1787 : : static void
1788 : 1 : test_lookahead (void)
1789 : : {
1790 : : GRegex *regex;
1791 : : GError *error;
1792 : : GMatchInfo *match;
1793 : : gboolean res;
1794 : : gchar *str;
1795 : : gint start, end;
1796 : :
1797 : 1 : error = NULL;
1798 : 1 : regex = g_regex_new ("\\w+(?=;)", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
1799 : 1 : g_assert (regex);
1800 : 1 : g_assert_no_error (error);
1801 : 1 : res = g_regex_match (regex, "word1 word2: word3;", 0, &match);
1802 : 1 : g_assert (res);
1803 : 1 : g_assert (g_match_info_matches (match));
1804 : 1 : g_assert_cmpint (g_match_info_get_match_count (match), ==, 1);
1805 : 1 : str = g_match_info_fetch (match, 0);
1806 : 1 : g_assert_cmpstr (str, ==, "word3");
1807 : 1 : g_free (str);
1808 : 1 : g_match_info_free (match);
1809 : 1 : g_regex_unref (regex);
1810 : :
1811 : 1 : error = NULL;
1812 : 1 : regex = g_regex_new ("foo(?!bar)", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
1813 : 1 : g_assert (regex);
1814 : 1 : g_assert_no_error (error);
1815 : 1 : res = g_regex_match (regex, "foobar foobaz", 0, &match);
1816 : 1 : g_assert (res);
1817 : 1 : g_assert (g_match_info_matches (match));
1818 : 1 : g_assert_cmpint (g_match_info_get_match_count (match), ==, 1);
1819 : 1 : res = g_match_info_fetch_pos (match, 0, &start, &end);
1820 : 1 : g_assert (res);
1821 : 1 : g_assert_cmpint (start, ==, 7);
1822 : 1 : g_assert_cmpint (end, ==, 10);
1823 : 1 : g_match_info_free (match);
1824 : 1 : g_regex_unref (regex);
1825 : :
1826 : 1 : error = NULL;
1827 : 1 : regex = g_regex_new ("(?!bar)foo", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
1828 : 1 : g_assert (regex);
1829 : 1 : g_assert_no_error (error);
1830 : 1 : res = g_regex_match (regex, "foobar foobaz", 0, &match);
1831 : 1 : g_assert (res);
1832 : 1 : g_assert (g_match_info_matches (match));
1833 : 1 : g_assert_cmpint (g_match_info_get_match_count (match), ==, 1);
1834 : 1 : res = g_match_info_fetch_pos (match, 0, &start, &end);
1835 : 1 : g_assert (res);
1836 : 1 : g_assert_cmpint (start, ==, 0);
1837 : 1 : g_assert_cmpint (end, ==, 3);
1838 : 1 : res = g_match_info_next (match, &error);
1839 : 1 : g_assert (res);
1840 : 1 : g_assert_no_error (error);
1841 : 1 : res = g_match_info_fetch_pos (match, 0, &start, &end);
1842 : 1 : g_assert (res);
1843 : 1 : g_assert_cmpint (start, ==, 7);
1844 : 1 : g_assert_cmpint (end, ==, 10);
1845 : 1 : g_match_info_free (match);
1846 : 1 : g_regex_unref (regex);
1847 : 1 : }
1848 : :
1849 : : /* examples for lookbehind assertions taken from pcrepattern(3) */
1850 : : static void
1851 : 1 : test_lookbehind (void)
1852 : : {
1853 : : GRegex *regex;
1854 : : GError *error;
1855 : : GMatchInfo *match;
1856 : : gboolean res;
1857 : : gint start, end;
1858 : :
1859 : 1 : error = NULL;
1860 : 1 : regex = g_regex_new ("(?<!foo)bar", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
1861 : 1 : g_assert (regex);
1862 : 1 : g_assert_no_error (error);
1863 : 1 : res = g_regex_match (regex, "foobar boobar", 0, &match);
1864 : 1 : g_assert (res);
1865 : 1 : g_assert (g_match_info_matches (match));
1866 : 1 : g_assert_cmpint (g_match_info_get_match_count (match), ==, 1);
1867 : 1 : res = g_match_info_fetch_pos (match, 0, &start, &end);
1868 : 1 : g_assert (res);
1869 : 1 : g_assert_cmpint (start, ==, 10);
1870 : 1 : g_assert_cmpint (end, ==, 13);
1871 : 1 : g_match_info_free (match);
1872 : 1 : g_regex_unref (regex);
1873 : :
1874 : 1 : error = NULL;
1875 : 1 : regex = g_regex_new ("(?<=bullock|donkey) poo", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
1876 : 1 : g_assert (regex);
1877 : 1 : g_assert_no_error (error);
1878 : 1 : res = g_regex_match (regex, "don poo, and bullock poo", 0, &match);
1879 : 1 : g_assert (res);
1880 : 1 : g_assert (g_match_info_matches (match));
1881 : 1 : g_assert_cmpint (g_match_info_get_match_count (match), ==, 1);
1882 : 1 : res = g_match_info_fetch_pos (match, 0, &start, NULL);
1883 : 1 : g_assert (res);
1884 : 1 : g_assert_cmpint (start, ==, 20);
1885 : 1 : g_match_info_free (match);
1886 : 1 : g_regex_unref (regex);
1887 : :
1888 : 1 : regex = g_regex_new ("(?<=abc|abde)foo", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
1889 : 1 : g_assert (regex);
1890 : 1 : g_assert_no_error (error);
1891 : 1 : res = g_regex_match (regex, "abfoo, abdfoo, abcfoo", 0, &match);
1892 : 1 : g_assert (res);
1893 : 1 : g_assert (g_match_info_matches (match));
1894 : 1 : res = g_match_info_fetch_pos (match, 0, &start, NULL);
1895 : 1 : g_assert (res);
1896 : 1 : g_assert_cmpint (start, ==, 18);
1897 : 1 : g_match_info_free (match);
1898 : 1 : g_regex_unref (regex);
1899 : :
1900 : 1 : regex = g_regex_new ("^.*+(?<=abcd)", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
1901 : 1 : g_assert (regex);
1902 : 1 : g_assert_no_error (error);
1903 : 1 : res = g_regex_match (regex, "abcabcabcabcabcabcabcabcabcd", 0, &match);
1904 : 1 : g_assert (res);
1905 : 1 : g_assert (g_match_info_matches (match));
1906 : 1 : g_match_info_free (match);
1907 : 1 : g_regex_unref (regex);
1908 : :
1909 : 1 : regex = g_regex_new ("(?<=\\d{3})(?<!999)foo", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
1910 : 1 : g_assert (regex);
1911 : 1 : g_assert_no_error (error);
1912 : 1 : res = g_regex_match (regex, "999foo 123abcfoo 123foo", 0, &match);
1913 : 1 : g_assert (res);
1914 : 1 : g_assert (g_match_info_matches (match));
1915 : 1 : res = g_match_info_fetch_pos (match, 0, &start, NULL);
1916 : 1 : g_assert (res);
1917 : 1 : g_assert_cmpint (start, ==, 20);
1918 : 1 : g_match_info_free (match);
1919 : 1 : g_regex_unref (regex);
1920 : :
1921 : 1 : regex = g_regex_new ("(?<=\\d{3}...)(?<!999)foo", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
1922 : 1 : g_assert (regex);
1923 : 1 : g_assert_no_error (error);
1924 : 1 : res = g_regex_match (regex, "999foo 123abcfoo 123foo", 0, &match);
1925 : 1 : g_assert (res);
1926 : 1 : g_assert (g_match_info_matches (match));
1927 : 1 : res = g_match_info_fetch_pos (match, 0, &start, NULL);
1928 : 1 : g_assert (res);
1929 : 1 : g_assert_cmpint (start, ==, 13);
1930 : 1 : g_match_info_free (match);
1931 : 1 : g_regex_unref (regex);
1932 : :
1933 : 1 : regex = g_regex_new ("(?<=\\d{3}(?!999)...)foo", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
1934 : 1 : g_assert (regex);
1935 : 1 : g_assert_no_error (error);
1936 : 1 : res = g_regex_match (regex, "999foo 123abcfoo 123foo", 0, &match);
1937 : 1 : g_assert (res);
1938 : 1 : g_assert (g_match_info_matches (match));
1939 : 1 : res = g_match_info_fetch_pos (match, 0, &start, NULL);
1940 : 1 : g_assert (res);
1941 : 1 : g_assert_cmpint (start, ==, 13);
1942 : 1 : g_match_info_free (match);
1943 : 1 : g_regex_unref (regex);
1944 : :
1945 : 1 : regex = g_regex_new ("(?<=(?<!foo)bar)baz", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
1946 : 1 : g_assert (regex);
1947 : 1 : g_assert_no_error (error);
1948 : 1 : res = g_regex_match (regex, "foobarbaz barfoobaz barbarbaz", 0, &match);
1949 : 1 : g_assert (res);
1950 : 1 : g_assert (g_match_info_matches (match));
1951 : 1 : res = g_match_info_fetch_pos (match, 0, &start, NULL);
1952 : 1 : g_assert (res);
1953 : 1 : g_assert_cmpint (start, ==, 26);
1954 : 1 : g_match_info_free (match);
1955 : 1 : g_regex_unref (regex);
1956 : 1 : }
1957 : :
1958 : : /* examples for subpatterns taken from pcrepattern(3) */
1959 : : static void
1960 : 1 : test_subpattern (void)
1961 : : {
1962 : : GRegex *regex;
1963 : : GError *error;
1964 : : GMatchInfo *match;
1965 : : gboolean res;
1966 : : gchar *str;
1967 : : gint start;
1968 : :
1969 : 1 : error = NULL;
1970 : 1 : regex = g_regex_new ("cat(aract|erpillar|)", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
1971 : 1 : g_assert (regex);
1972 : 1 : g_assert_no_error (error);
1973 : 1 : g_assert_cmpint (g_regex_get_capture_count (regex), ==, 1);
1974 : 1 : g_assert_cmpint (g_regex_get_max_backref (regex), ==, 0);
1975 : 1 : res = g_regex_match_all (regex, "caterpillar", 0, &match);
1976 : 1 : g_assert (res);
1977 : 1 : g_assert (g_match_info_matches (match));
1978 : 1 : g_assert_cmpint (g_match_info_get_match_count (match), ==, 2);
1979 : 1 : str = g_match_info_fetch (match, 0);
1980 : 1 : g_assert_cmpstr (str, ==, "caterpillar");
1981 : 1 : g_free (str);
1982 : 1 : str = g_match_info_fetch (match, 1);
1983 : 1 : g_assert_cmpstr (str, ==, "cat");
1984 : 1 : g_free (str);
1985 : 1 : g_match_info_free (match);
1986 : 1 : g_regex_unref (regex);
1987 : :
1988 : 1 : regex = g_regex_new ("the ((red|white) (king|queen))", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
1989 : 1 : g_assert (regex);
1990 : 1 : g_assert_no_error (error);
1991 : 1 : g_assert_cmpint (g_regex_get_capture_count (regex), ==, 3);
1992 : 1 : g_assert_cmpint (g_regex_get_max_backref (regex), ==, 0);
1993 : 1 : res = g_regex_match (regex, "the red king", 0, &match);
1994 : 1 : g_assert (res);
1995 : 1 : g_assert (g_match_info_matches (match));
1996 : 1 : g_assert_cmpint (g_match_info_get_match_count (match), ==, 4);
1997 : 1 : str = g_match_info_fetch (match, 0);
1998 : 1 : g_assert_cmpstr (str, ==, "the red king");
1999 : 1 : g_free (str);
2000 : 1 : str = g_match_info_fetch (match, 1);
2001 : 1 : g_assert_cmpstr (str, ==, "red king");
2002 : 1 : g_free (str);
2003 : 1 : str = g_match_info_fetch (match, 2);
2004 : 1 : g_assert_cmpstr (str, ==, "red");
2005 : 1 : g_free (str);
2006 : 1 : str = g_match_info_fetch (match, 3);
2007 : 1 : g_assert_cmpstr (str, ==, "king");
2008 : 1 : g_free (str);
2009 : 1 : g_match_info_free (match);
2010 : 1 : g_regex_unref (regex);
2011 : :
2012 : 1 : regex = g_regex_new ("the ((?:red|white) (king|queen))", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
2013 : 1 : g_assert (regex);
2014 : 1 : g_assert_no_error (error);
2015 : 1 : res = g_regex_match (regex, "the white queen", 0, &match);
2016 : 1 : g_assert (res);
2017 : 1 : g_assert (g_match_info_matches (match));
2018 : 1 : g_assert_cmpint (g_match_info_get_match_count (match), ==, 3);
2019 : 1 : g_assert_cmpint (g_regex_get_max_backref (regex), ==, 0);
2020 : 1 : str = g_match_info_fetch (match, 0);
2021 : 1 : g_assert_cmpstr (str, ==, "the white queen");
2022 : 1 : g_free (str);
2023 : 1 : str = g_match_info_fetch (match, 1);
2024 : 1 : g_assert_cmpstr (str, ==, "white queen");
2025 : 1 : g_free (str);
2026 : 1 : str = g_match_info_fetch (match, 2);
2027 : 1 : g_assert_cmpstr (str, ==, "queen");
2028 : 1 : g_free (str);
2029 : 1 : g_match_info_free (match);
2030 : 1 : g_regex_unref (regex);
2031 : :
2032 : 1 : regex = g_regex_new ("(?|(Sat)(ur)|(Sun))day (morning|afternoon)", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
2033 : 1 : g_assert (regex);
2034 : 1 : g_assert_no_error (error);
2035 : 1 : g_assert_cmpint (g_regex_get_capture_count (regex), ==, 3);
2036 : 1 : res = g_regex_match (regex, "Saturday morning", 0, &match);
2037 : 1 : g_assert (res);
2038 : 1 : g_assert (g_match_info_matches (match));
2039 : 1 : g_assert_cmpint (g_match_info_get_match_count (match), ==, 4);
2040 : 1 : str = g_match_info_fetch (match, 1);
2041 : 1 : g_assert_cmpstr (str, ==, "Sat");
2042 : 1 : g_free (str);
2043 : 1 : str = g_match_info_fetch (match, 2);
2044 : 1 : g_assert_cmpstr (str, ==, "ur");
2045 : 1 : g_free (str);
2046 : 1 : str = g_match_info_fetch (match, 3);
2047 : 1 : g_assert_cmpstr (str, ==, "morning");
2048 : 1 : g_free (str);
2049 : 1 : g_match_info_free (match);
2050 : 1 : g_regex_unref (regex);
2051 : :
2052 : 1 : regex = g_regex_new ("(?|(abc)|(def))\\1", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
2053 : 1 : g_assert (regex);
2054 : 1 : g_assert_no_error (error);
2055 : 1 : g_assert_cmpint (g_regex_get_max_backref (regex), ==, 1);
2056 : 1 : res = g_regex_match (regex, "abcabc abcdef defabc defdef", 0, &match);
2057 : 1 : g_assert (res);
2058 : 1 : g_assert (g_match_info_matches (match));
2059 : 1 : res = g_match_info_fetch_pos (match, 0, &start, NULL);
2060 : 1 : g_assert (res);
2061 : 1 : g_assert_cmpint (start, ==, 0);
2062 : 1 : res = g_match_info_next (match, &error);
2063 : 1 : g_assert (res);
2064 : 1 : res = g_match_info_fetch_pos (match, 0, &start, NULL);
2065 : 1 : g_assert (res);
2066 : 1 : g_assert_cmpint (start, ==, 21);
2067 : 1 : g_match_info_free (match);
2068 : 1 : g_regex_unref (regex);
2069 : :
2070 : 1 : regex = g_regex_new ("(?|(abc)|(def))(?1)", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
2071 : 1 : g_assert (regex);
2072 : 1 : g_assert_no_error (error);
2073 : 1 : res = g_regex_match (regex, "abcabc abcdef defabc defdef", 0, &match);
2074 : 1 : g_assert (res);
2075 : 1 : g_assert (g_match_info_matches (match));
2076 : 1 : res = g_match_info_fetch_pos (match, 0, &start, NULL);
2077 : 1 : g_assert (res);
2078 : 1 : g_assert_cmpint (start, ==, 0);
2079 : 1 : res = g_match_info_next (match, &error);
2080 : 1 : g_assert (res);
2081 : 1 : res = g_match_info_fetch_pos (match, 0, &start, NULL);
2082 : 1 : g_assert (res);
2083 : 1 : g_assert_cmpint (start, ==, 14);
2084 : 1 : g_match_info_free (match);
2085 : 1 : g_regex_unref (regex);
2086 : :
2087 : 1 : regex = g_regex_new ("(?<DN>Mon|Fri|Sun)(?:day)?|(?<DN>Tue)(?:sday)?|(?<DN>Wed)(?:nesday)?|(?<DN>Thu)(?:rsday)?|(?<DN>Sat)(?:urday)?", G_REGEX_OPTIMIZE|G_REGEX_DUPNAMES, G_REGEX_MATCH_DEFAULT, &error);
2088 : 1 : g_assert (regex);
2089 : 1 : g_assert_no_error (error);
2090 : 1 : res = g_regex_match (regex, "Mon Tuesday Wed Saturday", 0, &match);
2091 : 1 : g_assert (res);
2092 : 1 : g_assert (g_match_info_matches (match));
2093 : 1 : str = g_match_info_fetch_named (match, "DN");
2094 : 1 : g_assert_cmpstr (str, ==, "Mon");
2095 : 1 : g_free (str);
2096 : 1 : res = g_match_info_next (match, &error);
2097 : 1 : g_assert (res);
2098 : 1 : str = g_match_info_fetch_named (match, "DN");
2099 : 1 : g_assert_cmpstr (str, ==, "Tue");
2100 : 1 : g_free (str);
2101 : 1 : res = g_match_info_next (match, &error);
2102 : 1 : g_assert (res);
2103 : 1 : str = g_match_info_fetch_named (match, "DN");
2104 : 1 : g_assert_cmpstr (str, ==, "Wed");
2105 : 1 : g_free (str);
2106 : 1 : res = g_match_info_next (match, &error);
2107 : 1 : g_assert (res);
2108 : 1 : str = g_match_info_fetch_named (match, "DN");
2109 : 1 : g_assert_cmpstr (str, ==, "Sat");
2110 : 1 : g_free (str);
2111 : 1 : g_match_info_free (match);
2112 : 1 : g_regex_unref (regex);
2113 : :
2114 : 1 : regex = g_regex_new ("^(a|b\\1)+$", G_REGEX_OPTIMIZE|G_REGEX_DUPNAMES, G_REGEX_MATCH_DEFAULT, &error);
2115 : 1 : g_assert (regex);
2116 : 1 : g_assert_no_error (error);
2117 : 1 : res = g_regex_match (regex, "aaaaaaaaaaaaaaaa", 0, &match);
2118 : 1 : g_assert (res);
2119 : 1 : g_assert (g_match_info_matches (match));
2120 : 1 : g_match_info_free (match);
2121 : 1 : res = g_regex_match (regex, "ababbaa", 0, &match);
2122 : 1 : g_assert (res);
2123 : 1 : g_assert (g_match_info_matches (match));
2124 : 1 : g_match_info_free (match);
2125 : 1 : g_regex_unref (regex);
2126 : 1 : }
2127 : :
2128 : : /* examples for conditions taken from pcrepattern(3) */
2129 : : static void
2130 : 1 : test_condition (void)
2131 : : {
2132 : : GRegex *regex;
2133 : : GError *error;
2134 : : GMatchInfo *match;
2135 : : gboolean res;
2136 : :
2137 : 1 : error = NULL;
2138 : 1 : regex = g_regex_new ("^(a+)(\\()?[^()]+(?(-1)\\))(b+)$", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
2139 : 1 : g_assert (regex);
2140 : 1 : g_assert_no_error (error);
2141 : 1 : res = g_regex_match (regex, "a(zzzzzz)b", 0, &match);
2142 : 1 : g_assert (res);
2143 : 1 : g_assert (g_match_info_matches (match));
2144 : 1 : g_match_info_free (match);
2145 : 1 : res = g_regex_match (regex, "aaazzzzzzbbb", 0, &match);
2146 : 1 : g_assert (res);
2147 : 1 : g_assert (g_match_info_matches (match));
2148 : 1 : g_match_info_free (match);
2149 : 1 : g_regex_unref (regex);
2150 : :
2151 : 1 : error = NULL;
2152 : 1 : regex = g_regex_new ("^(a+)(?<OPEN>\\()?[^()]+(?(<OPEN>)\\))(b+)$", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
2153 : 1 : g_assert (regex);
2154 : 1 : g_assert_no_error (error);
2155 : 1 : res = g_regex_match (regex, "a(zzzzzz)b", 0, &match);
2156 : 1 : g_assert (res);
2157 : 1 : g_assert (g_match_info_matches (match));
2158 : 1 : g_match_info_free (match);
2159 : 1 : res = g_regex_match (regex, "aaazzzzzzbbb", 0, &match);
2160 : 1 : g_assert (res);
2161 : 1 : g_assert (g_match_info_matches (match));
2162 : 1 : g_match_info_free (match);
2163 : 1 : g_regex_unref (regex);
2164 : :
2165 : 1 : regex = g_regex_new ("^(a+)(?(+1)\\[|\\<)?[^()]+(\\])?(b+)$", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
2166 : 1 : g_assert (regex);
2167 : 1 : g_assert_no_error (error);
2168 : 1 : res = g_regex_match (regex, "a[zzzzzz]b", 0, &match);
2169 : 1 : g_assert (res);
2170 : 1 : g_assert (g_match_info_matches (match));
2171 : 1 : g_match_info_free (match);
2172 : 1 : res = g_regex_match (regex, "aaa<zzzzzzbbb", 0, &match);
2173 : 1 : g_assert (res);
2174 : 1 : g_assert (g_match_info_matches (match));
2175 : 1 : g_match_info_free (match);
2176 : 1 : g_regex_unref (regex);
2177 : :
2178 : 1 : regex = g_regex_new ("(?(DEFINE) (?<byte> 2[0-4]\\d | 25[0-5] | 1\\d\\d | [1-9]?\\d) )"
2179 : : "\\b (?&byte) (\\.(?&byte)){3} \\b",
2180 : : G_REGEX_OPTIMIZE|G_REGEX_EXTENDED, 0, &error);
2181 : 1 : g_assert (regex);
2182 : 1 : g_assert_no_error (error);
2183 : 1 : res = g_regex_match (regex, "128.0.0.1", 0, &match);
2184 : 1 : g_assert (res);
2185 : 1 : g_assert (g_match_info_matches (match));
2186 : 1 : g_match_info_free (match);
2187 : 1 : res = g_regex_match (regex, "192.168.1.1", 0, &match);
2188 : 1 : g_assert (res);
2189 : 1 : g_assert (g_match_info_matches (match));
2190 : 1 : g_match_info_free (match);
2191 : 1 : res = g_regex_match (regex, "209.132.180.167", 0, &match);
2192 : 1 : g_assert (res);
2193 : 1 : g_assert (g_match_info_matches (match));
2194 : 1 : g_match_info_free (match);
2195 : 1 : g_regex_unref (regex);
2196 : :
2197 : 1 : regex = g_regex_new ("^(?(?=[^a-z]*[a-z])"
2198 : : "\\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} )$",
2199 : : G_REGEX_OPTIMIZE|G_REGEX_EXTENDED, 0, &error);
2200 : 1 : g_assert (regex);
2201 : 1 : g_assert_no_error (error);
2202 : 1 : res = g_regex_match (regex, "01-abc-24", 0, &match);
2203 : 1 : g_assert (res);
2204 : 1 : g_assert (g_match_info_matches (match));
2205 : 1 : g_match_info_free (match);
2206 : 1 : res = g_regex_match (regex, "01-23-45", 0, &match);
2207 : 1 : g_assert (res);
2208 : 1 : g_assert (g_match_info_matches (match));
2209 : 1 : g_match_info_free (match);
2210 : 1 : res = g_regex_match (regex, "01-uv-45", 0, &match);
2211 : 1 : g_assert (!res);
2212 : 1 : g_assert (!g_match_info_matches (match));
2213 : 1 : g_match_info_free (match);
2214 : 1 : res = g_regex_match (regex, "01-234-45", 0, &match);
2215 : 1 : g_assert (!res);
2216 : 1 : g_assert (!g_match_info_matches (match));
2217 : 1 : g_match_info_free (match);
2218 : 1 : g_regex_unref (regex);
2219 : 1 : }
2220 : :
2221 : : /* examples for recursion taken from pcrepattern(3) */
2222 : : static void
2223 : 1 : test_recursion (void)
2224 : : {
2225 : : GRegex *regex;
2226 : : GError *error;
2227 : : GMatchInfo *match;
2228 : : gboolean res;
2229 : : gint start;
2230 : :
2231 : 1 : error = NULL;
2232 : 1 : regex = g_regex_new ("\\( ( [^()]++ | (?R) )* \\)", G_REGEX_OPTIMIZE|G_REGEX_EXTENDED, G_REGEX_MATCH_DEFAULT, &error);
2233 : 1 : g_assert (regex);
2234 : 1 : g_assert_no_error (error);
2235 : 1 : res = g_regex_match (regex, "(middle)", 0, &match);
2236 : 1 : g_assert (res);
2237 : 1 : g_assert (g_match_info_matches (match));
2238 : 1 : g_match_info_free (match);
2239 : 1 : res = g_regex_match (regex, "((((((((((((((((middle))))))))))))))))", 0, &match);
2240 : 1 : g_assert (res);
2241 : 1 : g_assert (g_match_info_matches (match));
2242 : 1 : g_match_info_free (match);
2243 : 1 : res = g_regex_match (regex, "(((xxx(((", 0, &match);
2244 : 1 : g_assert (!res);
2245 : 1 : g_assert (!g_match_info_matches (match));
2246 : 1 : g_match_info_free (match);
2247 : 1 : g_regex_unref (regex);
2248 : :
2249 : 1 : regex = g_regex_new ("^( \\( ( [^()]++ | (?1) )* \\) )$", G_REGEX_OPTIMIZE|G_REGEX_EXTENDED, G_REGEX_MATCH_DEFAULT, &error);
2250 : 1 : g_assert (regex);
2251 : 1 : g_assert_no_error (error);
2252 : 1 : res = g_regex_match (regex, "((((((((((((((((middle))))))))))))))))", 0, &match);
2253 : 1 : g_assert (res);
2254 : 1 : g_assert (g_match_info_matches (match));
2255 : 1 : g_match_info_free (match);
2256 : 1 : res = g_regex_match (regex, "(((xxx((()", 0, &match);
2257 : 1 : g_assert (!res);
2258 : 1 : g_assert (!g_match_info_matches (match));
2259 : 1 : g_match_info_free (match);
2260 : 1 : g_regex_unref (regex);
2261 : :
2262 : 1 : regex = g_regex_new ("^(?<pn> \\( ( [^()]++ | (?&pn) )* \\) )$", G_REGEX_OPTIMIZE|G_REGEX_EXTENDED, G_REGEX_MATCH_DEFAULT, &error);
2263 : 1 : g_assert (regex);
2264 : 1 : g_assert_no_error (error);
2265 : 1 : g_regex_match (regex, "(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()", 0, &match);
2266 : 1 : g_assert (!res);
2267 : 1 : g_assert (!g_match_info_matches (match));
2268 : 1 : g_match_info_free (match);
2269 : 1 : g_regex_unref (regex);
2270 : :
2271 : 1 : regex = g_regex_new ("< (?: (?(R) \\d++ | [^<>]*+) | (?R)) * >", G_REGEX_OPTIMIZE|G_REGEX_EXTENDED, G_REGEX_MATCH_DEFAULT, &error);
2272 : 1 : g_assert (regex);
2273 : 1 : g_assert_no_error (error);
2274 : 1 : res = g_regex_match (regex, "<ab<01<23<4>>>>", 0, &match);
2275 : 1 : g_assert (res);
2276 : 1 : g_assert (g_match_info_matches (match));
2277 : 1 : res = g_match_info_fetch_pos (match, 0, &start, NULL);
2278 : 1 : g_assert (res);
2279 : 1 : g_assert_cmpint (start, ==, 0);
2280 : 1 : g_match_info_free (match);
2281 : 1 : res = g_regex_match (regex, "<ab<01<xx<x>>>>", 0, &match);
2282 : 1 : g_assert (res);
2283 : 1 : g_assert (g_match_info_matches (match));
2284 : 1 : res = g_match_info_fetch_pos (match, 0, &start, NULL);
2285 : 1 : g_assert (res);
2286 : 1 : g_assert_cmpint (start, >, 0);
2287 : 1 : g_match_info_free (match);
2288 : 1 : g_regex_unref (regex);
2289 : :
2290 : 1 : regex = g_regex_new ("^((.)(?1)\\2|.)$", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
2291 : 1 : g_assert (regex);
2292 : 1 : g_assert_no_error (error);
2293 : 1 : res = g_regex_match (regex, "abcdcba", 0, &match);
2294 : 1 : g_assert (res);
2295 : 1 : g_assert (g_match_info_matches (match));
2296 : 1 : g_match_info_free (match);
2297 : 1 : res = g_regex_match (regex, "abcddcba", 0, &match);
2298 : 1 : g_assert (!res);
2299 : 1 : g_assert (!g_match_info_matches (match));
2300 : 1 : g_match_info_free (match);
2301 : 1 : g_regex_unref (regex);
2302 : :
2303 : 1 : regex = g_regex_new ("^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
2304 : 1 : g_assert (regex);
2305 : 1 : g_assert_no_error (error);
2306 : 1 : res = g_regex_match (regex, "abcdcba", 0, &match);
2307 : 1 : g_assert (res);
2308 : 1 : g_assert (g_match_info_matches (match));
2309 : 1 : g_match_info_free (match);
2310 : 1 : res = g_regex_match (regex, "abcddcba", 0, &match);
2311 : 1 : g_assert (res);
2312 : 1 : g_assert (g_match_info_matches (match));
2313 : 1 : g_match_info_free (match);
2314 : 1 : g_regex_unref (regex);
2315 : :
2316 : 1 : regex = g_regex_new ("^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$", G_REGEX_OPTIMIZE|G_REGEX_CASELESS, G_REGEX_MATCH_DEFAULT, &error);
2317 : 1 : g_assert (regex);
2318 : 1 : g_assert_no_error (error);
2319 : 1 : res = g_regex_match (regex, "abcdcba", 0, &match);
2320 : 1 : g_assert (res);
2321 : 1 : g_assert (g_match_info_matches (match));
2322 : 1 : g_match_info_free (match);
2323 : 1 : res = g_regex_match (regex, "A man, a plan, a canal: Panama!", 0, &match);
2324 : 1 : g_assert (res);
2325 : 1 : g_assert (g_match_info_matches (match));
2326 : 1 : g_match_info_free (match);
2327 : 1 : res = g_regex_match (regex, "Oozy rat in a sanitary zoo", 0, &match);
2328 : 1 : g_assert (res);
2329 : 1 : g_assert (g_match_info_matches (match));
2330 : 1 : g_match_info_free (match);
2331 : 1 : g_regex_unref (regex);
2332 : 1 : }
2333 : :
2334 : : static void
2335 : 1 : test_multiline (void)
2336 : : {
2337 : : GRegex *regex;
2338 : : GMatchInfo *info;
2339 : : gint count;
2340 : :
2341 : 1 : g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=640489");
2342 : :
2343 : 1 : regex = g_regex_new ("^a$", G_REGEX_MULTILINE|G_REGEX_DOTALL, G_REGEX_MATCH_DEFAULT, NULL);
2344 : :
2345 : 1 : count = 0;
2346 : 1 : g_regex_match (regex, "a\nb\na", 0, &info);
2347 [ + + ]: 3 : while (g_match_info_matches (info))
2348 : : {
2349 : 2 : count++;
2350 : 2 : g_match_info_next (info, NULL);
2351 : : }
2352 : 1 : g_match_info_free (info);
2353 : 1 : g_regex_unref (regex);
2354 : :
2355 : 1 : g_assert_cmpint (count, ==, 2);
2356 : 1 : }
2357 : :
2358 : : static void
2359 : 1 : test_explicit_crlf (void)
2360 : : {
2361 : : GRegex *regex;
2362 : :
2363 : 1 : regex = g_regex_new ("[\r\n]a", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL);
2364 : 1 : g_assert_cmpint (g_regex_get_has_cr_or_lf (regex), ==, TRUE);
2365 : 1 : g_regex_unref (regex);
2366 : 1 : }
2367 : :
2368 : : static void
2369 : 1 : test_max_lookbehind (void)
2370 : : {
2371 : : GRegex *regex;
2372 : :
2373 : 1 : regex = g_regex_new ("abc", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL);
2374 : 1 : g_assert_cmpint (g_regex_get_max_lookbehind (regex), ==, 0);
2375 : 1 : g_regex_unref (regex);
2376 : :
2377 : 1 : regex = g_regex_new ("\\babc", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL);
2378 : 1 : g_assert_cmpint (g_regex_get_max_lookbehind (regex), ==, 1);
2379 : 1 : g_regex_unref (regex);
2380 : :
2381 : 1 : regex = g_regex_new ("(?<=123)abc", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL);
2382 : 1 : g_assert_cmpint (g_regex_get_max_lookbehind (regex), ==, 3);
2383 : 1 : g_regex_unref (regex);
2384 : 1 : }
2385 : :
2386 : : static gboolean
2387 : 1 : pcre2_ge (guint64 major, guint64 minor)
2388 : : {
2389 : : gchar version[32];
2390 : : const gchar *ptr;
2391 : : guint64 pcre2_major, pcre2_minor;
2392 : :
2393 : : /* e.g. 10.36 2020-12-04 */
2394 : 1 : pcre2_config (PCRE2_CONFIG_VERSION, version);
2395 : :
2396 : 1 : pcre2_major = g_ascii_strtoull (version, (gchar **) &ptr, 10);
2397 : : /* ptr points to ".MINOR (release date)" */
2398 : 1 : g_assert (ptr[0] == '.');
2399 : 1 : pcre2_minor = g_ascii_strtoull (ptr + 1, NULL, 10);
2400 : :
2401 [ + - + - : 1 : return (pcre2_major > major) || (pcre2_major == major && pcre2_minor >= minor);
+ - ]
2402 : : }
2403 : :
2404 : : static void
2405 : 1 : test_compile_errors (void)
2406 : : {
2407 : : GRegex *regex;
2408 : 1 : GError *error = NULL;
2409 : :
2410 : 1 : regex = g_regex_new ("\\o{999}", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error);
2411 : 1 : g_assert_null (regex);
2412 : 1 : g_assert_error (error, G_REGEX_ERROR, G_REGEX_ERROR_COMPILE);
2413 : 1 : g_clear_error (&error);
2414 : 1 : }
2415 : :
2416 : : static void
2417 : 1 : test_jit_unsupported_matching_options (void)
2418 : : {
2419 : : GRegex *regex;
2420 : : GMatchInfo *info;
2421 : : gchar *substring;
2422 : :
2423 : 1 : regex = g_regex_new ("(\\w+)#(\\w+)", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, NULL);
2424 : :
2425 : 1 : g_assert_true (g_regex_match (regex, "aa#bb cc#dd", G_REGEX_MATCH_DEFAULT, &info));
2426 : 1 : g_assert_cmpint (g_match_info_get_match_count (info), ==, 3);
2427 : 1 : substring = g_match_info_fetch (info, 1);
2428 : 1 : g_assert_cmpstr (substring, ==, "aa");
2429 : 1 : g_clear_pointer (&substring, g_free);
2430 : 1 : substring = g_match_info_fetch (info, 2);
2431 : 1 : g_assert_cmpstr (substring, ==, "bb");
2432 : 1 : g_clear_pointer (&substring, g_free);
2433 : 1 : g_assert_true (g_match_info_next (info, NULL));
2434 : 1 : g_assert_cmpint (g_match_info_get_match_count (info), ==, 3);
2435 : 1 : substring = g_match_info_fetch (info, 1);
2436 : 1 : g_assert_cmpstr (substring, ==, "cc");
2437 : 1 : g_clear_pointer (&substring, g_free);
2438 : 1 : substring = g_match_info_fetch (info, 2);
2439 : 1 : g_assert_cmpstr (substring, ==, "dd");
2440 : 1 : g_clear_pointer (&substring, g_free);
2441 : 1 : g_assert_false (g_match_info_next (info, NULL));
2442 : 1 : g_match_info_free (info);
2443 : :
2444 : 1 : g_assert_true (g_regex_match (regex, "aa#bb cc#dd", G_REGEX_MATCH_ANCHORED, &info));
2445 : 1 : g_assert_cmpint (g_match_info_get_match_count (info), ==, 3);
2446 : 1 : substring = g_match_info_fetch (info, 1);
2447 : 1 : g_assert_cmpstr (substring, ==, "aa");
2448 : 1 : g_clear_pointer (&substring, g_free);
2449 : 1 : substring = g_match_info_fetch (info, 2);
2450 : 1 : g_assert_cmpstr (substring, ==, "bb");
2451 : 1 : g_clear_pointer (&substring, g_free);
2452 : 1 : g_assert_false (g_match_info_next (info, NULL));
2453 : 1 : g_match_info_free (info);
2454 : :
2455 : 1 : g_assert_true (g_regex_match (regex, "aa#bb cc#dd", G_REGEX_MATCH_DEFAULT, &info));
2456 : 1 : g_assert_cmpint (g_match_info_get_match_count (info), ==, 3);
2457 : 1 : substring = g_match_info_fetch (info, 1);
2458 : 1 : g_assert_cmpstr (substring, ==, "aa");
2459 : 1 : g_clear_pointer (&substring, g_free);
2460 : 1 : substring = g_match_info_fetch (info, 2);
2461 : 1 : g_assert_cmpstr (substring, ==, "bb");
2462 : 1 : g_clear_pointer (&substring, g_free);
2463 : 1 : g_assert_true (g_match_info_next (info, NULL));
2464 : 1 : g_assert_cmpint (g_match_info_get_match_count (info), ==, 3);
2465 : 1 : substring = g_match_info_fetch (info, 1);
2466 : 1 : g_assert_cmpstr (substring, ==, "cc");
2467 : 1 : g_clear_pointer (&substring, g_free);
2468 : 1 : substring = g_match_info_fetch (info, 2);
2469 : 1 : g_assert_cmpstr (substring, ==, "dd");
2470 : 1 : g_clear_pointer (&substring, g_free);
2471 : 1 : g_assert_false (g_match_info_next (info, NULL));
2472 : 1 : g_match_info_free (info);
2473 : :
2474 : 1 : g_regex_unref (regex);
2475 : 1 : }
2476 : :
2477 : : static void
2478 : 1 : test_unmatched_named_subpattern (void)
2479 : : {
2480 : 1 : GRegex *regex = NULL;
2481 : 1 : GMatchInfo *match_info = NULL;
2482 : 1 : const char *string = "Test";
2483 : :
2484 : 1 : g_test_summary ("Test that unmatched subpatterns can still be queried");
2485 : 1 : g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2881");
2486 : :
2487 : 1 : regex = g_regex_new ("((?<Key>[^\\s\"'\\=]+)|\"(?<Key>[^\"]*)\"|'(?<Key>[^']*)')"
2488 : : "(?:\\=((?<Value>[^\\s\"']+)|\"(?<Value>[^\"]*)\"|'(?<Value>[^']*)'))?",
2489 : : G_REGEX_DUPNAMES, 0, NULL);
2490 : :
2491 : 1 : g_assert_true (g_regex_match (regex, string, 0, &match_info));
2492 : :
2493 [ + + ]: 2 : while (g_match_info_matches (match_info))
2494 : : {
2495 : 1 : char *key = g_match_info_fetch_named (match_info, "Key");
2496 : 1 : char *value = g_match_info_fetch_named (match_info, "Value");
2497 : :
2498 : 1 : g_assert_cmpstr (key, ==, "Test");
2499 : 1 : g_assert_cmpstr (value, ==, "");
2500 : :
2501 : 1 : g_free (key);
2502 : 1 : g_free (value);
2503 : 1 : g_match_info_next (match_info, NULL);
2504 : : }
2505 : :
2506 : 1 : g_match_info_unref (match_info);
2507 : 1 : g_regex_unref (regex);
2508 : 1 : }
2509 : :
2510 : : static void
2511 : 1 : test_compiled_regex_after_jit_failure (void)
2512 : : {
2513 : 1 : GRegex *regex = NULL;
2514 : : char string[LARGE_TEST_STRING_LEN];
2515 : :
2516 : 1 : g_test_summary ("Test that failed OPTIMIZE regex doesn't cause issues on subsequent matches");
2517 : 1 : g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2824");
2518 : :
2519 : 1 : regex = g_regex_new ("^(?:[ \t\n]|[^[:cntrl:]])*$", G_REGEX_OPTIMIZE, 0, NULL);
2520 : :
2521 : : /* Generate large enough string to cause JIT failure on this regex. */
2522 : 1 : memset (string, '*', LARGE_TEST_STRING_LEN);
2523 : 1 : string[LARGE_TEST_STRING_LEN - 1] = '\0';
2524 : :
2525 : 1 : g_assert_true (g_regex_match (regex, string, 0, NULL));
2526 : : /* Second assert here is the key - does the first JIT overflow mess up our state? */
2527 : 1 : g_assert_true (g_regex_match (regex, string, 0, NULL));
2528 : :
2529 : 1 : g_regex_unref (regex);
2530 : 1 : }
2531 : :
2532 : : int
2533 : 1 : main (int argc, char *argv[])
2534 : : {
2535 : 1 : setlocale (LC_ALL, "");
2536 : :
2537 : 1 : g_test_init (&argc, &argv, NULL);
2538 : :
2539 : 1 : g_test_add_func ("/regex/properties", test_properties);
2540 : 1 : g_test_add_func ("/regex/class", test_class);
2541 : 1 : g_test_add_func ("/regex/lookahead", test_lookahead);
2542 : 1 : g_test_add_func ("/regex/lookbehind", test_lookbehind);
2543 : 1 : g_test_add_func ("/regex/subpattern", test_subpattern);
2544 : 1 : g_test_add_func ("/regex/condition", test_condition);
2545 : 1 : g_test_add_func ("/regex/recursion", test_recursion);
2546 : 1 : g_test_add_func ("/regex/multiline", test_multiline);
2547 : 1 : g_test_add_func ("/regex/explicit-crlf", test_explicit_crlf);
2548 : 1 : g_test_add_func ("/regex/max-lookbehind", test_max_lookbehind);
2549 : 1 : g_test_add_func ("/regex/compile-errors", test_compile_errors);
2550 : 1 : g_test_add_func ("/regex/jit-unsupported-matching", test_jit_unsupported_matching_options);
2551 : 1 : g_test_add_func ("/regex/unmatched-named-subpattern", test_unmatched_named_subpattern);
2552 : 1 : g_test_add_func ("/regex/compiled-regex-after-jit-failure", test_compiled_regex_after_jit_failure);
2553 : :
2554 : : /* TEST_NEW(pattern, compile_opts, match_opts) */
2555 : 1 : TEST_NEW("[A-Z]+", G_REGEX_CASELESS | G_REGEX_EXTENDED | G_REGEX_OPTIMIZE, G_REGEX_MATCH_NOTBOL | G_REGEX_MATCH_PARTIAL);
2556 : 1 : TEST_NEW("", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT);
2557 : 1 : TEST_NEW(".*", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT);
2558 : 1 : TEST_NEW(".*", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT);
2559 : 1 : TEST_NEW(".*", G_REGEX_MULTILINE, G_REGEX_MATCH_DEFAULT);
2560 : 1 : TEST_NEW(".*", G_REGEX_DOTALL, G_REGEX_MATCH_DEFAULT);
2561 : 1 : TEST_NEW(".*", G_REGEX_DOTALL, G_REGEX_MATCH_NOTBOL);
2562 : 1 : TEST_NEW("(123\\d*)[a-zA-Z]+(?P<hello>.*)", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT);
2563 : 1 : TEST_NEW("(123\\d*)[a-zA-Z]+(?P<hello>.*)", G_REGEX_CASELESS, G_REGEX_MATCH_DEFAULT);
2564 : 1 : TEST_NEW("(123\\d*)[a-zA-Z]+(?P<hello>.*)", G_REGEX_CASELESS | G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT);
2565 : 1 : TEST_NEW("(?P<A>x)|(?P<A>y)", G_REGEX_DUPNAMES, G_REGEX_MATCH_DEFAULT);
2566 : 1 : TEST_NEW("(?P<A>x)|(?P<A>y)", G_REGEX_DUPNAMES | G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT);
2567 : : /* This gives "internal error: code overflow" with pcre 6.0 */
2568 : 1 : TEST_NEW("(?i)(?-i)", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT);
2569 : 1 : TEST_NEW ("(?i)a", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT);
2570 : 1 : TEST_NEW ("(?m)a", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT);
2571 : 1 : TEST_NEW ("(?s)a", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT);
2572 : 1 : TEST_NEW ("(?x)a", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT);
2573 : 1 : TEST_NEW ("(?J)a", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT);
2574 : 1 : TEST_NEW ("(?U)[a-z]+", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT);
2575 : :
2576 : : /* TEST_NEW_CHECK_FLAGS(pattern, compile_opts, match_ops, real_compile_opts, real_match_opts) */
2577 : 1 : TEST_NEW_CHECK_FLAGS ("a", G_REGEX_OPTIMIZE, 0, G_REGEX_OPTIMIZE, 0);
2578 : 1 : TEST_NEW_CHECK_FLAGS ("a", G_REGEX_OPTIMIZE, G_REGEX_MATCH_NOTEMPTY,
2579 : : G_REGEX_OPTIMIZE, G_REGEX_MATCH_NOTEMPTY);
2580 : 1 : TEST_NEW_CHECK_FLAGS ("a", 0, G_REGEX_MATCH_NEWLINE_ANYCRLF | G_REGEX_MATCH_BSR_ANYCRLF,
2581 : : G_REGEX_NEWLINE_ANYCRLF | G_REGEX_BSR_ANYCRLF,
2582 : : G_REGEX_MATCH_NEWLINE_ANYCRLF | G_REGEX_MATCH_BSR_ANYCRLF);
2583 : 1 : TEST_NEW_CHECK_FLAGS ("a", G_REGEX_RAW, 0, G_REGEX_RAW, 0);
2584 : 1 : TEST_NEW_CHECK_FLAGS ("(?J)a", 0, 0, G_REGEX_DUPNAMES, 0);
2585 : 1 : TEST_NEW_CHECK_FLAGS ("^.*", 0, 0, G_REGEX_ANCHORED, 0);
2586 : 1 : TEST_NEW_CHECK_FLAGS ("(*UTF8)a", 0, 0, 0 /* this is the default in GRegex */, 0);
2587 : 1 : TEST_NEW_CHECK_FLAGS ("(*UCP)a", 0, 0, 0 /* this always on in GRegex */, 0);
2588 : 1 : TEST_NEW_CHECK_FLAGS ("(*CR)a", 0, 0, G_REGEX_NEWLINE_CR, 0);
2589 : 1 : TEST_NEW_CHECK_FLAGS ("(*LF)a", 0, 0, G_REGEX_NEWLINE_LF, 0);
2590 : 1 : TEST_NEW_CHECK_FLAGS ("(*CRLF)a", 0, 0, G_REGEX_NEWLINE_CRLF, 0);
2591 : 1 : TEST_NEW_CHECK_FLAGS ("(*ANY)a", 0, 0, 0 /* this is the default in GRegex */, 0);
2592 : 1 : TEST_NEW_CHECK_FLAGS ("(*ANYCRLF)a", 0, 0, G_REGEX_NEWLINE_ANYCRLF, 0);
2593 : 1 : TEST_NEW_CHECK_FLAGS ("(*BSR_ANYCRLF)a", 0, 0, G_REGEX_BSR_ANYCRLF, 0);
2594 : 1 : TEST_NEW_CHECK_FLAGS ("(*BSR_UNICODE)a", 0, 0, 0 /* this is the default in GRegex */, 0);
2595 : 1 : TEST_NEW_CHECK_FLAGS ("(*NO_START_OPT)a", 0, 0, 0 /* not exposed in GRegex */, 0);
2596 : : /* Make sure we ignore deprecated G_REGEX_JAVASCRIPT_COMPAT */
2597 : : G_GNUC_BEGIN_IGNORE_DEPRECATIONS
2598 : 1 : TEST_NEW_CHECK_FLAGS ("a", G_REGEX_JAVASCRIPT_COMPAT, 0, 0, 0);
2599 : : G_GNUC_END_IGNORE_DEPRECATIONS
2600 : :
2601 : : /* TEST_NEW_FAIL(pattern, compile_opts, expected_error) */
2602 : 1 : TEST_NEW_FAIL("(", 0, G_REGEX_ERROR_UNMATCHED_PARENTHESIS);
2603 : 1 : TEST_NEW_FAIL(")", 0, G_REGEX_ERROR_UNMATCHED_PARENTHESIS);
2604 : 1 : TEST_NEW_FAIL("[", 0, G_REGEX_ERROR_UNTERMINATED_CHARACTER_CLASS);
2605 : 1 : TEST_NEW_FAIL("*", 0, G_REGEX_ERROR_NOTHING_TO_REPEAT);
2606 : 1 : TEST_NEW_FAIL("?", 0, G_REGEX_ERROR_NOTHING_TO_REPEAT);
2607 : 1 : TEST_NEW_FAIL("(?P<A>x)|(?P<A>y)", 0, G_REGEX_ERROR_DUPLICATE_SUBPATTERN_NAME);
2608 : :
2609 : : /* Check all GRegexError codes */
2610 : 1 : TEST_NEW_FAIL ("a\\", 0, G_REGEX_ERROR_STRAY_BACKSLASH);
2611 : 1 : TEST_NEW_FAIL ("a\\c", 0, G_REGEX_ERROR_MISSING_CONTROL_CHAR);
2612 : 1 : TEST_NEW_FAIL ("a\\l", 0, G_REGEX_ERROR_UNRECOGNIZED_ESCAPE);
2613 : 1 : TEST_NEW_FAIL ("a{4,2}", 0, G_REGEX_ERROR_QUANTIFIERS_OUT_OF_ORDER);
2614 : 1 : TEST_NEW_FAIL ("a{999999,}", 0, G_REGEX_ERROR_QUANTIFIER_TOO_BIG);
2615 : 1 : TEST_NEW_FAIL ("[a-z", 0, G_REGEX_ERROR_UNTERMINATED_CHARACTER_CLASS);
2616 : 1 : TEST_NEW_FAIL ("[\\B]", 0, G_REGEX_ERROR_INVALID_ESCAPE_IN_CHARACTER_CLASS);
2617 : 1 : TEST_NEW_FAIL ("[z-a]", 0, G_REGEX_ERROR_RANGE_OUT_OF_ORDER);
2618 : 1 : TEST_NEW_FAIL ("^[[:alnum:]-_.]+$", 0, G_REGEX_ERROR_COMPILE);
2619 : 1 : TEST_NEW_FAIL ("{2,4}", 0, G_REGEX_ERROR_NOTHING_TO_REPEAT);
2620 : 1 : TEST_NEW_FAIL ("a(?u)", 0, G_REGEX_ERROR_UNRECOGNIZED_CHARACTER);
2621 : 1 : TEST_NEW_FAIL ("a(?<$foo)bar", 0, G_REGEX_ERROR_MISSING_SUBPATTERN_NAME);
2622 : 1 : TEST_NEW_FAIL ("a[:alpha:]b", 0, G_REGEX_ERROR_POSIX_NAMED_CLASS_OUTSIDE_CLASS);
2623 : 1 : TEST_NEW_FAIL ("a(b", 0, G_REGEX_ERROR_UNMATCHED_PARENTHESIS);
2624 : 1 : TEST_NEW_FAIL ("a)b", 0, G_REGEX_ERROR_UNMATCHED_PARENTHESIS);
2625 : 1 : TEST_NEW_FAIL ("a(?R", 0, G_REGEX_ERROR_UNMATCHED_PARENTHESIS);
2626 : 1 : TEST_NEW_FAIL ("a(?-54", 0, G_REGEX_ERROR_INEXISTENT_SUBPATTERN_REFERENCE);
2627 : 1 : TEST_NEW_FAIL ("(ab\\2)", 0, G_REGEX_ERROR_INEXISTENT_SUBPATTERN_REFERENCE);
2628 : 1 : TEST_NEW_FAIL ("a(?#abc", 0, G_REGEX_ERROR_UNTERMINATED_COMMENT);
2629 : 1 : TEST_NEW_FAIL ("(?<=a+)b", 0, G_REGEX_ERROR_VARIABLE_LENGTH_LOOKBEHIND);
2630 : 1 : TEST_NEW_FAIL ("(?(1?)a|b)", 0, G_REGEX_ERROR_MALFORMED_CONDITION);
2631 : 1 : TEST_NEW_FAIL ("(a)(?(1)a|b|c)", 0, G_REGEX_ERROR_TOO_MANY_CONDITIONAL_BRANCHES);
2632 : 1 : TEST_NEW_FAIL ("(?(?i))", 0, G_REGEX_ERROR_ASSERTION_EXPECTED);
2633 : 1 : TEST_NEW_FAIL ("a[[:fubar:]]b", 0, G_REGEX_ERROR_UNKNOWN_POSIX_CLASS_NAME);
2634 : 1 : TEST_NEW_FAIL ("[[.ch.]]", 0, G_REGEX_ERROR_POSIX_COLLATING_ELEMENTS_NOT_SUPPORTED);
2635 : 1 : TEST_NEW_FAIL ("\\x{110000}", 0, G_REGEX_ERROR_HEX_CODE_TOO_LARGE);
2636 : 1 : TEST_NEW_FAIL ("^(?(0)f|b)oo", 0, G_REGEX_ERROR_INEXISTENT_SUBPATTERN_REFERENCE);
2637 : 1 : TEST_NEW_FAIL ("(?<=\\C)X", 0, G_REGEX_ERROR_SINGLE_BYTE_MATCH_IN_LOOKBEHIND);
2638 : 1 : TEST_NEW ("(?!\\w)(?R)", 0, 0);
2639 : 1 : TEST_NEW_FAIL ("(?(?<ab))", 0, G_REGEX_ERROR_ASSERTION_EXPECTED);
2640 : 1 : TEST_NEW_FAIL ("(?P<sub>foo)\\g<sub", 0, G_REGEX_ERROR_MISSING_SUBPATTERN_NAME_TERMINATOR);
2641 : 1 : TEST_NEW_FAIL ("(?P<x>eks)(?P<x>eccs)", 0, G_REGEX_ERROR_DUPLICATE_SUBPATTERN_NAME);
2642 : 1 : TEST_NEW_FAIL ("\\666", G_REGEX_RAW, G_REGEX_ERROR_INVALID_OCTAL_VALUE);
2643 : 1 : TEST_NEW_FAIL ("^(?(DEFINE) abc | xyz ) ", 0, G_REGEX_ERROR_TOO_MANY_BRANCHES_IN_DEFINE);
2644 : 1 : TEST_NEW_FAIL ("a", G_REGEX_NEWLINE_CRLF | G_REGEX_NEWLINE_ANYCRLF, G_REGEX_ERROR_INCONSISTENT_NEWLINE_OPTIONS);
2645 : 1 : TEST_NEW_FAIL ("^(a)\\g{3", 0, G_REGEX_ERROR_MISSING_BACK_REFERENCE);
2646 : 1 : TEST_NEW_FAIL ("^(a)\\g{0}", 0, G_REGEX_ERROR_INEXISTENT_SUBPATTERN_REFERENCE);
2647 : 1 : TEST_NEW ("abc(*FAIL:123)xyz", 0, 0);
2648 : 1 : TEST_NEW_FAIL ("a(*FOOBAR)b", 0, G_REGEX_ERROR_UNKNOWN_BACKTRACKING_CONTROL_VERB);
2649 [ + - ]: 1 : if (pcre2_ge (10, 37))
2650 : : {
2651 : 1 : TEST_NEW ("(?i:A{1,}\\6666666666)", 0, 0);
2652 : : }
2653 : 1 : TEST_NEW_FAIL ("(?<a>)(?&)", 0, G_REGEX_ERROR_MISSING_SUBPATTERN_NAME);
2654 : 1 : TEST_NEW_FAIL ("(?+-a)", 0, G_REGEX_ERROR_INVALID_RELATIVE_REFERENCE);
2655 : 1 : TEST_NEW_FAIL ("(?|(?<a>A)|(?<b>B))", 0, G_REGEX_ERROR_EXTRA_SUBPATTERN_NAME);
2656 : 1 : TEST_NEW_FAIL ("a(*MARK)b", 0, G_REGEX_ERROR_BACKTRACKING_CONTROL_VERB_ARGUMENT_REQUIRED);
2657 : 1 : TEST_NEW_FAIL ("^\\c€", 0, G_REGEX_ERROR_INVALID_CONTROL_CHAR);
2658 : 1 : TEST_NEW_FAIL ("\\k", 0, G_REGEX_ERROR_MISSING_NAME);
2659 : 1 : TEST_NEW_FAIL ("a[\\NB]c", 0, G_REGEX_ERROR_NOT_SUPPORTED_IN_CLASS);
2660 : 1 : TEST_NEW_FAIL ("(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEFG)XX", 0, G_REGEX_ERROR_NAME_TOO_LONG);
2661 : : /* See https://gitlab.gnome.org/GNOME/gtksourceview/-/issues/278 */
2662 : 1 : TEST_NEW_FAIL ("(?i-x)((?:(?i-x)[^\\x00\\t\\n\\f\\r \"'/<=>\\x{007F}-\\x{009F}" \
2663 : : "\\x{FDD0}-\\x{FDEF}\\x{FFFE}\\x{FFFF}\\x{1FFFE}\\x{1FFFF}" \
2664 : : "\\x{2FFFE}\\x{2FFFF}\\x{3FFFE}\\x{3FFFF}\\x{4FFFE}\\x{4FFFF}" \
2665 : : "\\x{5FFFE}\\x{5FFFF}\\x{6FFFE}\\x{6FFFF}\\x{7FFFE}\\x{7FFFF}" \
2666 : : "\\x{8FFFE}\\x{8FFFF}\\x{9FFFE}\\x{9FFFF}\\x{AFFFE}\\x{AFFFF}" \
2667 : : "\\x{BFFFE}\\x{BFFFF}\\x{CFFFE}\\x{CFFFF}\\x{DFFFE}\\x{DFFFF}" \
2668 : : "\\x{EFFFE}\\x{EFFFF}\\x{FFFFE}\\x{FFFFF}\\x{10FFFE}\\x{10FFFF}]+)" \
2669 : : "\\s*=\\s*)(\\\")",
2670 : : G_REGEX_RAW, G_REGEX_ERROR_HEX_CODE_TOO_LARGE);
2671 : :
2672 : : /* These errors can't really be tested easily:
2673 : : * G_REGEX_ERROR_EXPRESSION_TOO_LARGE
2674 : : * G_REGEX_ERROR_MEMORY_ERROR
2675 : : * G_REGEX_ERROR_SUBPATTERN_NAME_TOO_LONG
2676 : : * G_REGEX_ERROR_TOO_MANY_SUBPATTERNS
2677 : : * G_REGEX_ERROR_TOO_MANY_FORWARD_REFERENCES
2678 : : *
2679 : : * These errors are obsolete and never raised by PCRE:
2680 : : * G_REGEX_ERROR_DEFINE_REPETION
2681 : : */
2682 : :
2683 : : /* TEST_MATCH_SIMPLE(pattern, string, compile_opts, match_opts, expected) */
2684 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("a", "", 0, 0, FALSE);
2685 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("a", "a", 0, 0, TRUE);
2686 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("a", "ba", 0, 0, TRUE);
2687 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("^a", "ba", 0, 0, FALSE);
2688 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("a", "ba", G_REGEX_ANCHORED, 0, FALSE);
2689 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("a", "ba", 0, G_REGEX_MATCH_ANCHORED, FALSE);
2690 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("a", "ab", G_REGEX_ANCHORED, 0, TRUE);
2691 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("a", "ab", 0, G_REGEX_MATCH_ANCHORED, TRUE);
2692 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("a", "a", G_REGEX_CASELESS, 0, TRUE);
2693 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("a", "A", G_REGEX_CASELESS, 0, TRUE);
2694 [ + - + - ]: 1 : TEST_MATCH_SIMPLE("\\C\\C", "ab", G_REGEX_OPTIMIZE | G_REGEX_RAW, 0, TRUE);
2695 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("^[[:alnum:]\\-_.]+$", "admin-foo", 0, 0, TRUE);
2696 : : /* These are needed to test extended properties. */
2697 [ - + - + ]: 1 : TEST_MATCH_SIMPLE(AGRAVE, AGRAVE, G_REGEX_CASELESS, 0, TRUE);
2698 [ - + - + ]: 1 : TEST_MATCH_SIMPLE(AGRAVE, AGRAVE_UPPER, G_REGEX_CASELESS, 0, TRUE);
2699 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{L}", "a", 0, 0, TRUE);
2700 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{L}", "1", 0, 0, FALSE);
2701 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{L}", AGRAVE, 0, 0, TRUE);
2702 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{L}", AGRAVE_UPPER, 0, 0, TRUE);
2703 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{L}", SHEEN, 0, 0, TRUE);
2704 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{L}", ETH30, 0, 0, FALSE);
2705 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Ll}", "a", 0, 0, TRUE);
2706 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Ll}", AGRAVE, 0, 0, TRUE);
2707 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Ll}", AGRAVE_UPPER, 0, 0, FALSE);
2708 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Ll}", ETH30, 0, 0, FALSE);
2709 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Sc}", AGRAVE, 0, 0, FALSE);
2710 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Sc}", EURO, 0, 0, TRUE);
2711 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Sc}", ETH30, 0, 0, FALSE);
2712 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{N}", "a", 0, 0, FALSE);
2713 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{N}", "1", 0, 0, TRUE);
2714 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{N}", AGRAVE, 0, 0, FALSE);
2715 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{N}", AGRAVE_UPPER, 0, 0, FALSE);
2716 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{N}", SHEEN, 0, 0, FALSE);
2717 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{N}", ETH30, 0, 0, TRUE);
2718 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Nd}", "a", 0, 0, FALSE);
2719 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Nd}", "1", 0, 0, TRUE);
2720 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Nd}", AGRAVE, 0, 0, FALSE);
2721 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Nd}", AGRAVE_UPPER, 0, 0, FALSE);
2722 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Nd}", SHEEN, 0, 0, FALSE);
2723 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Nd}", ETH30, 0, 0, FALSE);
2724 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Common}", SHEEN, 0, 0, FALSE);
2725 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Common}", "a", 0, 0, FALSE);
2726 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Common}", AGRAVE, 0, 0, FALSE);
2727 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Common}", AGRAVE_UPPER, 0, 0, FALSE);
2728 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Common}", ETH30, 0, 0, FALSE);
2729 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Common}", "%", 0, 0, TRUE);
2730 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Common}", "1", 0, 0, TRUE);
2731 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Arabic}", SHEEN, 0, 0, TRUE);
2732 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Arabic}", "a", 0, 0, FALSE);
2733 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Arabic}", AGRAVE, 0, 0, FALSE);
2734 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Arabic}", AGRAVE_UPPER, 0, 0, FALSE);
2735 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Arabic}", ETH30, 0, 0, FALSE);
2736 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Arabic}", "%", 0, 0, FALSE);
2737 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Arabic}", "1", 0, 0, FALSE);
2738 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Latin}", SHEEN, 0, 0, FALSE);
2739 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Latin}", "a", 0, 0, TRUE);
2740 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Latin}", AGRAVE, 0, 0, TRUE);
2741 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Latin}", AGRAVE_UPPER, 0, 0, TRUE);
2742 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Latin}", ETH30, 0, 0, FALSE);
2743 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Latin}", "%", 0, 0, FALSE);
2744 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Latin}", "1", 0, 0, FALSE);
2745 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Ethiopic}", SHEEN, 0, 0, FALSE);
2746 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Ethiopic}", "a", 0, 0, FALSE);
2747 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Ethiopic}", AGRAVE, 0, 0, FALSE);
2748 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Ethiopic}", AGRAVE_UPPER, 0, 0, FALSE);
2749 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Ethiopic}", ETH30, 0, 0, TRUE);
2750 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Ethiopic}", "%", 0, 0, FALSE);
2751 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{Ethiopic}", "1", 0, 0, FALSE);
2752 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{L}(?<=\\p{Arabic})", SHEEN, 0, 0, TRUE);
2753 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\p{L}(?<=\\p{Latin})", SHEEN, 0, 0, FALSE);
2754 : : /* Invalid patterns. */
2755 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("\\", "a", 0, 0, FALSE);
2756 [ - + - + ]: 1 : TEST_MATCH_SIMPLE("[", "", 0, 0, FALSE);
2757 : :
2758 : : /* Test that JIT compiler has enough stack */
2759 : : char test_string[TEST_STRING_LEN];
2760 : 1 : memset (test_string, '*', TEST_STRING_LEN);
2761 : 1 : test_string[TEST_STRING_LEN - 1] = '\0';
2762 [ - + - + ]: 1 : TEST_MATCH_SIMPLE ("^(?:[ \t\n]|[^[:cntrl:]])*$", test_string, 0, 0, TRUE);
2763 : :
2764 : : /* Test that gregex falls back to unoptimized matching when reaching the JIT
2765 : : * compiler stack limit */
2766 : : char large_test_string[LARGE_TEST_STRING_LEN];
2767 : 1 : memset (large_test_string, '*', LARGE_TEST_STRING_LEN);
2768 : 1 : large_test_string[LARGE_TEST_STRING_LEN - 1] = '\0';
2769 [ - + - + ]: 1 : TEST_MATCH_SIMPLE ("^(?:[ \t\n]|[^[:cntrl:]])*$", large_test_string, 0, 0, TRUE);
2770 : :
2771 : : /* TEST_MATCH(pattern, compile_opts, match_opts, string,
2772 : : * string_len, start_position, match_opts2, expected) */
2773 [ - + - + ]: 1 : TEST_MATCH("a", 0, 0, "a", -1, 0, 0, TRUE);
2774 [ - + - + ]: 1 : TEST_MATCH("a", 0, 0, "A", -1, 0, 0, FALSE);
2775 [ - + - + ]: 1 : TEST_MATCH("a", G_REGEX_CASELESS, 0, "A", -1, 0, 0, TRUE);
2776 [ - + - + ]: 1 : TEST_MATCH("a", 0, 0, "ab", -1, 1, 0, FALSE);
2777 [ - + - + ]: 1 : TEST_MATCH("a", 0, 0, "ba", 1, 0, 0, FALSE);
2778 [ - + - + ]: 1 : TEST_MATCH("a", 0, 0, "bab", -1, 0, 0, TRUE);
2779 [ - + - + ]: 1 : TEST_MATCH("a", 0, 0, "b", -1, 0, 0, FALSE);
2780 [ - + - + ]: 1 : TEST_MATCH("a", 0, G_REGEX_MATCH_ANCHORED, "a", -1, 0, 0, TRUE);
2781 [ - + - + ]: 1 : TEST_MATCH("a", 0, G_REGEX_MATCH_ANCHORED, "ab", -1, 1, 0, FALSE);
2782 [ - + - + ]: 1 : TEST_MATCH("a", 0, G_REGEX_MATCH_ANCHORED, "ba", 1, 0, 0, FALSE);
2783 [ - + - + ]: 1 : TEST_MATCH("a", 0, G_REGEX_MATCH_ANCHORED, "bab", -1, 0, 0, FALSE);
2784 [ - + - + ]: 1 : TEST_MATCH("a", 0, G_REGEX_MATCH_ANCHORED, "b", -1, 0, 0, FALSE);
2785 [ - + - + ]: 1 : TEST_MATCH("a", 0, 0, "a", -1, 0, G_REGEX_MATCH_ANCHORED, TRUE);
2786 [ - + - + ]: 1 : TEST_MATCH("a", 0, 0, "ab", -1, 1, G_REGEX_MATCH_ANCHORED, FALSE);
2787 [ - + - + ]: 1 : TEST_MATCH("a", 0, 0, "ba", 1, 0, G_REGEX_MATCH_ANCHORED, FALSE);
2788 [ - + - + ]: 1 : TEST_MATCH("a", 0, 0, "bab", -1, 0, G_REGEX_MATCH_ANCHORED, FALSE);
2789 [ - + - + ]: 1 : TEST_MATCH("a", 0, 0, "b", -1, 0, G_REGEX_MATCH_ANCHORED, FALSE);
2790 [ - + - + ]: 1 : TEST_MATCH("a|b", 0, 0, "a", -1, 0, 0, TRUE);
2791 [ - + - + ]: 1 : TEST_MATCH("\\d", 0, 0, EURO, -1, 0, 0, FALSE);
2792 [ - + - + ]: 1 : TEST_MATCH("^.$", 0, 0, EURO, -1, 0, 0, TRUE);
2793 [ - + - + ]: 1 : TEST_MATCH("^.{3}$", 0, 0, EURO, -1, 0, 0, FALSE);
2794 [ - + - + ]: 1 : TEST_MATCH("^.$", G_REGEX_RAW, 0, EURO, -1, 0, 0, FALSE);
2795 [ - + - + ]: 1 : TEST_MATCH("^.{3}$", G_REGEX_RAW, 0, EURO, -1, 0, 0, TRUE);
2796 [ - + - + ]: 1 : TEST_MATCH(AGRAVE, G_REGEX_CASELESS, 0, AGRAVE_UPPER, -1, 0, 0, TRUE);
2797 : :
2798 : : /* New lines handling. */
2799 [ - + - + ]: 1 : TEST_MATCH("^a\\Rb$", 0, 0, "a\r\nb", -1, 0, 0, TRUE);
2800 [ - + - + ]: 1 : TEST_MATCH("^a\\Rb$", 0, 0, "a\nb", -1, 0, 0, TRUE);
2801 [ - + - + ]: 1 : TEST_MATCH("^a\\Rb$", 0, 0, "a\rb", -1, 0, 0, TRUE);
2802 [ - + - + ]: 1 : TEST_MATCH("^a\\Rb$", 0, 0, "a\n\rb", -1, 0, 0, FALSE);
2803 [ - + - + ]: 1 : TEST_MATCH("^a\\R\\Rb$", 0, 0, "a\n\rb", -1, 0, 0, TRUE);
2804 [ - + - + ]: 1 : TEST_MATCH("^a\\nb$", 0, 0, "a\r\nb", -1, 0, 0, FALSE);
2805 [ - + - + ]: 1 : TEST_MATCH("^a\\r\\nb$", 0, 0, "a\r\nb", -1, 0, 0, TRUE);
2806 : :
2807 [ - + - + ]: 1 : TEST_MATCH("^b$", 0, 0, "a\nb\nc", -1, 0, 0, FALSE);
2808 [ - + - + ]: 1 : TEST_MATCH("^b$", G_REGEX_MULTILINE, 0, "a\nb\nc", -1, 0, 0, TRUE);
2809 [ - + - + ]: 1 : TEST_MATCH("^b$", G_REGEX_MULTILINE, 0, "a\r\nb\r\nc", -1, 0, 0, TRUE);
2810 [ - + - + ]: 1 : TEST_MATCH("^b$", G_REGEX_MULTILINE, 0, "a\rb\rc", -1, 0, 0, TRUE);
2811 [ - + - + ]: 1 : TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, 0, "a\nb\nc", -1, 0, 0, FALSE);
2812 [ - + - + ]: 1 : TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_LF, 0, "a\nb\nc", -1, 0, 0, TRUE);
2813 [ - + - + ]: 1 : TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CRLF, 0, "a\nb\nc", -1, 0, 0, FALSE);
2814 [ - + - + ]: 1 : TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, 0, "a\r\nb\r\nc", -1, 0, 0, FALSE);
2815 [ - + - + ]: 1 : TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_LF, 0, "a\r\nb\r\nc", -1, 0, 0, FALSE);
2816 [ - + - + ]: 1 : TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CRLF, 0, "a\r\nb\r\nc", -1, 0, 0, TRUE);
2817 [ - + - + ]: 1 : TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, 0, "a\rb\rc", -1, 0, 0, TRUE);
2818 [ - + - + ]: 1 : TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_LF, 0, "a\rb\rc", -1, 0, 0, FALSE);
2819 [ - + - + ]: 1 : TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CRLF, 0, "a\rb\rc", -1, 0, 0, FALSE);
2820 [ - + - + ]: 1 : TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_ANYCRLF, 0, "a\r\nb\nc", -1, 0, 0, TRUE);
2821 [ - + - + ]: 1 : TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_ANYCRLF, 0, "a\r\nb\rc", -1, 0, 0, TRUE);
2822 [ - + - + ]: 1 : TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_CR, "a\nb\nc", -1, 0, 0, FALSE);
2823 [ - + - + ]: 1 : TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_LF, "a\nb\nc", -1, 0, 0, TRUE);
2824 [ - + - + ]: 1 : TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_CRLF, "a\nb\nc", -1, 0, 0, FALSE);
2825 [ - + - + ]: 1 : TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_CR, "a\r\nb\r\nc", -1, 0, 0, FALSE);
2826 [ - + - + ]: 1 : TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_LF, "a\r\nb\r\nc", -1, 0, 0, FALSE);
2827 [ - + - + ]: 1 : TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_CRLF, "a\r\nb\r\nc", -1, 0, 0, TRUE);
2828 [ - + - + ]: 1 : TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_CR, "a\rb\rc", -1, 0, 0, TRUE);
2829 [ - + - + ]: 1 : TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_LF, "a\rb\rc", -1, 0, 0, FALSE);
2830 [ - + - + ]: 1 : TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_CRLF, "a\rb\rc", -1, 0, 0, FALSE);
2831 [ - + - + ]: 1 : TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_ANYCRLF, "a\r\nb\rc", -1, 0, 0, TRUE);
2832 [ - + - + ]: 1 : TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_ANYCRLF, "a\r\nb\nc", -1, 0, 0, TRUE);
2833 : :
2834 [ - + - + ]: 1 : TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, G_REGEX_MATCH_NEWLINE_ANY, "a\nb\nc", -1, 0, 0, TRUE);
2835 [ - + - + ]: 1 : TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, G_REGEX_MATCH_NEWLINE_ANY, "a\rb\rc", -1, 0, 0, TRUE);
2836 [ - + - + ]: 1 : TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, G_REGEX_MATCH_NEWLINE_ANY, "a\r\nb\r\nc", -1, 0, 0, TRUE);
2837 [ - + - + ]: 1 : TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, G_REGEX_MATCH_NEWLINE_LF, "a\nb\nc", -1, 0, 0, TRUE);
2838 [ - + - + ]: 1 : TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, G_REGEX_MATCH_NEWLINE_LF, "a\rb\rc", -1, 0, 0, FALSE);
2839 [ - + - + ]: 1 : TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, G_REGEX_MATCH_NEWLINE_CRLF, "a\r\nb\r\nc", -1, 0, 0, TRUE);
2840 [ - + - + ]: 1 : TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, G_REGEX_MATCH_NEWLINE_CRLF, "a\rb\rc", -1, 0, 0, FALSE);
2841 : :
2842 : : /* See https://gitlab.gnome.org/GNOME/glib/-/issues/2729#note_1544130 */
2843 [ - + - + ]: 1 : TEST_MATCH("^a$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_ANY, "a", -1, 0, 0, TRUE);
2844 [ - + - + ]: 1 : TEST_MATCH("^a$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_LF, "a", -1, 0, 0, TRUE);
2845 [ - + - + ]: 1 : TEST_MATCH("^a$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_CR, "a", -1, 0, 0, TRUE);
2846 [ - + - + ]: 1 : TEST_MATCH("^a$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_CRLF, "a", -1, 0, 0, TRUE);
2847 [ - + - + ]: 1 : TEST_MATCH("^a$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_ANYCRLF, "a", -1, 0, 0, TRUE);
2848 : :
2849 [ - + - + ]: 1 : TEST_MATCH("a#\nb", G_REGEX_EXTENDED, 0, "a", -1, 0, 0, FALSE);
2850 [ - + - + ]: 1 : TEST_MATCH("a#\r\nb", G_REGEX_EXTENDED, 0, "a", -1, 0, 0, FALSE);
2851 [ - + - + ]: 1 : TEST_MATCH("a#\rb", G_REGEX_EXTENDED, 0, "a", -1, 0, 0, FALSE);
2852 : : /* Due to PCRE2 only supporting newline settings passed to pcre2_compile (and
2853 : : * not to pcre2_match also), we have to compile the pattern with the
2854 : : * effective (combined from compile and match options) newline setting.
2855 : : * However, this setting also affects how newlines are interpreted *inside*
2856 : : * the pattern. With G_REGEX_EXTENDED, this changes where the comment
2857 : : * (started with `#`) ends.
2858 : : */
2859 : : /* On PCRE1, this test expected no match; on PCRE2 it matches because of the above. */
2860 [ - + - + ]: 1 : TEST_MATCH("a#\nb", G_REGEX_EXTENDED, G_REGEX_MATCH_NEWLINE_CR, "a", -1, 0, 0, TRUE /*FALSE*/);
2861 [ - + - + ]: 1 : TEST_MATCH("a#\nb", G_REGEX_EXTENDED | G_REGEX_NEWLINE_CR, 0, "a", -1, 0, 0, TRUE);
2862 : :
2863 [ - + - + ]: 1 : TEST_MATCH("line\nbreak", G_REGEX_MULTILINE, 0, "this is a line\nbreak", -1, 0, 0, TRUE);
2864 [ - + - + ]: 1 : TEST_MATCH("line\nbreak", G_REGEX_MULTILINE | G_REGEX_FIRSTLINE, 0, "first line\na line\nbreak", -1, 0, 0, FALSE);
2865 : :
2866 : : /* This failed with PCRE 7.2 (gnome bug #455640) */
2867 [ - + - + ]: 1 : TEST_MATCH(".*$", 0, 0, "\xe1\xbb\x85", -1, 0, 0, TRUE);
2868 : :
2869 : : /* Test that othercasing in our pcre/glib integration is bug-for-bug compatible
2870 : : * with pcre's internal tables. Bug #678273 */
2871 [ - + - + ]: 1 : TEST_MATCH("[Ç„]", G_REGEX_CASELESS, 0, "Ç„", -1, 0, 0, TRUE);
2872 [ - + - + ]: 1 : TEST_MATCH("[DŽ]", G_REGEX_CASELESS, 0, "dž", -1, 0, 0, TRUE);
2873 [ - + - + ]: 1 : TEST_MATCH("[Ç„]", G_REGEX_CASELESS, 0, "Ç…", -1, 0, 0, TRUE);
2874 : :
2875 : : /* see https://gitlab.gnome.org/GNOME/glib/-/issues/2700 */
2876 [ - + - + ]: 1 : TEST_MATCH("(\n.+)+", G_REGEX_DEFAULT, 0, "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n", -1, 0, 0, TRUE);
2877 [ - + - + ]: 1 : TEST_MATCH("\n([\\-\\.a-zA-Z]+[\\-\\.0-9]*) +connected ([^(\n ]*)[^\n]*((\n +[0-9]+x[0-9]+[^\n]+)+)", G_REGEX_DEFAULT, 0, "Screen 0: minimum 1 x 1, current 3840 x 1080, maximum 8192 x 8192\nVirtual1 connected primary 1920x1080+0+0 (normal left inverted right x axis y axis) 0mm x 0mm\n 1920x1080 60.00*+ 59.96 \n 3840x2400 59.97 \n 3840x2160 59.97 \n 2880x1800 59.95 \n 2560x1600 59.99 \n 2560x1440 59.95 \n 1920x1440 60.00 \n 1856x1392 60.00 \n 1792x1344 60.00 \n 1920x1200 59.88 \n 1600x1200 60.00 \n 1680x1050 59.95 \n 1400x1050 59.98 \n 1280x1024 60.02 \n 1440x900 59.89 \n 1280x960 60.00 \n 1360x768 60.02 \n 1280x800 59.81 \n 1152x864 75.00 \n 1280x768 59.87 \n 1280x720 59.86 \n 1024x768 60.00 \n 800x600 60.32 \n 640x480 59.94 \nVirtual2 connected 1920x1080+1920+0 (normal left inverted right x axis y axis) 0mm x 0mm\n 1920x1080 60.00*+ 59.96 \n 3840x2400 59.97 \n 3840x2160 59.97 \n 2880x1800 59.95 \n 2560x1600 59.99 \n 2560x1440 59.95 \n 1920x1440 60.00 \n 1856x1392 60.00 \n 1792x1344 60.00 \n 1920x1200 59.88 \n 1600x1200 60.00 \n 1680x1050 59.95 \n 1400x1050 59.98 \n 1280x1024 60.02 \n 1440x900 59.89 \n 1280x960 60.00 \n 1360x768 60.02 \n 1280x800 59.81 \n 1152x864 75.00 \n 1280x768 59.87 \n 1280x720 59.86 \n 1024x768 60.00 \n 800x600 60.32 \n 640x480 59.94 \nVirtual3 disconnected (normal left inverted right x axis y axis)\nVirtual4 disconnected (normal left inverted right x axis y axis)\nVirtual5 disconnected (normal left inverted right x axis y axis)\nVirtual6 disconnected (normal left inverted right x axis y axis)\nVirtual7 disconnected (normal left inverted right x axis y axis)\nVirtual8 disconnected (normal left inverted right x axis y axis)\n", -1, 0, 0, TRUE);
2878 : :
2879 : : /* TEST_MATCH_NEXT#(pattern, string, string_len, start_position, ...) */
2880 : 1 : TEST_MATCH_NEXT0("a", "x", -1, 0);
2881 : 1 : TEST_MATCH_NEXT0("a", "ax", -1, 1);
2882 : 1 : TEST_MATCH_NEXT0("a", "xa", 1, 0);
2883 : 1 : TEST_MATCH_NEXT0("a", "axa", 1, 2);
2884 : 1 : TEST_MATCH_NEXT1("", "", -1, 0, "", 0, 0);
2885 : 1 : TEST_MATCH_NEXT1("a", "a", -1, 0, "a", 0, 1);
2886 : 1 : TEST_MATCH_NEXT1("a", "xax", -1, 0, "a", 1, 2);
2887 : 1 : TEST_MATCH_NEXT1(EURO, ENG EURO, -1, 0, EURO, 2, 5);
2888 : 1 : TEST_MATCH_NEXT1("a*", "", -1, 0, "", 0, 0);
2889 : 1 : TEST_MATCH_NEXT2("", "a", -1, 0, "", 0, 0, "", 1, 1);
2890 : 1 : TEST_MATCH_NEXT2("a*", "aa", -1, 0, "aa", 0, 2, "", 2, 2);
2891 : 1 : TEST_MATCH_NEXT2(EURO "*", EURO EURO, -1, 0, EURO EURO, 0, 6, "", 6, 6);
2892 : 1 : TEST_MATCH_NEXT2("a", "axa", -1, 0, "a", 0, 1, "a", 2, 3);
2893 : 1 : TEST_MATCH_NEXT2("a+", "aaxa", -1, 0, "aa", 0, 2, "a", 3, 4);
2894 : 1 : TEST_MATCH_NEXT2("a", "aa", -1, 0, "a", 0, 1, "a", 1, 2);
2895 : 1 : TEST_MATCH_NEXT2("a", "ababa", -1, 2, "a", 2, 3, "a", 4, 5);
2896 : 1 : TEST_MATCH_NEXT2(EURO "+", EURO "-" EURO, -1, 0, EURO, 0, 3, EURO, 4, 7);
2897 : 1 : TEST_MATCH_NEXT3("", "ab", -1, 0, "", 0, 0, "", 1, 1, "", 2, 2);
2898 : 1 : TEST_MATCH_NEXT3("", AGRAVE "b", -1, 0, "", 0, 0, "", 2, 2, "", 3, 3);
2899 : 1 : TEST_MATCH_NEXT3("a", "aaxa", -1, 0, "a", 0, 1, "a", 1, 2, "a", 3, 4);
2900 : 1 : TEST_MATCH_NEXT3("a", "aa" OGRAVE "a", -1, 0, "a", 0, 1, "a", 1, 2, "a", 4, 5);
2901 : 1 : TEST_MATCH_NEXT3("a*", "aax", -1, 0, "aa", 0, 2, "", 2, 2, "", 3, 3);
2902 : 1 : TEST_MATCH_NEXT3("(?=[A-Z0-9])", "RegExTest", -1, 0, "", 0, 0, "", 3, 3, "", 5, 5);
2903 : 1 : TEST_MATCH_NEXT4("a*", "aaxa", -1, 0, "aa", 0, 2, "", 2, 2, "a", 3, 4, "", 4, 4);
2904 : :
2905 : : /* TEST_MATCH_COUNT(pattern, string, start_position, match_opts, expected_count) */
2906 : 1 : TEST_MATCH_COUNT("a", "", 0, 0, 0);
2907 : 1 : TEST_MATCH_COUNT("a", "a", 0, 0, 1);
2908 : 1 : TEST_MATCH_COUNT("a", "a", 1, 0, 0);
2909 : 1 : TEST_MATCH_COUNT("(.)", "a", 0, 0, 2);
2910 : 1 : TEST_MATCH_COUNT("(.)", EURO, 0, 0, 2);
2911 : 1 : TEST_MATCH_COUNT("(?:.)", "a", 0, 0, 1);
2912 : 1 : TEST_MATCH_COUNT("(?P<A>.)", "a", 0, 0, 2);
2913 : 1 : TEST_MATCH_COUNT("a$", "a", 0, G_REGEX_MATCH_NOTEOL, 0);
2914 : 1 : TEST_MATCH_COUNT("(a)?(b)", "b", 0, 0, 3);
2915 : 1 : TEST_MATCH_COUNT("(a)?(b)", "ab", 0, 0, 3);
2916 : :
2917 : : /* TEST_PARTIAL(pattern, string, expected), no JIT */
2918 [ - + - + ]: 1 : TEST_PARTIAL("^ab", "a", G_REGEX_DEFAULT, TRUE);
2919 [ - + - + ]: 1 : TEST_PARTIAL("^ab", "xa", G_REGEX_DEFAULT, FALSE);
2920 [ - + - + ]: 1 : TEST_PARTIAL("ab", "xa", G_REGEX_DEFAULT, TRUE);
2921 [ - + - + ]: 1 : TEST_PARTIAL("ab", "ab", G_REGEX_DEFAULT, FALSE); /* normal match. */
2922 [ - + - + ]: 1 : TEST_PARTIAL("a+b", "aa", G_REGEX_DEFAULT, TRUE);
2923 [ - + - + ]: 1 : TEST_PARTIAL("(a)+b", "aa", G_REGEX_DEFAULT, TRUE);
2924 [ - + - + ]: 1 : TEST_PARTIAL("a?b", "a", G_REGEX_DEFAULT, TRUE);
2925 : :
2926 : : /* TEST_PARTIAL(pattern, string, expected) with JIT */
2927 [ + - + - ]: 1 : TEST_PARTIAL("^ab", "a", G_REGEX_OPTIMIZE, TRUE);
2928 [ + - + - ]: 1 : TEST_PARTIAL("^ab", "xa", G_REGEX_OPTIMIZE, FALSE);
2929 [ + - + - ]: 1 : TEST_PARTIAL("ab", "xa", G_REGEX_OPTIMIZE, TRUE);
2930 [ + - + - ]: 1 : TEST_PARTIAL("ab", "ab", G_REGEX_OPTIMIZE, FALSE); /* normal match. */
2931 [ + - + - ]: 1 : TEST_PARTIAL("a+b", "aa", G_REGEX_OPTIMIZE, TRUE);
2932 [ + - + - ]: 1 : TEST_PARTIAL("(a)+b", "aa", G_REGEX_OPTIMIZE, TRUE);
2933 [ + - + - ]: 1 : TEST_PARTIAL("a?b", "a", G_REGEX_OPTIMIZE, TRUE);
2934 : :
2935 : : /* Test soft vs. hard partial matching, no JIT */
2936 [ - + - + ]: 1 : TEST_PARTIAL_FULL("cat(fish)?", "cat", G_REGEX_DEFAULT, G_REGEX_MATCH_PARTIAL_SOFT, FALSE);
2937 [ - + - + ]: 1 : TEST_PARTIAL_FULL("cat(fish)?", "cat", G_REGEX_DEFAULT, G_REGEX_MATCH_PARTIAL_HARD, TRUE);
2938 [ - + - + ]: 1 : TEST_PARTIAL_FULL("ab+", "ab", G_REGEX_DEFAULT, G_REGEX_MATCH_PARTIAL_SOFT, FALSE);
2939 [ - + - + ]: 1 : TEST_PARTIAL_FULL("ab+", "ab", G_REGEX_DEFAULT, G_REGEX_MATCH_PARTIAL_HARD, TRUE);
2940 : :
2941 : : /* Test soft vs. hard partial matching with JIT */
2942 [ + - + - ]: 1 : TEST_PARTIAL_FULL("cat(fish)?", "cat", G_REGEX_OPTIMIZE, G_REGEX_MATCH_PARTIAL_SOFT, FALSE);
2943 [ + - + - ]: 1 : TEST_PARTIAL_FULL("cat(fish)?", "cat", G_REGEX_OPTIMIZE, G_REGEX_MATCH_PARTIAL_HARD, TRUE);
2944 [ + - + - ]: 1 : TEST_PARTIAL_FULL("ab+", "ab", G_REGEX_OPTIMIZE, G_REGEX_MATCH_PARTIAL_SOFT, FALSE);
2945 [ + - + - ]: 1 : TEST_PARTIAL_FULL("ab+", "ab", G_REGEX_OPTIMIZE, G_REGEX_MATCH_PARTIAL_HARD, TRUE);
2946 : :
2947 : : /* TEST_SUB_PATTERN(pattern, string, start_position, sub_n, expected_sub,
2948 : : * expected_start, expected_end) */
2949 : 1 : TEST_SUB_PATTERN("a", "a", 0, 0, "a", 0, 1);
2950 : 1 : TEST_SUB_PATTERN("a(.)", "ab", 0, 1, "b", 1, 2);
2951 : 1 : TEST_SUB_PATTERN("a(.)", "a" EURO, 0, 1, EURO, 1, 4);
2952 : 1 : TEST_SUB_PATTERN("(?:.*)(a)(.)", "xxa" ENG, 0, 2, ENG, 3, 5);
2953 : 1 : TEST_SUB_PATTERN("(" HSTROKE ")", "a" HSTROKE ENG, 0, 1, HSTROKE, 1, 3);
2954 : 1 : TEST_SUB_PATTERN("a", "a", 0, 1, NULL, UNTOUCHED, UNTOUCHED);
2955 : 1 : TEST_SUB_PATTERN("a", "a", 0, 1, NULL, UNTOUCHED, UNTOUCHED);
2956 : 1 : TEST_SUB_PATTERN("(a)?(b)", "b", 0, 0, "b", 0, 1);
2957 : 1 : TEST_SUB_PATTERN("(a)?(b)", "b", 0, 1, "", -1, -1);
2958 : 1 : TEST_SUB_PATTERN("(a)?(b)", "b", 0, 2, "b", 0, 1);
2959 : 1 : TEST_SUB_PATTERN("(a)?b", "b", 0, 0, "b", 0, 1);
2960 : 1 : TEST_SUB_PATTERN("(a)?b", "b", 0, 1, "", -1, -1);
2961 : 1 : TEST_SUB_PATTERN("(a)?b", "b", 0, 2, NULL, UNTOUCHED, UNTOUCHED);
2962 : :
2963 : : /* TEST_NAMED_SUB_PATTERN(pattern, string, start_position, sub_name,
2964 : : * expected_sub, expected_start, expected_end) */
2965 : 1 : TEST_NAMED_SUB_PATTERN("a(?P<A>.)(?P<B>.)?", "ab", 0, "A", "b", 1, 2);
2966 : 1 : TEST_NAMED_SUB_PATTERN("a(?P<A>.)(?P<B>.)?", "aab", 1, "A", "b", 2, 3);
2967 : 1 : TEST_NAMED_SUB_PATTERN("a(?P<A>.)(?P<B>.)?", EURO "ab", 0, "A", "b", 4, 5);
2968 : 1 : TEST_NAMED_SUB_PATTERN("a(?P<A>.)(?P<B>.)?", EURO "ab", 0, "B", "", -1, -1);
2969 : 1 : TEST_NAMED_SUB_PATTERN("a(?P<A>.)(?P<B>.)?", EURO "ab", 0, "C", NULL, UNTOUCHED, UNTOUCHED);
2970 : 1 : TEST_NAMED_SUB_PATTERN("a(?P<A>.)(?P<B>.)?", "a" EGRAVE "x", 0, "A", EGRAVE, 1, 3);
2971 : 1 : TEST_NAMED_SUB_PATTERN("a(?P<A>.)(?P<B>.)?", "a" EGRAVE "x", 0, "B", "x", 3, 4);
2972 : 1 : TEST_NAMED_SUB_PATTERN("(?P<A>a)?(?P<B>b)", "b", 0, "A", "", -1, -1);
2973 : 1 : TEST_NAMED_SUB_PATTERN("(?P<A>a)?(?P<B>b)", "b", 0, "B", "b", 0, 1);
2974 : :
2975 : : /* TEST_NAMED_SUB_PATTERN_DUPNAMES(pattern, string, start_position, sub_name,
2976 : : * expected_sub, expected_start, expected_end) */
2977 : 1 : TEST_NAMED_SUB_PATTERN_DUPNAMES("(?P<N>a)|(?P<N>b)", "ab", 0, "N", "a", 0, 1);
2978 : 1 : TEST_NAMED_SUB_PATTERN_DUPNAMES("(?P<N>aa)|(?P<N>a)", "aa", 0, "N", "aa", 0, 2);
2979 : 1 : TEST_NAMED_SUB_PATTERN_DUPNAMES("(?P<N>aa)(?P<N>a)", "aaa", 0, "N", "aa", 0, 2);
2980 : 1 : TEST_NAMED_SUB_PATTERN_DUPNAMES("(?P<N>x)|(?P<N>a)", "a", 0, "N", "a", 0, 1);
2981 : 1 : TEST_NAMED_SUB_PATTERN_DUPNAMES("(?P<N>x)y|(?P<N>a)b", "ab", 0, "N", "a", 0, 1);
2982 : :
2983 : : /* DUPNAMES option inside the pattern */
2984 : 1 : TEST_NAMED_SUB_PATTERN("(?J)(?P<N>a)|(?P<N>b)", "ab", 0, "N", "a", 0, 1);
2985 : 1 : TEST_NAMED_SUB_PATTERN("(?J)(?P<N>aa)|(?P<N>a)", "aa", 0, "N", "aa", 0, 2);
2986 : 1 : TEST_NAMED_SUB_PATTERN("(?J)(?P<N>aa)(?P<N>a)", "aaa", 0, "N", "aa", 0, 2);
2987 : 1 : TEST_NAMED_SUB_PATTERN("(?J)(?P<N>x)|(?P<N>a)", "a", 0, "N", "a", 0, 1);
2988 : 1 : TEST_NAMED_SUB_PATTERN("(?J)(?P<N>x)y|(?P<N>a)b", "ab", 0, "N", "a", 0, 1);
2989 : :
2990 : : /* TEST_FETCH_ALL#(pattern, string, ...) */
2991 : 1 : TEST_FETCH_ALL0("a", "");
2992 : 1 : TEST_FETCH_ALL0("a", "b");
2993 : 1 : TEST_FETCH_ALL1("a", "a", "a");
2994 : 1 : TEST_FETCH_ALL1("a+", "aa", "aa");
2995 : 1 : TEST_FETCH_ALL1("(?:a)", "a", "a");
2996 : 1 : TEST_FETCH_ALL2("(a)", "a", "a", "a");
2997 : 1 : TEST_FETCH_ALL2("a(.)", "ab", "ab", "b");
2998 : 1 : TEST_FETCH_ALL2("a(.)", "a" HSTROKE, "a" HSTROKE, HSTROKE);
2999 : 1 : TEST_FETCH_ALL3("(?:.*)(a)(.)", "xyazk", "xyaz", "a", "z");
3000 : 1 : TEST_FETCH_ALL3("(?P<A>.)(a)", "xa", "xa", "x", "a");
3001 : 1 : TEST_FETCH_ALL3("(?P<A>.)(a)", ENG "a", ENG "a", ENG, "a");
3002 : 1 : TEST_FETCH_ALL3("(a)?(b)", "b", "b", "", "b");
3003 : 1 : TEST_FETCH_ALL3("(a)?(b)", "ab", "ab", "a", "b");
3004 : :
3005 : : /* TEST_SPLIT_SIMPLE#(pattern, string, ...) */
3006 : 1 : TEST_SPLIT_SIMPLE0("", "");
3007 : 1 : TEST_SPLIT_SIMPLE0("a", "");
3008 : 1 : TEST_SPLIT_SIMPLE1(",", "a", "a");
3009 : 1 : TEST_SPLIT_SIMPLE1("(,)\\s*", "a", "a");
3010 : 1 : TEST_SPLIT_SIMPLE2(",", "a,b", "a", "b");
3011 : 1 : TEST_SPLIT_SIMPLE3(",", "a,b,c", "a", "b", "c");
3012 : 1 : TEST_SPLIT_SIMPLE3(",\\s*", "a,b,c", "a", "b", "c");
3013 : 1 : TEST_SPLIT_SIMPLE3(",\\s*", "a, b, c", "a", "b", "c");
3014 : 1 : TEST_SPLIT_SIMPLE3("(,)\\s*", "a,b", "a", ",", "b");
3015 : 1 : TEST_SPLIT_SIMPLE3("(,)\\s*", "a, b", "a", ",", "b");
3016 : 1 : TEST_SPLIT_SIMPLE2("\\s", "ab c", "ab", "c");
3017 : 1 : TEST_SPLIT_SIMPLE3("\\s*", "ab c", "a", "b", "c");
3018 : : /* Not matched sub-strings. */
3019 : 1 : TEST_SPLIT_SIMPLE2("a|(b)", "xay", "x", "y");
3020 : 1 : TEST_SPLIT_SIMPLE3("a|(b)", "xby", "x", "b", "y");
3021 : : /* Empty matches. */
3022 : 1 : TEST_SPLIT_SIMPLE3("", "abc", "a", "b", "c");
3023 : 1 : TEST_SPLIT_SIMPLE3(" *", "ab c", "a", "b", "c");
3024 : : /* Invalid patterns. */
3025 : 1 : TEST_SPLIT_SIMPLE0("\\", "");
3026 : 1 : TEST_SPLIT_SIMPLE0("[", "");
3027 : :
3028 : : /* TEST_SPLIT#(pattern, string, start_position, max_tokens, ...) */
3029 : 1 : TEST_SPLIT0("", "", 0, 0);
3030 : 1 : TEST_SPLIT0("a", "", 0, 0);
3031 : 1 : TEST_SPLIT0("a", "", 0, 1);
3032 : 1 : TEST_SPLIT0("a", "", 0, 2);
3033 : 1 : TEST_SPLIT0("a", "a", 1, 0);
3034 : 1 : TEST_SPLIT1(",", "a", 0, 0, "a");
3035 : 1 : TEST_SPLIT1(",", "a,b", 0, 1, "a,b");
3036 : 1 : TEST_SPLIT1("(,)\\s*", "a", 0, 0, "a");
3037 : 1 : TEST_SPLIT1(",", "a,b", 2, 0, "b");
3038 : 1 : TEST_SPLIT2(",", "a,b", 0, 0, "a", "b");
3039 : 1 : TEST_SPLIT2(",", "a,b,c", 0, 2, "a", "b,c");
3040 : 1 : TEST_SPLIT2(",", "a,b", 1, 0, "", "b");
3041 : 1 : TEST_SPLIT2(",", "a,", 0, 0, "a", "");
3042 : 1 : TEST_SPLIT3(",", "a,b,c", 0, 0, "a", "b", "c");
3043 : 1 : TEST_SPLIT3(",\\s*", "a,b,c", 0, 0, "a", "b", "c");
3044 : 1 : TEST_SPLIT3(",\\s*", "a, b, c", 0, 0, "a", "b", "c");
3045 : 1 : TEST_SPLIT3("(,)\\s*", "a,b", 0, 0, "a", ",", "b");
3046 : 1 : TEST_SPLIT3("(,)\\s*", "a, b", 0, 0, "a", ",", "b");
3047 : : /* Not matched sub-strings. */
3048 : 1 : TEST_SPLIT2("a|(b)", "xay", 0, 0, "x", "y");
3049 : 1 : TEST_SPLIT3("a|(b)", "xby", 0, -1, "x", "b", "y");
3050 : : /* Empty matches. */
3051 : 1 : TEST_SPLIT2(" *", "ab c", 1, 0, "b", "c");
3052 : 1 : TEST_SPLIT3("", "abc", 0, 0, "a", "b", "c");
3053 : 1 : TEST_SPLIT3(" *", "ab c", 0, 0, "a", "b", "c");
3054 : 1 : TEST_SPLIT1(" *", "ab c", 0, 1, "ab c");
3055 : 1 : TEST_SPLIT2(" *", "ab c", 0, 2, "a", "b c");
3056 : 1 : TEST_SPLIT3(" *", "ab c", 0, 3, "a", "b", "c");
3057 : 1 : TEST_SPLIT3(" *", "ab c", 0, 4, "a", "b", "c");
3058 : :
3059 : : /* TEST_CHECK_REPLACEMENT(string_to_expand, expected, expected_refs) */
3060 : 1 : TEST_CHECK_REPLACEMENT("", TRUE, FALSE);
3061 : 1 : TEST_CHECK_REPLACEMENT("a", TRUE, FALSE);
3062 : 1 : TEST_CHECK_REPLACEMENT("\\t\\n\\v\\r\\f\\a\\b\\\\\\x{61}", TRUE, FALSE);
3063 : 1 : TEST_CHECK_REPLACEMENT("\\0", TRUE, TRUE);
3064 : 1 : TEST_CHECK_REPLACEMENT("\\n\\2", TRUE, TRUE);
3065 : 1 : TEST_CHECK_REPLACEMENT("\\g<foo>", TRUE, TRUE);
3066 : : /* Invalid strings */
3067 : 1 : TEST_CHECK_REPLACEMENT("\\Q", FALSE, FALSE);
3068 : 1 : TEST_CHECK_REPLACEMENT("x\\Ay", FALSE, FALSE);
3069 : :
3070 : : /* TEST_EXPAND(pattern, string, string_to_expand, raw, expected) */
3071 : 1 : TEST_EXPAND("a", "a", "", FALSE, "");
3072 : 1 : TEST_EXPAND("a", "a", "\\0", FALSE, "a");
3073 : 1 : TEST_EXPAND("a", "a", "\\1", FALSE, "");
3074 : 1 : TEST_EXPAND("(a)", "ab", "\\1", FALSE, "a");
3075 : 1 : TEST_EXPAND("(a)", "a", "\\1", FALSE, "a");
3076 : 1 : TEST_EXPAND("(a)", "a", "\\g<1>", FALSE, "a");
3077 : 1 : TEST_EXPAND("a", "a", "\\0130", FALSE, "X");
3078 : 1 : TEST_EXPAND("a", "a", "\\\\\\0", FALSE, "\\a");
3079 : 1 : TEST_EXPAND("a(?P<G>.)c", "xabcy", "X\\g<G>X", FALSE, "XbX");
3080 : 1 : TEST_EXPAND(".", EURO, "\\0", FALSE, EURO);
3081 : 1 : TEST_EXPAND("(.)", EURO, "\\1", FALSE, EURO);
3082 : 1 : TEST_EXPAND("(?P<G>.)", EURO, "\\g<G>", FALSE, EURO);
3083 : 1 : TEST_EXPAND(".", "a", EURO, FALSE, EURO);
3084 : 1 : TEST_EXPAND(".", "a", EURO "\\0", FALSE, EURO "a");
3085 : 1 : TEST_EXPAND(".", "", "\\Lab\\Ec", FALSE, "abc");
3086 : 1 : TEST_EXPAND(".", "", "\\LaB\\EC", FALSE, "abC");
3087 : 1 : TEST_EXPAND(".", "", "\\Uab\\Ec", FALSE, "ABc");
3088 : 1 : TEST_EXPAND(".", "", "a\\ubc", FALSE, "aBc");
3089 : 1 : TEST_EXPAND(".", "", "a\\lbc", FALSE, "abc");
3090 : 1 : TEST_EXPAND(".", "", "A\\uBC", FALSE, "ABC");
3091 : 1 : TEST_EXPAND(".", "", "A\\lBC", FALSE, "AbC");
3092 : 1 : TEST_EXPAND(".", "", "A\\l\\\\BC", FALSE, "A\\BC");
3093 : 1 : TEST_EXPAND(".", "", "\\L" AGRAVE "\\E", FALSE, AGRAVE);
3094 : 1 : TEST_EXPAND(".", "", "\\U" AGRAVE "\\E", FALSE, AGRAVE_UPPER);
3095 : 1 : TEST_EXPAND(".", "", "\\u" AGRAVE "a", FALSE, AGRAVE_UPPER "a");
3096 : 1 : TEST_EXPAND(".", "ab", "x\\U\\0y\\Ez", FALSE, "xAYz");
3097 : 1 : TEST_EXPAND(".(.)", "AB", "x\\L\\1y\\Ez", FALSE, "xbyz");
3098 : 1 : TEST_EXPAND(".", "ab", "x\\u\\0y\\Ez", FALSE, "xAyz");
3099 : 1 : TEST_EXPAND(".(.)", "AB", "x\\l\\1y\\Ez", FALSE, "xbyz");
3100 : 1 : TEST_EXPAND(".(.)", "a" AGRAVE_UPPER, "x\\l\\1y", FALSE, "x" AGRAVE "y");
3101 : 1 : TEST_EXPAND("a", "bab", "\\x{61}", FALSE, "a");
3102 : 1 : TEST_EXPAND("a", "bab", "\\x61", FALSE, "a");
3103 : 1 : TEST_EXPAND("a", "bab", "\\x5a", FALSE, "Z");
3104 : 1 : TEST_EXPAND("a", "bab", "\\0\\x5A", FALSE, "aZ");
3105 : 1 : TEST_EXPAND("a", "bab", "\\1\\x{5A}", FALSE, "Z");
3106 : 1 : TEST_EXPAND("a", "bab", "\\x{00E0}", FALSE, AGRAVE);
3107 : 1 : TEST_EXPAND("", "bab", "\\x{0634}", FALSE, SHEEN);
3108 : 1 : TEST_EXPAND("", "bab", "\\x{634}", FALSE, SHEEN);
3109 : 1 : TEST_EXPAND("", "", "\\t", FALSE, "\t");
3110 : 1 : TEST_EXPAND("", "", "\\v", FALSE, "\v");
3111 : 1 : TEST_EXPAND("", "", "\\r", FALSE, "\r");
3112 : 1 : TEST_EXPAND("", "", "\\n", FALSE, "\n");
3113 : 1 : TEST_EXPAND("", "", "\\f", FALSE, "\f");
3114 : 1 : TEST_EXPAND("", "", "\\a", FALSE, "\a");
3115 : 1 : TEST_EXPAND("", "", "\\b", FALSE, "\b");
3116 : 1 : TEST_EXPAND("a(.)", "abc", "\\0\\b\\1", FALSE, "ab\bb");
3117 : 1 : TEST_EXPAND("a(.)", "abc", "\\0141", FALSE, "a");
3118 : 1 : TEST_EXPAND("a(.)", "abc", "\\078", FALSE, "\a8");
3119 : 1 : TEST_EXPAND("a(.)", "abc", "\\077", FALSE, "?");
3120 : 1 : TEST_EXPAND("a(.)", "abc", "\\0778", FALSE, "?8");
3121 : 1 : TEST_EXPAND("a(.)", "a" AGRAVE "b", "\\1", FALSE, AGRAVE);
3122 : 1 : TEST_EXPAND("a(.)", "a" AGRAVE "b", "\\1", TRUE, "\xc3");
3123 : 1 : TEST_EXPAND("a(.)", "a" AGRAVE "b", "\\0", TRUE, "a\xc3");
3124 : : /* Invalid strings. */
3125 : 1 : TEST_EXPAND("", "", "\\Q", FALSE, NULL);
3126 : 1 : TEST_EXPAND("", "", "x\\Ay", FALSE, NULL);
3127 : 1 : TEST_EXPAND("", "", "\\g<", FALSE, NULL);
3128 : 1 : TEST_EXPAND("", "", "\\g<>", FALSE, NULL);
3129 : 1 : TEST_EXPAND("", "", "\\g<1a>", FALSE, NULL);
3130 : 1 : TEST_EXPAND("", "", "\\g<a$>", FALSE, NULL);
3131 : 1 : TEST_EXPAND("", "", "\\", FALSE, NULL);
3132 : 1 : TEST_EXPAND("a", "a", "\\x{61", FALSE, NULL);
3133 : 1 : TEST_EXPAND("a", "a", "\\x6X", FALSE, NULL);
3134 : : /* Pattern-less. */
3135 : 1 : TEST_EXPAND(NULL, NULL, "", FALSE, "");
3136 : 1 : TEST_EXPAND(NULL, NULL, "\\n", FALSE, "\n");
3137 : : /* Invalid strings */
3138 : 1 : TEST_EXPAND(NULL, NULL, "\\Q", FALSE, NULL);
3139 : 1 : TEST_EXPAND(NULL, NULL, "x\\Ay", FALSE, NULL);
3140 : :
3141 : : /* TEST_REPLACE(pattern, string, start_position, replacement, expected) */
3142 [ - + - + ]: 1 : TEST_REPLACE("a", "ababa", 0, "A", "AbAbA");
3143 [ - + - + ]: 1 : TEST_REPLACE("a", "ababa", 1, "A", "abAbA");
3144 [ - + - + ]: 1 : TEST_REPLACE("a", "ababa", 2, "A", "abAbA");
3145 [ - + - + ]: 1 : TEST_REPLACE("a", "ababa", 3, "A", "ababA");
3146 [ - + - + ]: 1 : TEST_REPLACE("a", "ababa", 4, "A", "ababA");
3147 [ - + - + ]: 1 : TEST_REPLACE("a", "ababa", 5, "A", "ababa");
3148 [ - + - + ]: 1 : TEST_REPLACE("a", "ababa", 6, "A", "ababa");
3149 [ - + - + ]: 1 : TEST_REPLACE("a", "abababa", 2, "A", "abAbAbA");
3150 [ - + - + ]: 1 : TEST_REPLACE("a", "abab", 0, "A", "AbAb");
3151 [ - + - + ]: 1 : TEST_REPLACE("a", "baba", 0, "A", "bAbA");
3152 [ - + - + ]: 1 : TEST_REPLACE("a", "bab", 0, "A", "bAb");
3153 [ - + - + ]: 1 : TEST_REPLACE("$^", "abc", 0, "X", "abc");
3154 [ - + - + ]: 1 : TEST_REPLACE("(.)a", "ciao", 0, "a\\1", "caio");
3155 [ - + - + ]: 1 : TEST_REPLACE("a.", "abc", 0, "\\0\\0", "ababc");
3156 [ - + - + ]: 1 : TEST_REPLACE("a", "asd", 0, "\\0101", "Asd");
3157 [ - + - + ]: 1 : TEST_REPLACE("(a).\\1", "aba cda", 0, "\\1\\n", "a\n cda");
3158 [ - + - + ]: 1 : TEST_REPLACE("a" AGRAVE "a", "a" AGRAVE "a", 0, "x", "x");
3159 [ - + - + ]: 1 : TEST_REPLACE("a" AGRAVE "a", "a" AGRAVE "a", 0, OGRAVE, OGRAVE);
3160 [ - + - + ]: 1 : TEST_REPLACE("[^-]", "-" EURO "-x-" HSTROKE, 0, "a", "-a-a-a");
3161 [ - + - + ]: 1 : TEST_REPLACE("[^-]", "-" EURO "-" HSTROKE, 0, "a\\g<0>a", "-a" EURO "a-a" HSTROKE "a");
3162 [ - + - + ]: 1 : TEST_REPLACE("-", "-" EURO "-" HSTROKE, 0, "", EURO HSTROKE);
3163 [ - + - + ]: 1 : TEST_REPLACE(".*", "hello", 0, "\\U\\0\\E", "HELLO");
3164 [ - + - + ]: 1 : TEST_REPLACE(".*", "hello", 0, "\\u\\0", "Hello");
3165 [ - + - + ]: 1 : TEST_REPLACE("\\S+", "hello world", 0, "\\U-\\0-", "-HELLO- -WORLD-");
3166 [ - + - + ]: 1 : TEST_REPLACE(".", "a", 0, "\\A", NULL);
3167 [ - + - + ]: 1 : TEST_REPLACE(".", "a", 0, "\\g", NULL);
3168 [ + - + - ]: 1 : TEST_REPLACE_OPTIONS("(\\w+)#(\\w+)", "aa#bb cc#dd", 0, "\\2#\\1", "bb#aa dd#cc",
3169 : : G_REGEX_OPTIMIZE|G_REGEX_MULTILINE|G_REGEX_CASELESS,
3170 : : 0);
3171 [ + - + - ]: 1 : TEST_REPLACE_OPTIONS("(\\w+)#(\\w+)", "aa#bb cc#dd", 0, "\\2#\\1", "bb#aa cc#dd",
3172 : : G_REGEX_OPTIMIZE|G_REGEX_MULTILINE|G_REGEX_CASELESS,
3173 : : G_REGEX_MATCH_ANCHORED);
3174 : :
3175 : : /* TEST_REPLACE_LIT(pattern, string, start_position, replacement, expected) */
3176 : 1 : TEST_REPLACE_LIT("a", "ababa", 0, "A", "AbAbA");
3177 : 1 : TEST_REPLACE_LIT("a", "ababa", 1, "A", "abAbA");
3178 : 1 : TEST_REPLACE_LIT("a", "ababa", 2, "A", "abAbA");
3179 : 1 : TEST_REPLACE_LIT("a", "ababa", 3, "A", "ababA");
3180 : 1 : TEST_REPLACE_LIT("a", "ababa", 4, "A", "ababA");
3181 : 1 : TEST_REPLACE_LIT("a", "ababa", 5, "A", "ababa");
3182 : 1 : TEST_REPLACE_LIT("a", "ababa", 6, "A", "ababa");
3183 : 1 : TEST_REPLACE_LIT("a", "abababa", 2, "A", "abAbAbA");
3184 : 1 : TEST_REPLACE_LIT("a", "abcadaa", 0, "A", "AbcAdAA");
3185 : 1 : TEST_REPLACE_LIT("$^", "abc", 0, "X", "abc");
3186 : 1 : TEST_REPLACE_LIT("(.)a", "ciao", 0, "a\\1", "ca\\1o");
3187 : 1 : TEST_REPLACE_LIT("a.", "abc", 0, "\\0\\0\\n", "\\0\\0\\nc");
3188 : 1 : TEST_REPLACE_LIT("a" AGRAVE "a", "a" AGRAVE "a", 0, "x", "x");
3189 : 1 : TEST_REPLACE_LIT("a" AGRAVE "a", "a" AGRAVE "a", 0, OGRAVE, OGRAVE);
3190 : 1 : TEST_REPLACE_LIT(AGRAVE, "-" AGRAVE "-" HSTROKE, 0, "a" ENG "a", "-a" ENG "a-" HSTROKE);
3191 : 1 : TEST_REPLACE_LIT("[^-]", "-" EURO "-" AGRAVE "-" HSTROKE, 0, "a", "-a-a-a");
3192 : 1 : TEST_REPLACE_LIT("[^-]", "-" EURO "-" AGRAVE, 0, "a\\g<0>a", "-a\\g<0>a-a\\g<0>a");
3193 : 1 : TEST_REPLACE_LIT("-", "-" EURO "-" AGRAVE "-" HSTROKE, 0, "", EURO AGRAVE HSTROKE);
3194 : 1 : TEST_REPLACE_LIT("(?=[A-Z0-9])", "RegExTest", 0, "_", "_Reg_Ex_Test");
3195 : 1 : TEST_REPLACE_LIT("(?=[A-Z0-9])", "RegExTest", 1, "_", "Reg_Ex_Test");
3196 : :
3197 : : /* TEST_GET_STRING_NUMBER(pattern, name, expected_num) */
3198 : 1 : TEST_GET_STRING_NUMBER("", "A", -1);
3199 : 1 : TEST_GET_STRING_NUMBER("(?P<A>.)", "A", 1);
3200 : 1 : TEST_GET_STRING_NUMBER("(?P<A>.)", "B", -1);
3201 : 1 : TEST_GET_STRING_NUMBER("(?P<A>.)(?P<B>a)", "A", 1);
3202 : 1 : TEST_GET_STRING_NUMBER("(?P<A>.)(?P<B>a)", "B", 2);
3203 : 1 : TEST_GET_STRING_NUMBER("(?P<A>.)(?P<B>a)", "C", -1);
3204 : 1 : TEST_GET_STRING_NUMBER("(?P<A>.)(?P<B>a)(?P<C>b)", "A", 1);
3205 : 1 : TEST_GET_STRING_NUMBER("(?P<A>.)(?P<B>a)(?P<C>b)", "B", 2);
3206 : 1 : TEST_GET_STRING_NUMBER("(?P<A>.)(?P<B>a)(?P<C>b)", "C", 3);
3207 : 1 : TEST_GET_STRING_NUMBER("(?P<A>.)(?P<B>a)(?P<C>b)", "D", -1);
3208 : 1 : TEST_GET_STRING_NUMBER("(?P<A>.)(.)(?P<B>a)", "A", 1);
3209 : 1 : TEST_GET_STRING_NUMBER("(?P<A>.)(.)(?P<B>a)", "B", 3);
3210 : 1 : TEST_GET_STRING_NUMBER("(?P<A>.)(.)(?P<B>a)", "C", -1);
3211 : 1 : TEST_GET_STRING_NUMBER("(?:a)(?P<A>.)", "A", 1);
3212 : 1 : TEST_GET_STRING_NUMBER("(?:a)(?P<A>.)", "B", -1);
3213 : :
3214 : : /* TEST_ESCAPE_NUL(string, length, expected) */
3215 : 1 : TEST_ESCAPE_NUL("hello world", -1, "hello world");
3216 : 1 : TEST_ESCAPE_NUL("hello\0world", -1, "hello");
3217 : 1 : TEST_ESCAPE_NUL("\0world", -1, "");
3218 : 1 : TEST_ESCAPE_NUL("hello world", 5, "hello");
3219 : 1 : TEST_ESCAPE_NUL("hello.world", 11, "hello.world");
3220 : 1 : TEST_ESCAPE_NUL("a(b\\b.$", 7, "a(b\\b.$");
3221 : 1 : TEST_ESCAPE_NUL("hello\0", 6, "hello\\x00");
3222 : 1 : TEST_ESCAPE_NUL("\0world", 6, "\\x00world");
3223 : 1 : TEST_ESCAPE_NUL("\0\0", 2, "\\x00\\x00");
3224 : 1 : TEST_ESCAPE_NUL("hello\0world", 11, "hello\\x00world");
3225 : 1 : TEST_ESCAPE_NUL("hello\0world\0", 12, "hello\\x00world\\x00");
3226 : 1 : TEST_ESCAPE_NUL("hello\\\0world", 12, "hello\\x00world");
3227 : 1 : TEST_ESCAPE_NUL("hello\\\\\0world", 13, "hello\\\\\\x00world");
3228 : 1 : TEST_ESCAPE_NUL("|()[]{}^$*+?.", 13, "|()[]{}^$*+?.");
3229 : 1 : TEST_ESCAPE_NUL("|()[]{}^$*+?.\\\\", 15, "|()[]{}^$*+?.\\\\");
3230 : :
3231 : : /* TEST_ESCAPE(string, length, expected) */
3232 : 1 : TEST_ESCAPE("hello world", -1, "hello world");
3233 : 1 : TEST_ESCAPE("hello world", 5, "hello");
3234 : 1 : TEST_ESCAPE("hello.world", -1, "hello\\.world");
3235 : 1 : TEST_ESCAPE("a(b\\b.$", -1, "a\\(b\\\\b\\.\\$");
3236 : 1 : TEST_ESCAPE("hello\0world", -1, "hello");
3237 : 1 : TEST_ESCAPE("hello\0world", 11, "hello\\0world");
3238 : 1 : TEST_ESCAPE(EURO "*" ENG, -1, EURO "\\*" ENG);
3239 : 1 : TEST_ESCAPE("a$", -1, "a\\$");
3240 : 1 : TEST_ESCAPE("$a", -1, "\\$a");
3241 : 1 : TEST_ESCAPE("a$a", -1, "a\\$a");
3242 : 1 : TEST_ESCAPE("$a$", -1, "\\$a\\$");
3243 : 1 : TEST_ESCAPE("$a$", 0, "");
3244 : 1 : TEST_ESCAPE("$a$", 1, "\\$");
3245 : 1 : TEST_ESCAPE("$a$", 2, "\\$a");
3246 : 1 : TEST_ESCAPE("$a$", 3, "\\$a\\$");
3247 : 1 : TEST_ESCAPE("$a$", 4, "\\$a\\$\\0");
3248 : 1 : TEST_ESCAPE("|()[]{}^$*+?.", -1, "\\|\\(\\)\\[\\]\\{\\}\\^\\$\\*\\+\\?\\.");
3249 : 1 : TEST_ESCAPE("a|a(a)a[a]a{a}a^a$a*a+a?a.a", -1,
3250 : : "a\\|a\\(a\\)a\\[a\\]a\\{a\\}a\\^a\\$a\\*a\\+a\\?a\\.a");
3251 : :
3252 : : /* TEST_MATCH_ALL#(pattern, string, string_len, start_position, ...) */
3253 : 1 : TEST_MATCH_ALL0("<.*>", "", -1, 0);
3254 : 1 : TEST_MATCH_ALL0("a+", "", -1, 0);
3255 : 1 : TEST_MATCH_ALL0("a+", "a", 0, 0);
3256 : 1 : TEST_MATCH_ALL0("a+", "a", -1, 1);
3257 : 1 : TEST_MATCH_ALL1("<.*>", "<a>", -1, 0, "<a>", 0, 3);
3258 : 1 : TEST_MATCH_ALL1("a+", "a", -1, 0, "a", 0, 1);
3259 : 1 : TEST_MATCH_ALL1("a+", "aa", 1, 0, "a", 0, 1);
3260 : 1 : TEST_MATCH_ALL1("a+", "aa", -1, 1, "a", 1, 2);
3261 : 1 : TEST_MATCH_ALL1("a+", "aa", 2, 1, "a", 1, 2);
3262 : 1 : TEST_MATCH_ALL1(".+", ENG, -1, 0, ENG, 0, 2);
3263 : 1 : TEST_MATCH_ALL2("<.*>", "<a><b>", -1, 0, "<a><b>", 0, 6, "<a>", 0, 3);
3264 : 1 : TEST_MATCH_ALL2("a+", "aa", -1, 0, "aa", 0, 2, "a", 0, 1);
3265 : 1 : TEST_MATCH_ALL2(".+", ENG EURO, -1, 0, ENG EURO, 0, 5, ENG, 0, 2);
3266 : 1 : TEST_MATCH_ALL3("<.*>", "<a><b><c>", -1, 0, "<a><b><c>", 0, 9,
3267 : : "<a><b>", 0, 6, "<a>", 0, 3);
3268 : 1 : TEST_MATCH_ALL3("a+", "aaa", -1, 0, "aaa", 0, 3, "aa", 0, 2, "a", 0, 1);
3269 : :
3270 : : /* NOTEMPTY matching */
3271 [ - + - + ]: 1 : TEST_MATCH_NOTEMPTY("a?b?", "xyz", FALSE);
3272 [ - + - + ]: 1 : TEST_MATCH_NOTEMPTY_ATSTART("a?b?", "xyz", TRUE);
3273 : :
3274 : 1 : return g_test_run ();
3275 : : }
|