Coverage Report

Created: 2026-09-14 06:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/glib/glib/gregex.c
Line
Count
Source
1
/* GRegex -- regular expression API wrapper around PCRE.
2
 *
3
 * Copyright (C) 1999, 2000 Scott Wimer
4
 * Copyright (C) 2004, Matthias Clasen <mclasen@redhat.com>
5
 * Copyright (C) 2005 - 2007, Marco Barisione <marco@barisione.org>
6
 * Copyright (C) 2022, Marco Trevisan <marco.trevisan@canonical.com>
7
 *
8
 * SPDX-License-Identifier: LGPL-2.1-or-later
9
 *
10
 * This library is free software; you can redistribute it and/or
11
 * modify it under the terms of the GNU Lesser General Public
12
 * License as published by the Free Software Foundation; either
13
 * version 2.1 of the License, or (at your option) any later version.
14
 *
15
 * This library is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18
 * Lesser General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Lesser General Public License
21
 * along with this library; if not, see <http://www.gnu.org/licenses/>.
22
 */
23
24
#include "config.h"
25
26
#include <stdint.h>
27
#include <string.h>
28
29
#define PCRE2_CODE_UNIT_WIDTH 8
30
#include <pcre2.h>
31
32
#include "gtypes.h"
33
#include "gregex.h"
34
#include "glibintl.h"
35
#include "glist.h"
36
#include "gmessages.h"
37
#include "gstrfuncs.h"
38
#include "gatomic.h"
39
#include "gtestutils.h"
40
#include "gthread.h"
41
42
/**
43
 * GRegex:
44
 *
45
 * A `GRegex` is a compiled form of a regular expression.
46
 * 
47
 * After instantiating a `GRegex`, you can use its methods to find matches
48
 * in a string, replace matches within a string, or split the string at matches.
49
 *
50
 * `GRegex` implements regular expression pattern matching using syntax and 
51
 * semantics (such as character classes, quantifiers, and capture groups) 
52
 * similar to Perl regular expression. See the 
53
 * [PCRE documentation](man:pcre2pattern(3)) for details.
54
 *
55
 * A typical scenario for regex pattern matching is to check if a string 
56
 * matches a pattern. The following statements implement this scenario.
57
 * 
58
 * ``` { .c }
59
 * const char *regex_pattern = ".*GLib.*";
60
 * const char *string_to_search = "You will love the GLib implementation of regex";
61
 * g_autoptr(GMatchInfo) match_info = NULL;
62
 * g_autoptr(GRegex) regex = NULL;
63
 *
64
 * regex = g_regex_new (regex_pattern, G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL);
65
 * g_assert (regex != NULL);
66
 * 
67
 * if (g_regex_match (regex, string_to_search, G_REGEX_MATCH_DEFAULT, &match_info))
68
 *   {
69
 *     int start_pos, end_pos;
70
 *     g_match_info_fetch_pos (match_info, 0, &start_pos, &end_pos);
71
 *     g_print ("Match successful! Overall pattern matches bytes %d to %d\n", start_pos, end_pos);
72
 *   }
73
 * else
74
 *   {
75
 *     g_print ("No match!\n");
76
 *   }
77
 * ```
78
 * 
79
 * The constructor for `GRegex` includes two sets of bitmapped flags:
80
81
 * * [flags@GLib.RegexCompileFlags]—These flags 
82
 * control how GLib compiles the regex. There are options for case 
83
 * sensitivity, multiline, ignoring whitespace, etc.
84
 * * [flags@GLib.RegexMatchFlags]—These flags control 
85
 * `GRegex`’s matching behavior, such as anchoring and customizing definitions 
86
 * for newline characters.
87
 * 
88
 * Some regex patterns include backslash assertions, such as `\d` (digit) or 
89
 * `\D` (non-digit). The regex pattern must escape those backslashes. For 
90
 * example, the pattern `"\\d\\D"` matches a digit followed by a non-digit.
91
 *
92
 * GLib’s implementation of pattern matching includes a `start_position` 
93
 * argument for some of the match, replace, and split methods. Specifying 
94
 * a start position provides flexibility when you want to ignore the first 
95
 * _n_ characters of a string, but want to incorporate backslash assertions 
96
 * at character _n_ - 1. For example, a database field contains inconsistent
97
 * spelling for a job title: `healthcare provider` and `health-care provider`.
98
 * The database manager wants to make the spelling consistent by adding a 
99
 * hyphen when it is missing. The following regex pattern tests for the string 
100
 * `care` preceded by a non-word boundary character (instead of a hyphen) 
101
 * and followed by a space.
102
 *
103
 * ``` { .c }
104
 * const char *regex_pattern = "\\Bcare\\s";
105
 * ```
106
 *
107
 * An efficient way to match with this pattern is to start examining at 
108
 * `start_position` 6 in the string `healthcare` or `health-care`.
109
110
 * ``` { .c }
111
 * const char *regex_pattern = "\\Bcare\\s";
112
 * const char *string_to_search = "healthcare provider";
113
 * g_autoptr(GMatchInfo) match_info = NULL;
114
 * g_autoptr(GRegex) regex = NULL;
115
 *
116
 * regex = g_regex_new (
117
 *   regex_pattern,
118
 *   G_REGEX_DEFAULT,
119
 *   G_REGEX_MATCH_DEFAULT,
120
 *   NULL);
121
 * g_assert (regex != NULL);
122
 * 
123
 * g_regex_match_full (
124
 *   regex, 
125
 *   string_to_search, 
126
 *   -1,
127
 *   6, // position of 'c' in the test string.
128
 *   G_REGEX_MATCH_DEFAULT, 
129
 *   &match_info,
130
 *   NULL);
131
 * ```
132
 * 
133
 * The method [method@GLib.Regex.match_full] (and other methods implementing 
134
 * `start_pos`) allow for lookback before the start position to determine if 
135
 * the previous character satisfies an assertion.
136
 *
137
 * Unless you set the [flags@GLib.RegexCompileFlags.RAW] as one of 
138
 * the `GRegexCompileFlags`, all the strings passed to `GRegex` methods must 
139
 * be encoded in UTF-8. The lengths and the positions inside the strings are 
140
 * in bytes and not in characters, so, for instance, `\xc3\xa0` (i.e., `à`) 
141
 * is two bytes long but it is treated as a single character. If you set 
142
 * `G_REGEX_RAW`, the strings can be non-valid UTF-8 strings and a byte is 
143
 * treated as a character, so `\xc3\xa0` is two bytes and two characters long.
144
 *
145
 * Regarding line endings, `\n` matches a `\n` character, and `\r` matches 
146
 * a `\r` character. More generally, `\R` matches all typical line endings: 
147
 * CR + LF (`\r\n`), LF (linefeed, U+000A, `\n`), VT (vertical tab, U+000B, 
148
 * `\v`), FF (formfeed, U+000C, `\f`), CR (carriage return, U+000D, `\r`), 
149
 * NEL (next line, U+0085), LS (line separator, U+2028), and PS (paragraph 
150
 * separator, U+2029).
151
 * 
152
 * The behaviour of the dot, circumflex, and dollar metacharacters are 
153
 * affected by newline characters. By default, `GRegex` matches any newline 
154
 * character matched by `\R`. You can limit the matched newline characters by 
155
 * specifying the [flags@GLib.RegexMatchFlags.NEWLINE_CR], 
156
 * [flags@GLib.RegexMatchFlags.NEWLINE_LF], and 
157
 * [flags@GLib.RegexMatchFlags.NEWLINE_CRLF] compile options, and 
158
 * with [flags@GLib.RegexMatchFlags.NEWLINE_ANY], 
159
 * [flags@GLib.RegexMatchFlags.NEWLINE_CR], 
160
 * [flags@GLib.RegexMatchFlags.NEWLINE_LF] and 
161
 * [flags@GLib.RegexMatchFlags.NEWLINE_CRLF] match options. 
162
 * These settings are also relevant when compiling a pattern if 
163
 * [flags@GLib.RegexCompileFlags.EXTENDED] is set and an unescaped 
164
 * `#` outside a character class is encountered. This indicates a comment 
165
 * that lasts until after the next newline.
166
 * 
167
 * Because `GRegex` does not modify its internal state between creation and 
168
 * destruction, you can create and modify the same `GRegex` instance from 
169
 * different threads. In contrast, [struct@GLib.MatchInfo] is not thread safe.
170
 * 
171
 * The regular expression low-level functionalities are obtained through
172
 * the excellent [PCRE](http://www.pcre.org/) library written by Philip Hazel.
173
 *
174
 * Since: 2.14
175
 */
176
177
0
#define G_REGEX_PCRE_GENERIC_MASK (PCRE2_ANCHORED       | \
178
0
                                   PCRE2_NO_UTF_CHECK   | \
179
0
                                   PCRE2_ENDANCHORED)
180
181
/* Mask of all the possible values for GRegexCompileFlags. */
182
0
#define G_REGEX_COMPILE_MASK (G_REGEX_DEFAULT          | \
183
0
                              G_REGEX_CASELESS         | \
184
0
                              G_REGEX_MULTILINE        | \
185
0
                              G_REGEX_DOTALL           | \
186
0
                              G_REGEX_EXTENDED         | \
187
0
                              G_REGEX_ANCHORED         | \
188
0
                              G_REGEX_DOLLAR_ENDONLY   | \
189
0
                              G_REGEX_UNGREEDY         | \
190
0
                              G_REGEX_RAW              | \
191
0
                              G_REGEX_NO_AUTO_CAPTURE  | \
192
0
                              G_REGEX_OPTIMIZE         | \
193
0
                              G_REGEX_FIRSTLINE        | \
194
0
                              G_REGEX_DUPNAMES         | \
195
0
                              G_REGEX_NEWLINE_CR       | \
196
0
                              G_REGEX_NEWLINE_LF       | \
197
0
                              G_REGEX_NEWLINE_CRLF     | \
198
0
                              G_REGEX_NEWLINE_ANYCRLF  | \
199
0
                              G_REGEX_BSR_ANYCRLF)
200
201
0
#define G_REGEX_PCRE2_COMPILE_MASK (PCRE2_ALLOW_EMPTY_CLASS    | \
202
0
                                    PCRE2_ALT_BSUX             | \
203
0
                                    PCRE2_AUTO_CALLOUT         | \
204
0
                                    PCRE2_CASELESS             | \
205
0
                                    PCRE2_DOLLAR_ENDONLY       | \
206
0
                                    PCRE2_DOTALL               | \
207
0
                                    PCRE2_DUPNAMES             | \
208
0
                                    PCRE2_EXTENDED             | \
209
0
                                    PCRE2_FIRSTLINE            | \
210
0
                                    PCRE2_MATCH_UNSET_BACKREF  | \
211
0
                                    PCRE2_MULTILINE            | \
212
0
                                    PCRE2_NEVER_UCP            | \
213
0
                                    PCRE2_NEVER_UTF            | \
214
0
                                    PCRE2_NO_AUTO_CAPTURE      | \
215
0
                                    PCRE2_NO_AUTO_POSSESS      | \
216
0
                                    PCRE2_NO_DOTSTAR_ANCHOR    | \
217
0
                                    PCRE2_NO_START_OPTIMIZE    | \
218
0
                                    PCRE2_UCP                  | \
219
0
                                    PCRE2_UNGREEDY             | \
220
0
                                    PCRE2_UTF                  | \
221
0
                                    PCRE2_NEVER_BACKSLASH_C    | \
222
0
                                    PCRE2_ALT_CIRCUMFLEX       | \
223
0
                                    PCRE2_ALT_VERBNAMES        | \
224
0
                                    PCRE2_USE_OFFSET_LIMIT     | \
225
0
                                    PCRE2_EXTENDED_MORE        | \
226
0
                                    PCRE2_LITERAL              | \
227
0
                                    PCRE2_MATCH_INVALID_UTF    | \
228
0
                                    G_REGEX_PCRE_GENERIC_MASK)
229
230
0
#define G_REGEX_COMPILE_NONPCRE_MASK (PCRE2_UTF)
231
232
/* Mask of all the possible values for GRegexMatchFlags. */
233
0
#define G_REGEX_MATCH_MASK (G_REGEX_MATCH_DEFAULT          | \
234
0
                            G_REGEX_MATCH_ANCHORED         | \
235
0
                            G_REGEX_MATCH_NOTBOL           | \
236
0
                            G_REGEX_MATCH_NOTEOL           | \
237
0
                            G_REGEX_MATCH_NOTEMPTY         | \
238
0
                            G_REGEX_MATCH_PARTIAL          | \
239
0
                            G_REGEX_MATCH_NEWLINE_CR       | \
240
0
                            G_REGEX_MATCH_NEWLINE_LF       | \
241
0
                            G_REGEX_MATCH_NEWLINE_CRLF     | \
242
0
                            G_REGEX_MATCH_NEWLINE_ANY      | \
243
0
                            G_REGEX_MATCH_NEWLINE_ANYCRLF  | \
244
0
                            G_REGEX_MATCH_BSR_ANYCRLF      | \
245
0
                            G_REGEX_MATCH_BSR_ANY          | \
246
0
                            G_REGEX_MATCH_PARTIAL_SOFT     | \
247
0
                            G_REGEX_MATCH_PARTIAL_HARD     | \
248
0
                            G_REGEX_MATCH_NOTEMPTY_ATSTART)
249
250
0
#define G_REGEX_PCRE2_MATCH_MASK (PCRE2_NOTBOL                      |\
251
0
                                  PCRE2_NOTEOL                      |\
252
0
                                  PCRE2_NOTEMPTY                    |\
253
0
                                  PCRE2_NOTEMPTY_ATSTART            |\
254
0
                                  PCRE2_PARTIAL_SOFT                |\
255
0
                                  PCRE2_PARTIAL_HARD                |\
256
0
                                  PCRE2_NO_JIT                      |\
257
0
                                  PCRE2_COPY_MATCHED_SUBJECT        |\
258
0
                                  G_REGEX_PCRE_GENERIC_MASK)
259
260
/* TODO: Support PCRE2_NEWLINE_NUL */
261
#define G_REGEX_NEWLINE_MASK (PCRE2_NEWLINE_CR |     \
262
                              PCRE2_NEWLINE_LF |     \
263
                              PCRE2_NEWLINE_CRLF |   \
264
                              PCRE2_NEWLINE_ANYCRLF)
265
266
/* Some match options are not supported when using JIT as stated in the
267
 * pcre2jit man page under the «UNSUPPORTED OPTIONS AND PATTERN ITEMS» section:
268
 *   https://www.pcre.org/current/doc/html/pcre2jit.html#SEC5
269
 */
270
0
#define G_REGEX_PCRE2_JIT_UNSUPPORTED_OPTIONS (PCRE2_ANCHORED | \
271
0
                                               PCRE2_ENDANCHORED)
272
273
0
#define G_REGEX_COMPILE_NEWLINE_MASK (G_REGEX_NEWLINE_CR      | \
274
0
                                      G_REGEX_NEWLINE_LF      | \
275
0
                                      G_REGEX_NEWLINE_CRLF    | \
276
0
                                      G_REGEX_NEWLINE_ANYCRLF)
277
278
0
#define G_REGEX_MATCH_NEWLINE_MASK (G_REGEX_MATCH_NEWLINE_CR      | \
279
0
                                    G_REGEX_MATCH_NEWLINE_LF      | \
280
0
                                    G_REGEX_MATCH_NEWLINE_CRLF    | \
281
0
                                    G_REGEX_MATCH_NEWLINE_ANY    | \
282
0
                                    G_REGEX_MATCH_NEWLINE_ANYCRLF)
283
284
/* if the string is in UTF-8 use g_utf8_ functions, else use
285
 * use just +/- 1. */
286
0
#define NEXT_CHAR(re, s) (((re)->regex_compile_opts & G_REGEX_RAW) ? \
287
0
                                ((s) + 1) : \
288
0
                                g_utf8_next_char (s))
289
0
#define PREV_CHAR(re, s) (((re)->regex_compile_opts & G_REGEX_RAW) ? \
290
0
                                ((s) - 1) : \
291
0
                                g_utf8_prev_char (s))
292
293
struct _GMatchInfo
294
{
295
  gint ref_count;               /* the ref count (atomic) */
296
  GRegex *regex;                /* the regex */
297
  uint32_t match_opts;          /* pcre match options used at match time on the regex */
298
  gint matches;                 /* number of matching sub patterns, guaranteed to be <= (n_subpatterns + 1) if doing a single match (rather than matching all) */
299
  uint32_t n_subpatterns;       /* total number of sub patterns in the regex */
300
  size_t pos;                   /* position in the string where last match left off; check @pos_valid before using */
301
  gboolean pos_valid;           /* whether @pos is valid; will be false when reaching the end of the string */
302
  size_t n_offsets;             /* number of offsets */
303
  gint *offsets;                /* array of offsets paired 0,1 ; 2,3 ; 3,4 etc */
304
  gint *workspace;              /* workspace for pcre2_dfa_match() */
305
  PCRE2_SIZE n_workspace;       /* number of workspace elements */
306
  const gchar *string;          /* string passed to the match function */
307
  size_t string_len;            /* length of string, in bytes */
308
  pcre2_match_context *match_context;
309
  pcre2_match_data *match_data;
310
  pcre2_jit_stack *jit_stack;
311
};
312
313
typedef enum
314
{
315
  JIT_STATUS_DEFAULT,
316
  JIT_STATUS_ENABLED,
317
  JIT_STATUS_DISABLED
318
} JITStatus;
319
320
struct _GRegex
321
{
322
  gint ref_count;               /* the ref count for the immutable part (atomic) */
323
  gchar *pattern;               /* the pattern */
324
  pcre2_code *pcre_re;          /* compiled form of the pattern */
325
  uint32_t pcre2_compile_opts;  /* options used at compile time on the pattern, pcre2 values */
326
  GRegexCompileFlags regex_compile_opts; /* options used at compile time on the pattern, gregex values */
327
  uint32_t match_opts;          /* pcre2 options used at match time on the regex */
328
  GRegexMatchFlags orig_match_opts; /* options used as default match options, gregex values */
329
  uint32_t jit_options;         /* options which were enabled for jit compiler */
330
  JITStatus jit_status;         /* indicates the status of jit compiler for this compiled regex */
331
  /* The jit_status here does _not_ correspond to whether we used the JIT in the last invocation,
332
   * which may be affected by match_options or a JIT_STACK_LIMIT error, but whether it was ever
333
   * enabled for the current regex AND current set of jit_options.
334
   * JIT_STATUS_DEFAULT means enablement was never tried,
335
   * JIT_STATUS_ENABLED means it was tried and successful (even if we're not currently using it),
336
   * and JIT_STATUS_DISABLED means it was tried and failed (so we shouldn't try again).
337
   */
338
};
339
340
/* TRUE if ret is an error code, FALSE otherwise. */
341
0
#define IS_PCRE2_ERROR(ret) ((ret) < PCRE2_ERROR_NOMATCH && (ret) != PCRE2_ERROR_PARTIAL)
342
343
typedef struct _InterpolationData InterpolationData;
344
static gboolean  interpolation_list_needs_match (GList *list);
345
static gboolean  interpolate_replacement        (const GMatchInfo *match_info,
346
                                                 GString *result,
347
                                                 gpointer data);
348
static GList    *split_replacement              (const gchar *replacement,
349
                                                 GError **error);
350
static void      free_interpolation_data        (InterpolationData *data);
351
352
static uint32_t
353
get_pcre2_compile_options (GRegexCompileFlags compile_flags)
354
0
{
355
  /* Maps compile flags to pcre2 values */
356
0
  uint32_t pcre2_flags = 0;
357
358
0
  if (compile_flags & G_REGEX_CASELESS)
359
0
    pcre2_flags |= PCRE2_CASELESS;
360
0
  if (compile_flags & G_REGEX_MULTILINE)
361
0
    pcre2_flags |= PCRE2_MULTILINE;
362
0
  if (compile_flags & G_REGEX_DOTALL)
363
0
    pcre2_flags |= PCRE2_DOTALL;
364
0
  if (compile_flags & G_REGEX_EXTENDED)
365
0
    pcre2_flags |= PCRE2_EXTENDED;
366
0
  if (compile_flags & G_REGEX_ANCHORED)
367
0
    pcre2_flags |= PCRE2_ANCHORED;
368
0
  if (compile_flags & G_REGEX_DOLLAR_ENDONLY)
369
0
    pcre2_flags |= PCRE2_DOLLAR_ENDONLY;
370
0
  if (compile_flags & G_REGEX_UNGREEDY)
371
0
    pcre2_flags |= PCRE2_UNGREEDY;
372
0
  if (!(compile_flags & G_REGEX_RAW))
373
0
    pcre2_flags |= PCRE2_UTF;
374
0
  if (compile_flags & G_REGEX_NO_AUTO_CAPTURE)
375
0
    pcre2_flags |= PCRE2_NO_AUTO_CAPTURE;
376
0
  if (compile_flags & G_REGEX_FIRSTLINE)
377
0
    pcre2_flags |= PCRE2_FIRSTLINE;
378
0
  if (compile_flags & G_REGEX_DUPNAMES)
379
0
    pcre2_flags |= PCRE2_DUPNAMES;
380
381
0
  return pcre2_flags & G_REGEX_PCRE2_COMPILE_MASK;
382
0
}
383
384
static uint32_t
385
get_pcre2_match_options (GRegexMatchFlags   match_flags,
386
                         GRegexCompileFlags compile_flags)
387
0
{
388
  /* Maps match flags to pcre2 values */
389
0
  uint32_t pcre2_flags = 0;
390
391
0
  if (match_flags & G_REGEX_MATCH_ANCHORED)
392
0
    pcre2_flags |= PCRE2_ANCHORED;
393
0
  if (match_flags & G_REGEX_MATCH_NOTBOL)
394
0
    pcre2_flags |= PCRE2_NOTBOL;
395
0
  if (match_flags & G_REGEX_MATCH_NOTEOL)
396
0
    pcre2_flags |= PCRE2_NOTEOL;
397
0
  if (match_flags & G_REGEX_MATCH_NOTEMPTY)
398
0
    pcre2_flags |= PCRE2_NOTEMPTY;
399
0
  if (match_flags & G_REGEX_MATCH_PARTIAL_SOFT)
400
0
    pcre2_flags |= PCRE2_PARTIAL_SOFT;
401
0
  if (match_flags & G_REGEX_MATCH_PARTIAL_HARD)
402
0
    pcre2_flags |= PCRE2_PARTIAL_HARD;
403
0
  if (match_flags & G_REGEX_MATCH_NOTEMPTY_ATSTART)
404
0
    pcre2_flags |= PCRE2_NOTEMPTY_ATSTART;
405
406
0
  if (compile_flags & G_REGEX_RAW)
407
0
    pcre2_flags |= PCRE2_NO_UTF_CHECK;
408
409
0
  return pcre2_flags & G_REGEX_PCRE2_MATCH_MASK;
410
0
}
411
412
static GRegexCompileFlags
413
g_regex_compile_flags_from_pcre2 (uint32_t pcre2_flags)
414
0
{
415
0
  GRegexCompileFlags compile_flags = G_REGEX_DEFAULT;
416
417
0
  if (pcre2_flags & PCRE2_CASELESS)
418
0
    compile_flags |= G_REGEX_CASELESS;
419
0
  if (pcre2_flags & PCRE2_MULTILINE)
420
0
    compile_flags |= G_REGEX_MULTILINE;
421
0
  if (pcre2_flags & PCRE2_DOTALL)
422
0
    compile_flags |= G_REGEX_DOTALL;
423
0
  if (pcre2_flags & PCRE2_EXTENDED)
424
0
    compile_flags |= G_REGEX_EXTENDED;
425
0
  if (pcre2_flags & PCRE2_ANCHORED)
426
0
    compile_flags |= G_REGEX_ANCHORED;
427
0
  if (pcre2_flags & PCRE2_DOLLAR_ENDONLY)
428
0
    compile_flags |= G_REGEX_DOLLAR_ENDONLY;
429
0
  if (pcre2_flags & PCRE2_UNGREEDY)
430
0
    compile_flags |= G_REGEX_UNGREEDY;
431
0
  if (!(pcre2_flags & PCRE2_UTF))
432
0
    compile_flags |= G_REGEX_RAW;
433
0
  if (pcre2_flags & PCRE2_NO_AUTO_CAPTURE)
434
0
    compile_flags |= G_REGEX_NO_AUTO_CAPTURE;
435
0
  if (pcre2_flags & PCRE2_FIRSTLINE)
436
0
    compile_flags |= G_REGEX_FIRSTLINE;
437
0
  if (pcre2_flags & PCRE2_DUPNAMES)
438
0
    compile_flags |= G_REGEX_DUPNAMES;
439
440
0
  return compile_flags & G_REGEX_COMPILE_MASK;
441
0
}
442
443
static GRegexMatchFlags
444
g_regex_match_flags_from_pcre2 (uint32_t pcre2_flags)
445
0
{
446
0
  GRegexMatchFlags match_flags = G_REGEX_MATCH_DEFAULT;
447
448
0
  if (pcre2_flags & PCRE2_ANCHORED)
449
0
    match_flags |= G_REGEX_MATCH_ANCHORED;
450
0
  if (pcre2_flags & PCRE2_NOTBOL)
451
0
    match_flags |= G_REGEX_MATCH_NOTBOL;
452
0
  if (pcre2_flags & PCRE2_NOTEOL)
453
0
    match_flags |= G_REGEX_MATCH_NOTEOL;
454
0
  if (pcre2_flags & PCRE2_NOTEMPTY)
455
0
    match_flags |= G_REGEX_MATCH_NOTEMPTY;
456
0
  if (pcre2_flags & PCRE2_PARTIAL_SOFT)
457
0
    match_flags |= G_REGEX_MATCH_PARTIAL_SOFT;
458
0
  if (pcre2_flags & PCRE2_PARTIAL_HARD)
459
0
    match_flags |= G_REGEX_MATCH_PARTIAL_HARD;
460
0
  if (pcre2_flags & PCRE2_NOTEMPTY_ATSTART)
461
0
    match_flags |= G_REGEX_MATCH_NOTEMPTY_ATSTART;
462
463
0
  return (match_flags & G_REGEX_MATCH_MASK);
464
0
}
465
466
static uint32_t
467
get_pcre2_newline_compile_options (GRegexCompileFlags compile_flags)
468
0
{
469
0
  compile_flags &= G_REGEX_COMPILE_NEWLINE_MASK;
470
471
0
  switch (compile_flags)
472
0
    {
473
0
    case G_REGEX_NEWLINE_CR:
474
0
      return PCRE2_NEWLINE_CR;
475
0
    case G_REGEX_NEWLINE_LF:
476
0
      return PCRE2_NEWLINE_LF;
477
0
    case G_REGEX_NEWLINE_CRLF:
478
0
      return PCRE2_NEWLINE_CRLF;
479
0
    case G_REGEX_NEWLINE_ANYCRLF:
480
0
      return PCRE2_NEWLINE_ANYCRLF;
481
0
    default:
482
0
      if (compile_flags != 0)
483
0
        return 0;
484
485
0
      return PCRE2_NEWLINE_ANY;
486
0
    }
487
0
}
488
489
static uint32_t
490
get_pcre2_newline_match_options (GRegexMatchFlags match_flags)
491
0
{
492
0
  switch (match_flags & G_REGEX_MATCH_NEWLINE_MASK)
493
0
    {
494
0
    case G_REGEX_MATCH_NEWLINE_CR:
495
0
      return PCRE2_NEWLINE_CR;
496
0
    case G_REGEX_MATCH_NEWLINE_LF:
497
0
      return PCRE2_NEWLINE_LF;
498
0
    case G_REGEX_MATCH_NEWLINE_CRLF:
499
0
      return PCRE2_NEWLINE_CRLF;
500
0
    case G_REGEX_MATCH_NEWLINE_ANY:
501
0
      return PCRE2_NEWLINE_ANY;
502
0
    case G_REGEX_MATCH_NEWLINE_ANYCRLF:
503
0
      return PCRE2_NEWLINE_ANYCRLF;
504
0
    default:
505
0
      return 0;
506
0
    }
507
0
}
508
509
static uint32_t
510
get_pcre2_bsr_compile_options (GRegexCompileFlags compile_flags)
511
0
{
512
0
  if (compile_flags & G_REGEX_BSR_ANYCRLF)
513
0
    return PCRE2_BSR_ANYCRLF;
514
515
0
  return PCRE2_BSR_UNICODE;
516
0
}
517
518
static uint32_t
519
get_pcre2_bsr_match_options (GRegexMatchFlags match_flags)
520
0
{
521
0
  if (match_flags & G_REGEX_MATCH_BSR_ANYCRLF)
522
0
    return PCRE2_BSR_ANYCRLF;
523
524
0
  if (match_flags & G_REGEX_MATCH_BSR_ANY)
525
0
    return PCRE2_BSR_UNICODE;
526
527
0
  return 0;
528
0
}
529
530
static char *
531
get_pcre2_error_string (int errcode)
532
0
{
533
0
  PCRE2_UCHAR8 error_msg[2048];
534
0
  int err_length;
535
536
0
  err_length = pcre2_get_error_message (errcode, error_msg,
537
0
                                        G_N_ELEMENTS (error_msg));
538
539
0
  if (err_length <= 0)
540
0
    return NULL;
541
542
  /* The array is always filled with a trailing zero */
543
0
  g_assert ((size_t) err_length < G_N_ELEMENTS (error_msg));
544
0
  return g_memdup2 (error_msg, err_length + 1);
545
0
}
546
547
static const gchar *
548
translate_match_error (gint errcode)
549
0
{
550
0
  switch (errcode)
551
0
    {
552
0
    case PCRE2_ERROR_NOMATCH:
553
      /* not an error */
554
0
      break;
555
0
    case PCRE2_ERROR_NULL:
556
      /* NULL argument, this should not happen in GRegex */
557
0
      g_critical ("A NULL argument was passed to PCRE");
558
0
      break;
559
0
    case PCRE2_ERROR_BADOPTION:
560
0
      return "bad options";
561
0
    case PCRE2_ERROR_BADMAGIC:
562
0
      return _("corrupted object");
563
0
    case PCRE2_ERROR_NOMEMORY:
564
0
      return _("out of memory");
565
0
    case PCRE2_ERROR_NOSUBSTRING:
566
      /* not used by pcre2_match() */
567
0
      break;
568
0
    case PCRE2_ERROR_MATCHLIMIT:
569
0
    case PCRE2_ERROR_CALLOUT:
570
      /* callouts are not implemented */
571
0
      break;
572
0
    case PCRE2_ERROR_BADUTFOFFSET:
573
      /* we do not check if strings are valid */
574
0
      break;
575
0
    case PCRE2_ERROR_PARTIAL:
576
      /* not an error */
577
0
      break;
578
0
    case PCRE2_ERROR_INTERNAL:
579
0
      return _("internal error");
580
0
    case PCRE2_ERROR_DFA_UITEM:
581
0
      return _("the pattern contains items not supported for partial matching");
582
0
    case PCRE2_ERROR_DFA_UCOND:
583
0
      return _("back references as conditions are not supported for partial matching");
584
0
    case PCRE2_ERROR_DFA_WSSIZE:
585
      /* handled expanding the workspace */
586
0
      break;
587
0
    case PCRE2_ERROR_DFA_RECURSE:
588
0
    case PCRE2_ERROR_RECURSIONLIMIT:
589
0
      return _("recursion limit reached");
590
0
    case PCRE2_ERROR_BADOFFSET:
591
0
      return _("bad offset");
592
0
    case PCRE2_ERROR_RECURSELOOP:
593
0
      return _("recursion loop");
594
0
    case PCRE2_ERROR_JIT_BADOPTION:
595
      /* should not happen in GRegex since we check modes before each match */
596
0
      return _("matching mode is requested that was not compiled for JIT");
597
0
    default:
598
0
      break;
599
0
    }
600
0
  return NULL;
601
0
}
602
603
static char *
604
get_match_error_message (int errcode)
605
0
{
606
0
  const char *msg = translate_match_error (errcode);
607
0
  char *error_string;
608
609
0
  if (msg)
610
0
    return g_strdup (msg);
611
612
0
  error_string = get_pcre2_error_string (errcode);
613
614
0
  if (error_string)
615
0
    return error_string;
616
617
0
  return g_strdup (_("unknown error"));
618
0
}
619
620
static void
621
translate_compile_error (gint *errcode, const gchar **errmsg)
622
0
{
623
  /* If errcode is known we put the translatable error message in
624
   * errmsg. If errcode is unknown we put the generic
625
   * G_REGEX_ERROR_COMPILE error code in errcode.
626
   * Note that there can be more PCRE errors with the same GRegexError
627
   * and that some PCRE errors are useless for us.
628
   */
629
0
  gint original_errcode = *errcode;
630
631
0
  *errcode = -1;
632
0
  *errmsg = NULL;
633
634
0
  switch (original_errcode)
635
0
    {
636
0
    case PCRE2_ERROR_END_BACKSLASH:
637
0
      *errcode = G_REGEX_ERROR_STRAY_BACKSLASH;
638
0
      *errmsg = _("\\ at end of pattern");
639
0
      break;
640
0
    case PCRE2_ERROR_END_BACKSLASH_C:
641
0
      *errcode = G_REGEX_ERROR_MISSING_CONTROL_CHAR;
642
0
      *errmsg = _("\\c at end of pattern");
643
0
      break;
644
0
    case PCRE2_ERROR_UNKNOWN_ESCAPE:
645
0
    case PCRE2_ERROR_UNSUPPORTED_ESCAPE_SEQUENCE:
646
0
      *errcode = G_REGEX_ERROR_UNRECOGNIZED_ESCAPE;
647
0
      *errmsg = _("unrecognized character following \\");
648
0
      break;
649
0
    case PCRE2_ERROR_QUANTIFIER_OUT_OF_ORDER:
650
0
      *errcode = G_REGEX_ERROR_QUANTIFIERS_OUT_OF_ORDER;
651
0
      *errmsg = _("numbers out of order in {} quantifier");
652
0
      break;
653
0
    case PCRE2_ERROR_QUANTIFIER_TOO_BIG:
654
0
      *errcode = G_REGEX_ERROR_QUANTIFIER_TOO_BIG;
655
0
      *errmsg = _("number too big in {} quantifier");
656
0
      break;
657
0
    case PCRE2_ERROR_MISSING_SQUARE_BRACKET:
658
0
      *errcode = G_REGEX_ERROR_UNTERMINATED_CHARACTER_CLASS;
659
0
      *errmsg = _("missing terminating ] for character class");
660
0
      break;
661
0
    case PCRE2_ERROR_ESCAPE_INVALID_IN_CLASS:
662
0
      *errcode = G_REGEX_ERROR_INVALID_ESCAPE_IN_CHARACTER_CLASS;
663
0
      *errmsg = _("invalid escape sequence in character class");
664
0
      break;
665
0
    case PCRE2_ERROR_CLASS_RANGE_ORDER:
666
0
      *errcode = G_REGEX_ERROR_RANGE_OUT_OF_ORDER;
667
0
      *errmsg = _("range out of order in character class");
668
0
      break;
669
0
    case PCRE2_ERROR_QUANTIFIER_INVALID:
670
0
    case PCRE2_ERROR_INTERNAL_UNEXPECTED_REPEAT:
671
0
      *errcode = G_REGEX_ERROR_NOTHING_TO_REPEAT;
672
0
      *errmsg = _("nothing to repeat");
673
0
      break;
674
0
    case PCRE2_ERROR_INVALID_AFTER_PARENS_QUERY:
675
0
      *errcode = G_REGEX_ERROR_UNRECOGNIZED_CHARACTER;
676
0
      *errmsg = _("unrecognized character after (? or (?-");
677
0
      break;
678
0
    case PCRE2_ERROR_POSIX_CLASS_NOT_IN_CLASS:
679
0
      *errcode = G_REGEX_ERROR_POSIX_NAMED_CLASS_OUTSIDE_CLASS;
680
0
      *errmsg = _("POSIX named classes are supported only within a class");
681
0
      break;
682
0
    case PCRE2_ERROR_POSIX_NO_SUPPORT_COLLATING:
683
0
      *errcode = G_REGEX_ERROR_POSIX_COLLATING_ELEMENTS_NOT_SUPPORTED;
684
0
      *errmsg = _("POSIX collating elements are not supported");
685
0
      break;
686
0
    case PCRE2_ERROR_MISSING_CLOSING_PARENTHESIS:
687
0
    case PCRE2_ERROR_UNMATCHED_CLOSING_PARENTHESIS:
688
0
    case PCRE2_ERROR_PARENS_QUERY_R_MISSING_CLOSING:
689
0
      *errcode = G_REGEX_ERROR_UNMATCHED_PARENTHESIS;
690
0
      *errmsg = _("missing terminating )");
691
0
      break;
692
0
    case PCRE2_ERROR_BAD_SUBPATTERN_REFERENCE:
693
0
      *errcode = G_REGEX_ERROR_INEXISTENT_SUBPATTERN_REFERENCE;
694
0
      *errmsg = _("reference to non-existent subpattern");
695
0
      break;
696
0
    case PCRE2_ERROR_MISSING_COMMENT_CLOSING:
697
0
      *errcode = G_REGEX_ERROR_UNTERMINATED_COMMENT;
698
0
      *errmsg = _("missing ) after comment");
699
0
      break;
700
0
    case PCRE2_ERROR_PATTERN_TOO_LARGE:
701
0
      *errcode = G_REGEX_ERROR_EXPRESSION_TOO_LARGE;
702
0
      *errmsg = _("regular expression is too large");
703
0
      break;
704
0
    case PCRE2_ERROR_MISSING_CONDITION_CLOSING:
705
0
      *errcode = G_REGEX_ERROR_MALFORMED_CONDITION;
706
0
      *errmsg = _("malformed number or name after (?(");
707
0
      break;
708
0
    case PCRE2_ERROR_LOOKBEHIND_NOT_FIXED_LENGTH:
709
0
      *errcode = G_REGEX_ERROR_VARIABLE_LENGTH_LOOKBEHIND;
710
0
      *errmsg = _("lookbehind assertion is not fixed length");
711
0
      break;
712
0
    case PCRE2_ERROR_TOO_MANY_CONDITION_BRANCHES:
713
0
      *errcode = G_REGEX_ERROR_TOO_MANY_CONDITIONAL_BRANCHES;
714
0
      *errmsg = _("conditional group contains more than two branches");
715
0
      break;
716
0
    case PCRE2_ERROR_CONDITION_ASSERTION_EXPECTED:
717
0
      *errcode = G_REGEX_ERROR_ASSERTION_EXPECTED;
718
0
      *errmsg = _("assertion expected after (?(");
719
0
      break;
720
0
    case PCRE2_ERROR_BAD_RELATIVE_REFERENCE:
721
0
      *errcode = G_REGEX_ERROR_INVALID_RELATIVE_REFERENCE;
722
0
      *errmsg = _("a numbered reference must not be zero");
723
0
      break;
724
0
    case PCRE2_ERROR_UNKNOWN_POSIX_CLASS:
725
0
      *errcode = G_REGEX_ERROR_UNKNOWN_POSIX_CLASS_NAME;
726
0
      *errmsg = _("unknown POSIX class name");
727
0
      break;
728
0
    case PCRE2_ERROR_CODE_POINT_TOO_BIG:
729
0
    case PCRE2_ERROR_INVALID_HEXADECIMAL:
730
0
      *errcode = G_REGEX_ERROR_HEX_CODE_TOO_LARGE;
731
0
      *errmsg = _("character value in \\x{...} sequence is too large");
732
0
      break;
733
0
    case PCRE2_ERROR_LOOKBEHIND_INVALID_BACKSLASH_C:
734
0
      *errcode = G_REGEX_ERROR_SINGLE_BYTE_MATCH_IN_LOOKBEHIND;
735
0
      *errmsg = _("\\C not allowed in lookbehind assertion");
736
0
      break;
737
0
    case PCRE2_ERROR_MISSING_NAME_TERMINATOR:
738
0
      *errcode = G_REGEX_ERROR_MISSING_SUBPATTERN_NAME_TERMINATOR;
739
0
      *errmsg = _("missing terminator in subpattern name");
740
0
      break;
741
0
    case PCRE2_ERROR_DUPLICATE_SUBPATTERN_NAME:
742
0
      *errcode = G_REGEX_ERROR_DUPLICATE_SUBPATTERN_NAME;
743
0
      *errmsg = _("two named subpatterns have the same name");
744
0
      break;
745
0
    case PCRE2_ERROR_MALFORMED_UNICODE_PROPERTY:
746
0
      *errcode = G_REGEX_ERROR_MALFORMED_PROPERTY;
747
0
      *errmsg = _("malformed \\P or \\p sequence");
748
0
      break;
749
0
    case PCRE2_ERROR_UNKNOWN_UNICODE_PROPERTY:
750
0
      *errcode = G_REGEX_ERROR_UNKNOWN_PROPERTY;
751
0
      *errmsg = _("unknown property name after \\P or \\p");
752
0
      break;
753
0
    case PCRE2_ERROR_SUBPATTERN_NAME_TOO_LONG:
754
0
      *errcode = G_REGEX_ERROR_SUBPATTERN_NAME_TOO_LONG;
755
0
      *errmsg = _("subpattern name is too long (maximum 32 characters)");
756
0
      break;
757
0
    case PCRE2_ERROR_TOO_MANY_NAMED_SUBPATTERNS:
758
0
      *errcode = G_REGEX_ERROR_TOO_MANY_SUBPATTERNS;
759
0
      *errmsg = _("too many named subpatterns (maximum 10,000)");
760
0
      break;
761
0
    case PCRE2_ERROR_OCTAL_BYTE_TOO_BIG:
762
0
      *errcode = G_REGEX_ERROR_INVALID_OCTAL_VALUE;
763
0
      *errmsg = _("octal value is greater than \\377");
764
0
      break;
765
0
    case PCRE2_ERROR_DEFINE_TOO_MANY_BRANCHES:
766
0
      *errcode = G_REGEX_ERROR_TOO_MANY_BRANCHES_IN_DEFINE;
767
0
      *errmsg = _("DEFINE group contains more than one branch");
768
0
      break;
769
0
    case PCRE2_ERROR_INTERNAL_UNKNOWN_NEWLINE:
770
0
      *errcode = G_REGEX_ERROR_INCONSISTENT_NEWLINE_OPTIONS;
771
0
      *errmsg = _("inconsistent NEWLINE options");
772
0
      break;
773
0
    case PCRE2_ERROR_BACKSLASH_G_SYNTAX:
774
0
      *errcode = G_REGEX_ERROR_MISSING_BACK_REFERENCE;
775
0
      *errmsg = _("\\g is not followed by a braced, angle-bracketed, or quoted name or "
776
0
                  "number, or by a plain number");
777
0
      break;
778
#ifdef PCRE2_ERROR_MISSING_NUMBER_TERMINATOR
779
    case PCRE2_ERROR_MISSING_NUMBER_TERMINATOR:
780
      *errcode = G_REGEX_ERROR_MISSING_BACK_REFERENCE;
781
      *errmsg = _("syntax error in subpattern number (missing terminator?)");
782
      break;
783
#endif
784
0
    case PCRE2_ERROR_VERB_ARGUMENT_NOT_ALLOWED:
785
0
      *errcode = G_REGEX_ERROR_BACKTRACKING_CONTROL_VERB_ARGUMENT_FORBIDDEN;
786
0
      *errmsg = _("an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)");
787
0
      break;
788
0
    case PCRE2_ERROR_VERB_UNKNOWN:
789
0
      *errcode = G_REGEX_ERROR_UNKNOWN_BACKTRACKING_CONTROL_VERB;
790
0
      *errmsg = _("(*VERB) not recognized");
791
0
      break;
792
0
    case PCRE2_ERROR_SUBPATTERN_NUMBER_TOO_BIG:
793
0
      *errcode = G_REGEX_ERROR_NUMBER_TOO_BIG;
794
0
      *errmsg = _("number is too big");
795
0
      break;
796
0
    case PCRE2_ERROR_SUBPATTERN_NAME_EXPECTED:
797
0
      *errcode = G_REGEX_ERROR_MISSING_SUBPATTERN_NAME;
798
0
      *errmsg = _("missing subpattern name after (?&");
799
0
      break;
800
0
    case PCRE2_ERROR_SUBPATTERN_NAMES_MISMATCH:
801
0
      *errcode = G_REGEX_ERROR_EXTRA_SUBPATTERN_NAME;
802
0
      *errmsg = _("different names for subpatterns of the same number are not allowed");
803
0
      break;
804
0
    case PCRE2_ERROR_MARK_MISSING_ARGUMENT:
805
0
      *errcode = G_REGEX_ERROR_BACKTRACKING_CONTROL_VERB_ARGUMENT_REQUIRED;
806
0
      *errmsg = _("(*MARK) must have an argument");
807
0
      break;
808
0
    case PCRE2_ERROR_BACKSLASH_C_SYNTAX:
809
0
      *errcode = G_REGEX_ERROR_INVALID_CONTROL_CHAR;
810
0
      *errmsg = _( "\\c must be followed by an ASCII character");
811
0
      break;
812
0
    case PCRE2_ERROR_BACKSLASH_K_SYNTAX:
813
0
      *errcode = G_REGEX_ERROR_MISSING_NAME;
814
0
      *errmsg = _("\\k is not followed by a braced, angle-bracketed, or quoted name");
815
0
      break;
816
0
    case PCRE2_ERROR_BACKSLASH_N_IN_CLASS:
817
0
      *errcode = G_REGEX_ERROR_NOT_SUPPORTED_IN_CLASS;
818
0
      *errmsg = _("\\N is not supported in a class");
819
0
      break;
820
0
    case PCRE2_ERROR_VERB_NAME_TOO_LONG:
821
0
      *errcode = G_REGEX_ERROR_NAME_TOO_LONG;
822
0
      *errmsg = _("name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)");
823
0
      break;
824
0
    case PCRE2_ERROR_INTERNAL_CODE_OVERFLOW:
825
0
      *errcode = G_REGEX_ERROR_INTERNAL;
826
0
      *errmsg = _("code overflow");
827
0
      break;
828
0
    case PCRE2_ERROR_UNRECOGNIZED_AFTER_QUERY_P:
829
0
      *errcode = G_REGEX_ERROR_UNRECOGNIZED_CHARACTER;
830
0
      *errmsg = _("unrecognized character after (?P");
831
0
      break;
832
0
    case PCRE2_ERROR_INTERNAL_OVERRAN_WORKSPACE:
833
0
      *errcode = G_REGEX_ERROR_INTERNAL;
834
0
      *errmsg = _("overran compiling workspace");
835
0
      break;
836
0
    case PCRE2_ERROR_INTERNAL_MISSING_SUBPATTERN:
837
0
      *errcode = G_REGEX_ERROR_INTERNAL;
838
0
      *errmsg = _("previously-checked referenced subpattern not found");
839
0
      break;
840
0
    case PCRE2_ERROR_HEAP_FAILED:
841
0
    case PCRE2_ERROR_INTERNAL_PARSED_OVERFLOW:
842
0
    case PCRE2_ERROR_UNICODE_NOT_SUPPORTED:
843
0
    case PCRE2_ERROR_UNICODE_DISALLOWED_CODE_POINT:
844
0
    case PCRE2_ERROR_NO_SURROGATES_IN_UTF16:
845
0
    case PCRE2_ERROR_INTERNAL_BAD_CODE_LOOKBEHINDS:
846
0
    case PCRE2_ERROR_UNICODE_PROPERTIES_UNAVAILABLE:
847
0
    case PCRE2_ERROR_INTERNAL_STUDY_ERROR:
848
0
    case PCRE2_ERROR_UTF_IS_DISABLED:
849
0
    case PCRE2_ERROR_UCP_IS_DISABLED:
850
0
    case PCRE2_ERROR_INTERNAL_BAD_CODE_AUTO_POSSESS:
851
0
    case PCRE2_ERROR_BACKSLASH_C_LIBRARY_DISABLED:
852
0
    case PCRE2_ERROR_INTERNAL_BAD_CODE:
853
0
    case PCRE2_ERROR_INTERNAL_BAD_CODE_IN_SKIP:
854
0
      *errcode = G_REGEX_ERROR_INTERNAL;
855
0
      break;
856
0
    case PCRE2_ERROR_INVALID_SUBPATTERN_NAME:
857
0
    case PCRE2_ERROR_CLASS_INVALID_RANGE:
858
0
    case PCRE2_ERROR_ZERO_RELATIVE_REFERENCE:
859
0
    case PCRE2_ERROR_PARENTHESES_STACK_CHECK:
860
0
    case PCRE2_ERROR_LOOKBEHIND_TOO_COMPLICATED:
861
0
    case PCRE2_ERROR_CALLOUT_NUMBER_TOO_BIG:
862
0
    case PCRE2_ERROR_MISSING_CALLOUT_CLOSING:
863
0
    case PCRE2_ERROR_ESCAPE_INVALID_IN_VERB:
864
0
    case PCRE2_ERROR_NULL_PATTERN:
865
0
    case PCRE2_ERROR_BAD_OPTIONS:
866
0
    case PCRE2_ERROR_PARENTHESES_NEST_TOO_DEEP:
867
0
    case PCRE2_ERROR_BACKSLASH_O_MISSING_BRACE:
868
0
    case PCRE2_ERROR_INVALID_OCTAL:
869
0
    case PCRE2_ERROR_CALLOUT_STRING_TOO_LONG:
870
0
    case PCRE2_ERROR_BACKSLASH_U_CODE_POINT_TOO_BIG:
871
0
    case PCRE2_ERROR_MISSING_OCTAL_OR_HEX_DIGITS:
872
0
    case PCRE2_ERROR_VERSION_CONDITION_SYNTAX:
873
0
    case PCRE2_ERROR_CALLOUT_NO_STRING_DELIMITER:
874
0
    case PCRE2_ERROR_CALLOUT_BAD_STRING_DELIMITER:
875
0
    case PCRE2_ERROR_BACKSLASH_C_CALLER_DISABLED:
876
0
    case PCRE2_ERROR_QUERY_BARJX_NEST_TOO_DEEP:
877
0
    case PCRE2_ERROR_PATTERN_TOO_COMPLICATED:
878
0
    case PCRE2_ERROR_LOOKBEHIND_TOO_LONG:
879
0
    case PCRE2_ERROR_PATTERN_STRING_TOO_LONG:
880
0
    case PCRE2_ERROR_BAD_LITERAL_OPTIONS:
881
0
    default:
882
0
      *errcode = G_REGEX_ERROR_COMPILE;
883
0
      break;
884
0
    }
885
886
0
  g_assert (*errcode != -1);
887
0
}
888
889
/* GMatchInfo */
890
891
static GMatchInfo *
892
match_info_new (const GRegex     *regex,
893
                const gchar      *string,
894
                size_t            string_len,
895
                size_t            start_position,
896
                GRegexMatchFlags  match_options,
897
                gboolean          is_dfa)
898
0
{
899
0
  GMatchInfo *match_info;
900
901
0
  match_info = g_new0 (GMatchInfo, 1);
902
0
  match_info->ref_count = 1;
903
0
  match_info->regex = g_regex_ref ((GRegex *)regex);
904
0
  match_info->string = string;
905
0
  match_info->string_len = string_len;
906
0
  match_info->matches = PCRE2_ERROR_NOMATCH;
907
0
  match_info->pos = start_position;
908
0
  match_info->pos_valid = TRUE;
909
0
  match_info->match_opts =
910
0
    get_pcre2_match_options (match_options, regex->regex_compile_opts);
911
912
0
  pcre2_pattern_info (regex->pcre_re, PCRE2_INFO_CAPTURECOUNT,
913
0
                      &match_info->n_subpatterns);
914
915
0
  match_info->match_context = pcre2_match_context_create (NULL);
916
917
0
  if (is_dfa)
918
0
    {
919
      /* These values should be enough for most cases, if they are not
920
       * enough g_regex_match_all_full() will expand them. */
921
0
      match_info->n_workspace = 100;
922
0
      match_info->workspace = g_new (gint, match_info->n_workspace);
923
0
    }
924
925
0
  match_info->n_offsets = 2;
926
0
  match_info->offsets = g_new0 (gint, match_info->n_offsets);
927
  /* Set an invalid position for the previous match. */
928
0
  match_info->offsets[0] = -1;
929
0
  match_info->offsets[1] = -1;
930
931
0
  match_info->match_data = pcre2_match_data_create_from_pattern (
932
0
      match_info->regex->pcre_re,
933
0
      NULL);
934
935
0
  return match_info;
936
0
}
937
938
static gboolean
939
recalc_match_offsets (GMatchInfo *match_info,
940
                      GError     **error)
941
0
{
942
0
  PCRE2_SIZE *ovector;
943
0
  uint32_t ovector_size = 0;
944
0
  uint32_t pre_n_offset;
945
946
0
  g_assert (!IS_PCRE2_ERROR (match_info->matches));
947
948
0
  if (match_info->matches == PCRE2_ERROR_PARTIAL)
949
0
    ovector_size = 1;
950
0
  else if (match_info->matches > 0)
951
0
    ovector_size = match_info->matches;
952
953
0
  g_assert (ovector_size != 0);
954
955
0
  if (pcre2_get_ovector_count (match_info->match_data) < ovector_size)
956
0
    {
957
0
      g_set_error (error, G_REGEX_ERROR, G_REGEX_ERROR_MATCH,
958
0
                   _("Error while matching regular expression %s: %s"),
959
0
                   match_info->regex->pattern, _("code overflow"));
960
0
      return FALSE;
961
0
    }
962
963
0
  pre_n_offset = match_info->n_offsets;
964
0
  match_info->n_offsets = ovector_size * 2;
965
0
  ovector = pcre2_get_ovector_pointer (match_info->match_data);
966
967
0
  if (match_info->n_offsets != pre_n_offset)
968
0
    {
969
0
      match_info->offsets = g_realloc_n (match_info->offsets,
970
0
                                         match_info->n_offsets,
971
0
                                         sizeof (gint));
972
0
    }
973
974
0
  for (size_t i = 0; i < match_info->n_offsets; i++)
975
0
    {
976
0
      match_info->offsets[i] = (int) ovector[i];
977
0
    }
978
979
0
  return TRUE;
980
0
}
981
982
static JITStatus
983
enable_jit_with_match_options (GMatchInfo  *match_info,
984
                               uint32_t  match_options)
985
0
{
986
0
  gint retval;
987
0
  uint32_t old_jit_options, new_jit_options;
988
989
0
  if (!(match_info->regex->regex_compile_opts & G_REGEX_OPTIMIZE))
990
0
    return JIT_STATUS_DISABLED;
991
992
0
  if (match_info->regex->jit_status == JIT_STATUS_DISABLED)
993
0
    return JIT_STATUS_DISABLED;
994
995
0
  if (match_options & G_REGEX_PCRE2_JIT_UNSUPPORTED_OPTIONS)
996
0
    return JIT_STATUS_DISABLED;
997
998
0
  old_jit_options = match_info->regex->jit_options;
999
0
  new_jit_options = old_jit_options | PCRE2_JIT_COMPLETE;
1000
0
  if (match_options & PCRE2_PARTIAL_HARD)
1001
0
    new_jit_options |= PCRE2_JIT_PARTIAL_HARD;
1002
0
  if (match_options & PCRE2_PARTIAL_SOFT)
1003
0
    new_jit_options |= PCRE2_JIT_PARTIAL_SOFT;
1004
1005
  /* no new options enabled */
1006
0
  if (new_jit_options == old_jit_options)
1007
0
    {
1008
0
      g_assert (match_info->regex->jit_status != JIT_STATUS_DEFAULT);
1009
0
      return match_info->regex->jit_status;
1010
0
    }
1011
1012
0
  retval = pcre2_jit_compile (match_info->regex->pcre_re, new_jit_options);
1013
0
  if (retval == 0)
1014
0
    {
1015
0
      match_info->regex->jit_status = JIT_STATUS_ENABLED;
1016
1017
0
      match_info->regex->jit_options = new_jit_options;
1018
      /* Set min stack size for JIT to 32KiB and max to 512KiB */
1019
0
      match_info->jit_stack = pcre2_jit_stack_create (1 << 15, 1 << 19, NULL);
1020
0
      pcre2_jit_stack_assign (match_info->match_context, NULL, match_info->jit_stack);
1021
0
    }
1022
0
  else
1023
0
    {
1024
0
      match_info->regex->jit_status = JIT_STATUS_DISABLED;
1025
1026
0
      switch (retval)
1027
0
        {
1028
0
        case PCRE2_ERROR_NOMEMORY:
1029
0
          g_debug ("JIT compilation was requested with G_REGEX_OPTIMIZE, "
1030
0
                   "but JIT was unable to allocate executable memory for the "
1031
0
                   "compiler. Falling back to interpretive code.");
1032
0
          break;
1033
0
        case PCRE2_ERROR_JIT_BADOPTION:
1034
0
          g_debug ("JIT compilation was requested with G_REGEX_OPTIMIZE, "
1035
0
                   "but JIT support is not available. Falling back to "
1036
0
                   "interpretive code.");
1037
0
          break;
1038
0
        default:
1039
0
          g_debug ("JIT compilation was requested with G_REGEX_OPTIMIZE, "
1040
0
                   "but request for JIT support had unexpectedly failed (error %d). "
1041
0
                   "Falling back to interpretive code.",
1042
0
                   retval);
1043
0
          break;
1044
0
        }
1045
0
    }
1046
1047
0
  return match_info->regex->jit_status;
1048
1049
0
  g_assert_not_reached ();
1050
0
}
1051
1052
/**
1053
 * g_match_info_get_regex:
1054
 * @match_info: a #GMatchInfo
1055
 *
1056
 * Returns #GRegex object used in @match_info. It belongs to Glib
1057
 * and must not be freed. Use g_regex_ref() if you need to keep it
1058
 * after you free @match_info object.
1059
 *
1060
 * Returns: (transfer none): #GRegex object used in @match_info
1061
 *
1062
 * Since: 2.14
1063
 */
1064
GRegex *
1065
g_match_info_get_regex (const GMatchInfo *match_info)
1066
0
{
1067
0
  g_return_val_if_fail (match_info != NULL, NULL);
1068
0
  return match_info->regex;
1069
0
}
1070
1071
/**
1072
 * g_match_info_get_string:
1073
 * @match_info: a #GMatchInfo
1074
 *
1075
 * Returns the string searched with @match_info. This is the
1076
 * string passed to g_regex_match() or g_regex_replace() so
1077
 * you may not free it before calling this function.
1078
 *
1079
 * Returns: the string searched with @match_info
1080
 *
1081
 * Since: 2.14
1082
 */
1083
const gchar *
1084
g_match_info_get_string (const GMatchInfo *match_info)
1085
0
{
1086
0
  g_return_val_if_fail (match_info != NULL, NULL);
1087
0
  return match_info->string;
1088
0
}
1089
1090
/**
1091
 * g_match_info_ref:
1092
 * @match_info: a #GMatchInfo
1093
 *
1094
 * Increases reference count of @match_info by 1.
1095
 *
1096
 * Returns: @match_info
1097
 *
1098
 * Since: 2.30
1099
 */
1100
GMatchInfo       *
1101
g_match_info_ref (GMatchInfo *match_info)
1102
0
{
1103
0
  g_return_val_if_fail (match_info != NULL, NULL);
1104
0
  g_atomic_int_inc (&match_info->ref_count);
1105
0
  return match_info;
1106
0
}
1107
1108
/**
1109
 * g_match_info_unref:
1110
 * @match_info: a #GMatchInfo
1111
 *
1112
 * Decreases reference count of @match_info by 1. When reference count drops
1113
 * to zero, it frees all the memory associated with the match_info structure.
1114
 *
1115
 * Since: 2.30
1116
 */
1117
void
1118
g_match_info_unref (GMatchInfo *match_info)
1119
0
{
1120
0
  if (g_atomic_int_dec_and_test (&match_info->ref_count))
1121
0
    {
1122
0
      g_regex_unref (match_info->regex);
1123
0
      if (match_info->match_context)
1124
0
        pcre2_match_context_free (match_info->match_context);
1125
0
      if (match_info->jit_stack)
1126
0
        pcre2_jit_stack_free (match_info->jit_stack);
1127
0
      if (match_info->match_data)
1128
0
        pcre2_match_data_free (match_info->match_data);
1129
0
      g_free (match_info->offsets);
1130
0
      g_free (match_info->workspace);
1131
0
      g_free (match_info);
1132
0
    }
1133
0
}
1134
1135
/**
1136
 * g_match_info_free:
1137
 * @match_info: (nullable): a #GMatchInfo, or %NULL
1138
 *
1139
 * If @match_info is not %NULL, calls g_match_info_unref(); otherwise does
1140
 * nothing.
1141
 *
1142
 * Since: 2.14
1143
 */
1144
void
1145
g_match_info_free (GMatchInfo *match_info)
1146
1.52k
{
1147
1.52k
  if (match_info == NULL)
1148
1.52k
    return;
1149
1150
0
  g_match_info_unref (match_info);
1151
0
}
1152
1153
/**
1154
 * g_match_info_next:
1155
 * @match_info: a #GMatchInfo structure
1156
 * @error: location to store the error occurring, or %NULL to ignore errors
1157
 *
1158
 * Scans for the next match using the same parameters of the previous
1159
 * call to g_regex_match_full() or g_regex_match() that returned
1160
 * @match_info.
1161
 *
1162
 * The match is done on the string passed to the match function, so you
1163
 * cannot free it before calling this function.
1164
 *
1165
 * Returns: %TRUE is the string matched, %FALSE otherwise
1166
 *
1167
 * Since: 2.14
1168
 */
1169
gboolean
1170
g_match_info_next (GMatchInfo  *match_info,
1171
                   GError     **error)
1172
0
{
1173
0
  JITStatus jit_status;
1174
0
  gint prev_match_start;
1175
0
  gint prev_match_end;
1176
0
  uint32_t opts;
1177
1178
0
  g_return_val_if_fail (match_info != NULL, FALSE);
1179
0
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1180
1181
0
  if (!match_info->pos_valid)
1182
0
    return FALSE;
1183
1184
0
  prev_match_start = match_info->offsets[0];
1185
0
  prev_match_end = match_info->offsets[1];
1186
1187
0
  if (match_info->pos > match_info->string_len)
1188
0
    {
1189
      /* we have reached the end of the string */
1190
0
      match_info->pos_valid = FALSE;
1191
0
      match_info->matches = PCRE2_ERROR_NOMATCH;
1192
0
      return FALSE;
1193
0
    }
1194
1195
0
  opts = match_info->regex->match_opts | match_info->match_opts;
1196
1197
0
  jit_status = enable_jit_with_match_options (match_info, opts);
1198
0
  if (jit_status == JIT_STATUS_ENABLED)
1199
0
    {
1200
0
      match_info->matches = pcre2_jit_match (match_info->regex->pcre_re,
1201
0
                                             (PCRE2_SPTR8) match_info->string,
1202
0
                                             match_info->string_len,
1203
0
                                             match_info->pos,
1204
0
                                             opts,
1205
0
                                             match_info->match_data,
1206
0
                                             match_info->match_context);
1207
      /* if the JIT stack limit was reached, fall back to non-JIT matching in
1208
       * the next conditional statement */
1209
0
      if (match_info->matches == PCRE2_ERROR_JIT_STACKLIMIT)
1210
0
        {
1211
0
          g_debug ("PCRE2 JIT stack limit reached, falling back to "
1212
0
                   "non-optimized matching.");
1213
0
          opts |= PCRE2_NO_JIT;
1214
0
          jit_status = JIT_STATUS_DISABLED;
1215
0
        }
1216
0
    }
1217
1218
0
  if (jit_status != JIT_STATUS_ENABLED)
1219
0
    {
1220
0
      match_info->matches = pcre2_match (match_info->regex->pcre_re,
1221
0
                                         (PCRE2_SPTR8) match_info->string,
1222
0
                                         match_info->string_len,
1223
0
                                         match_info->pos,
1224
0
                                         opts,
1225
0
                                         match_info->match_data,
1226
0
                                         match_info->match_context);
1227
0
    }
1228
1229
0
  if (IS_PCRE2_ERROR (match_info->matches))
1230
0
    {
1231
0
      gchar *error_msg = get_match_error_message (match_info->matches);
1232
1233
0
      g_set_error (error, G_REGEX_ERROR, G_REGEX_ERROR_MATCH,
1234
0
                   _("Error while matching regular expression %s: %s"),
1235
0
                   match_info->regex->pattern, error_msg);
1236
0
      g_clear_pointer (&error_msg, g_free);
1237
0
      return FALSE;
1238
0
    }
1239
0
  else if (match_info->matches == 0)
1240
0
    {
1241
      /* info->offsets is too small. */
1242
0
      match_info->n_offsets *= 2;
1243
1244
      /* uint32_t is the type accepted by pcre2_match_data_create() */
1245
0
      g_assert (match_info->n_offsets <= UINT32_MAX);
1246
1247
0
      match_info->offsets = g_realloc_n (match_info->offsets,
1248
0
                                         match_info->n_offsets,
1249
0
                                         sizeof (gint));
1250
1251
0
      pcre2_match_data_free (match_info->match_data);
1252
0
      match_info->match_data = pcre2_match_data_create (match_info->n_offsets, NULL);
1253
1254
0
      return g_match_info_next (match_info, error);
1255
0
    }
1256
0
  else if (match_info->matches == PCRE2_ERROR_NOMATCH)
1257
0
    {
1258
      /* We're done with this match info */
1259
0
      match_info->pos_valid = FALSE;
1260
0
      return FALSE;
1261
0
    }
1262
0
  else
1263
0
    if (!recalc_match_offsets (match_info, error))
1264
0
      return FALSE;
1265
1266
  /* avoid infinite loops if the pattern is an empty string or something
1267
   * equivalent */
1268
0
  g_assert (match_info->offsets[1] >= 0);
1269
0
  if (match_info->pos == (size_t) match_info->offsets[1])
1270
0
    {
1271
0
      if (match_info->pos > match_info->string_len)
1272
0
        {
1273
          /* we have reached the end of the string */
1274
0
          match_info->pos_valid = FALSE;
1275
0
          match_info->matches = PCRE2_ERROR_NOMATCH;
1276
0
          return FALSE;
1277
0
        }
1278
0
      else if (match_info->pos > match_info->string_len)
1279
0
        {
1280
          /* we have one last empty match at the end of the string */
1281
0
          match_info->pos_valid = FALSE;
1282
0
        }
1283
0
      else
1284
0
        {
1285
0
          match_info->pos = NEXT_CHAR (match_info->regex,
1286
0
                                       &match_info->string[match_info->pos]) -
1287
0
                                       match_info->string;
1288
0
          match_info->pos_valid = TRUE;
1289
0
        }
1290
0
    }
1291
0
  else
1292
0
    {
1293
0
      g_assert (match_info->offsets[1] >= 0);
1294
0
      match_info->pos = match_info->offsets[1];
1295
0
      match_info->pos_valid = TRUE;
1296
0
    }
1297
1298
0
  g_assert (match_info->matches < 0 ||
1299
0
            (size_t) match_info->matches <= (size_t) match_info->n_subpatterns + 1);
1300
1301
  /* it's possible to get two identical matches when we are matching
1302
   * empty strings, for instance if the pattern is "(?=[A-Z0-9])" and
1303
   * the string is "RegExTest" we have:
1304
   *  - search at position 0: match from 0 to 0
1305
   *  - search at position 1: match from 3 to 3
1306
   *  - search at position 3: match from 3 to 3 (duplicate)
1307
   *  - search at position 4: match from 5 to 5
1308
   *  - search at position 5: match from 5 to 5 (duplicate)
1309
   *  - search at position 6: no match -> stop
1310
   * so we have to ignore the duplicates.
1311
   * see bug #515944: http://bugzilla.gnome.org/show_bug.cgi?id=515944 */
1312
0
  if (match_info->matches >= 0 &&
1313
0
      prev_match_start == match_info->offsets[0] &&
1314
0
      prev_match_end == match_info->offsets[1])
1315
0
    {
1316
      /* ignore this match and search the next one */
1317
0
      return g_match_info_next (match_info, error);
1318
0
    }
1319
1320
0
  return match_info->matches >= 0;
1321
0
}
1322
1323
/**
1324
 * g_match_info_matches:
1325
 * @match_info: a #GMatchInfo structure
1326
 *
1327
 * Returns whether the previous match operation succeeded.
1328
 *
1329
 * Returns: %TRUE if the previous match operation succeeded,
1330
 *   %FALSE otherwise
1331
 *
1332
 * Since: 2.14
1333
 */
1334
gboolean
1335
g_match_info_matches (const GMatchInfo *match_info)
1336
0
{
1337
0
  g_return_val_if_fail (match_info != NULL, FALSE);
1338
1339
0
  return match_info->matches >= 0;
1340
0
}
1341
1342
/**
1343
 * g_match_info_get_match_count:
1344
 * @match_info: a #GMatchInfo structure
1345
 *
1346
 * Retrieves the number of matched substrings (including substring 0,
1347
 * that is the whole matched text), so 1 is returned if the pattern
1348
 * has no substrings in it and 0 is returned if the match failed.
1349
 *
1350
 * If the last match was obtained using the DFA algorithm, that is
1351
 * using g_regex_match_all() or g_regex_match_all_full(), the retrieved
1352
 * count is not that of the number of capturing parentheses but that of
1353
 * the number of matched substrings.
1354
 *
1355
 * Returns: Number of matched substrings, or -1 if an error occurred
1356
 *
1357
 * Since: 2.14
1358
 */
1359
gint
1360
g_match_info_get_match_count (const GMatchInfo *match_info)
1361
0
{
1362
0
  g_return_val_if_fail (match_info, -1);
1363
1364
0
  if (match_info->matches == PCRE2_ERROR_NOMATCH)
1365
    /* no match */
1366
0
    return 0;
1367
0
  else if (match_info->matches < PCRE2_ERROR_NOMATCH)
1368
    /* error */
1369
0
    return -1;
1370
0
  else
1371
    /* match */
1372
0
    return match_info->matches;
1373
0
}
1374
1375
/**
1376
 * g_match_info_is_partial_match:
1377
 * @match_info: a #GMatchInfo structure
1378
 *
1379
 * Usually if the string passed to g_regex_match*() matches as far as
1380
 * it goes, but is too short to match the entire pattern, %FALSE is
1381
 * returned. There are circumstances where it might be helpful to
1382
 * distinguish this case from other cases in which there is no match.
1383
 *
1384
 * Consider, for example, an application where a human is required to
1385
 * type in data for a field with specific formatting requirements. An
1386
 * example might be a date in the form ddmmmyy, defined by the pattern
1387
 * "^\d?\d(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d\d$".
1388
 * If the application sees the user’s keystrokes one by one, and can
1389
 * check that what has been typed so far is potentially valid, it is
1390
 * able to raise an error as soon as a mistake is made.
1391
 *
1392
 * GRegex supports the concept of partial matching by means of the
1393
 * %G_REGEX_MATCH_PARTIAL_SOFT and %G_REGEX_MATCH_PARTIAL_HARD flags.
1394
 * When they are used, the return code for
1395
 * g_regex_match() or g_regex_match_full() is, as usual, %TRUE
1396
 * for a complete match, %FALSE otherwise. But, when these functions
1397
 * return %FALSE, you can check if the match was partial calling
1398
 * g_match_info_is_partial_match().
1399
 *
1400
 * The difference between %G_REGEX_MATCH_PARTIAL_SOFT and
1401
 * %G_REGEX_MATCH_PARTIAL_HARD is that when a partial match is encountered
1402
 * with %G_REGEX_MATCH_PARTIAL_SOFT, matching continues to search for a
1403
 * possible complete match, while with %G_REGEX_MATCH_PARTIAL_HARD matching
1404
 * stops at the partial match.
1405
 * When both %G_REGEX_MATCH_PARTIAL_SOFT and %G_REGEX_MATCH_PARTIAL_HARD
1406
 * are set, the latter takes precedence.
1407
 *
1408
 * There were formerly some restrictions on the pattern for partial matching.
1409
 * The restrictions no longer apply.
1410
 *
1411
 * If the match was partial g_match_info_fetch(), g_match_info_fetch_pos()
1412
 * and g_match_info_fetch_all() can be called to retrieve the text and positions
1413
 * of the entire match, i.e. only for sub expression `0`.
1414
 *
1415
 * See pcrepartial(3) for more information on partial matching.
1416
 *
1417
 * Returns: %TRUE if the match was partial, %FALSE otherwise
1418
 *
1419
 * Since: 2.14
1420
 */
1421
gboolean
1422
g_match_info_is_partial_match (const GMatchInfo *match_info)
1423
0
{
1424
0
  g_return_val_if_fail (match_info != NULL, FALSE);
1425
1426
0
  return match_info->matches == PCRE2_ERROR_PARTIAL;
1427
0
}
1428
1429
/**
1430
 * g_match_info_expand_references:
1431
 * @match_info: (nullable): a #GMatchInfo or %NULL
1432
 * @string_to_expand: the string to expand
1433
 * @error: location to store the error occurring, or %NULL to ignore errors
1434
 *
1435
 * Returns a new string containing the text in @string_to_expand with
1436
 * references and escape sequences expanded. References refer to the last
1437
 * match done with @string against @regex and have the same syntax used by
1438
 * g_regex_replace().
1439
 *
1440
 * The @string_to_expand must be UTF-8 encoded even if %G_REGEX_RAW was
1441
 * passed to g_regex_new().
1442
 *
1443
 * The backreferences are extracted from the string passed to the match
1444
 * function, so you cannot call this function after freeing the string.
1445
 *
1446
 * @match_info may be %NULL in which case @string_to_expand must not
1447
 * contain references. For instance "foo\n" does not refer to an actual
1448
 * pattern and '\n' merely will be replaced with \n character,
1449
 * while to expand "\0" (whole match) one needs the result of a match.
1450
 * Use g_regex_check_replacement() to find out whether @string_to_expand
1451
 * contains references.
1452
 *
1453
 * Returns: (nullable): the expanded string, or %NULL if an error occurred
1454
 *
1455
 * Since: 2.14
1456
 */
1457
gchar *
1458
g_match_info_expand_references (const GMatchInfo  *match_info,
1459
                                const gchar       *string_to_expand,
1460
                                GError           **error)
1461
0
{
1462
0
  GString *result;
1463
0
  GList *list;
1464
0
  GError *tmp_error = NULL;
1465
1466
0
  g_return_val_if_fail (string_to_expand != NULL, NULL);
1467
0
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
1468
1469
0
  list = split_replacement (string_to_expand, &tmp_error);
1470
0
  if (tmp_error != NULL)
1471
0
    {
1472
0
      g_propagate_error (error, tmp_error);
1473
0
      return NULL;
1474
0
    }
1475
1476
0
  if (!match_info && interpolation_list_needs_match (list))
1477
0
    {
1478
0
      g_critical ("String '%s' contains references to the match, can't "
1479
0
                  "expand references without GMatchInfo object",
1480
0
                  string_to_expand);
1481
0
      return NULL;
1482
0
    }
1483
1484
0
  result = g_string_sized_new (strlen (string_to_expand));
1485
0
  interpolate_replacement (match_info, result, list);
1486
1487
0
  g_list_free_full (list, (GDestroyNotify) free_interpolation_data);
1488
1489
0
  return g_string_free (result, FALSE);
1490
0
}
1491
1492
/**
1493
 * g_match_info_fetch:
1494
 * @match_info: #GMatchInfo structure
1495
 * @match_num: number of the sub expression
1496
 *
1497
 * Retrieves the text matching the @match_num'th capturing
1498
 * parentheses. 0 is the full text of the match, 1 is the first paren
1499
 * set, 2 the second, and so on.
1500
 *
1501
 * If @match_num is a valid sub pattern but it didn't match anything
1502
 * (e.g. sub pattern 1, matching "b" against "(a)?b") then an empty
1503
 * string is returned.
1504
 * When a partial match is reported via g_match_info_is_partial_match()
1505
 * only the full text of the match can be queried (@match_num must be `0`).
1506
 *
1507
 * If the match was obtained using the DFA algorithm, that is using
1508
 * g_regex_match_all() or g_regex_match_all_full(), the retrieved
1509
 * string is not that of a set of parentheses but that of a matched
1510
 * substring. Substrings are matched in reverse order of length, so
1511
 * 0 is the longest match.
1512
 *
1513
 * The string is fetched from the string passed to the match function,
1514
 * so you cannot call this function after freeing the string.
1515
 *
1516
 * Returns: (nullable): The matched substring, or %NULL if an error
1517
 *     occurred. You have to free the string yourself
1518
 *
1519
 * Since: 2.14
1520
 */
1521
gchar *
1522
g_match_info_fetch (const GMatchInfo *match_info,
1523
                    gint              match_num)
1524
0
{
1525
0
  gchar *match = NULL;
1526
0
  gint start, end;
1527
1528
0
  g_return_val_if_fail (match_info != NULL, NULL);
1529
0
  g_return_val_if_fail (match_num >= 0, NULL);
1530
1531
  /* match_num does not exist or it didn't matched, i.e. matching "b"
1532
   * against "(a)?b" then group 0 is empty. */
1533
0
  if (!g_match_info_fetch_pos (match_info, match_num, &start, &end))
1534
0
    match = NULL;
1535
0
  else if (start == -1)
1536
0
    match = g_strdup ("");
1537
0
  else
1538
0
    match = g_strndup (&match_info->string[start], end - start);
1539
1540
0
  return match;
1541
0
}
1542
1543
/**
1544
 * g_match_info_fetch_pos:
1545
 * @match_info: #GMatchInfo structure
1546
 * @match_num: number of the capture parenthesis
1547
 * @start_pos: (out) (optional): pointer to location where to store
1548
 *     the start position, or %NULL
1549
 * @end_pos: (out) (optional): pointer to location where to store
1550
 *     the end position (the byte after the final byte of the match), or %NULL
1551
 *
1552
 * Returns the start and end positions (in bytes) of a successfully matching 
1553
 * capture parenthesis.
1554
 * 
1555
 * Valid values for @match_num are `0` for the full text of the match,
1556
 * `1` for the first paren set, `2` for the second, and so on.
1557
 * When a partial match is reported via g_match_info_is_partial_match()
1558
 * only the full text of the match can be queried (@match_num must be `0`).
1559
 *
1560
 * As @end_pos is set to the byte after the final byte of the match (on success),
1561
 * the length of the match can be calculated as `end_pos - start_pos`.
1562
 *
1563
 * As a best practice, initialize @start_pos and @end_pos to identifiable 
1564
 * values, such as `G_MAXINT`, so that you can test if 
1565
 * `g_match_info_fetch_pos()` actually changed the value for a given 
1566
 * capture parenthesis.
1567
 *
1568
 * The parameter @match_num corresponds to a matched capture parenthesis. The 
1569
 * actual value you use for @match_num depends on the method used to generate
1570
 * @match_info. The following sections describe those methods.
1571
 * 
1572
 * ## Methods Using Non-deterministic Finite Automata Matching
1573
 *
1574
 * The methods [method@GLib.Regex.match] and [method@GLib.Regex.match_full]
1575
 * return a [struct@GLib.MatchInfo] using traditional (greedy) pattern
1576
 * matching, also known as 
1577
 * [Non-deterministic Finite Automaton](https://en.wikipedia.org/wiki/Nondeterministic_finite_automaton)
1578
 * (NFA) matching. You pass the returned `GMatchInfo` from these methods to 
1579
 * `g_match_info_fetch_pos()` to determine the start and end positions 
1580
 * of capture parentheses. The values for @match_num correspond to the capture 
1581
 * parentheses in order, with `0` corresponding to the entire matched string.
1582
 * 
1583
 * @match_num can refer to a capture parenthesis with no match. For example, 
1584
 * the string `b` matches against the pattern `(a)?b`, but the capture
1585
 * parenthesis `(a)` has no match. In this case, `g_match_info_fetch_pos()`
1586
 * returns true and sets @start_pos and @end_pos to `-1` when called with
1587
 * `match_num` as `1` (for `(a)`).
1588
 *
1589
 * For an expanded example, a regex pattern is `(a)?(.*?)the (.*)`, 
1590
 * and a candidate string is `glib regexes are the best`. In this scenario 
1591
 * there are four capture parentheses numbered 0–3: an implicit one 
1592
 * for the entire string, and three explicitly declared in the regex pattern.
1593
 *
1594
 * Given this example, the following table describes the return values 
1595
 * from `g_match_info_fetch_pos()` for various values of @match_num.
1596
 *
1597
 * `match_num` | Contents | Return value | Returned `start_pos` | Returned `end_pos`
1598
 * ----------- | -------- | ------------ | -------------------- | ------------------
1599
 * 0 | Matches entire string | True | 0 | 25
1600
 * 1 | Does not match first character | True | -1 | -1
1601
 * 2 | All text before `the ` | True | 0 | 17
1602
 * 3 | All text after `the ` | True | 21 | 25
1603
 * 4 | Capture paren out of range | False | Unchanged | Unchanged
1604
 *
1605
 * The following code sample and output implements this example.
1606
 *
1607
 * ``` { .c }
1608
 * #include <glib.h>
1609
 *
1610
 * int
1611
 * main (int argc, char *argv[])
1612
 * {
1613
 *   g_autoptr(GError) local_error = NULL;
1614
 *   const char *regex_pattern = "(a)?(.*?)the (.*)";
1615
 *   const char *test_string = "glib regexes are the best";
1616
 *   g_autoptr(GRegex) regex = NULL;
1617
 *
1618
 *   regex = g_regex_new (regex_pattern,
1619
 *                        G_REGEX_DEFAULT,
1620
 *                        G_REGEX_MATCH_DEFAULT,
1621
 *                        &local_error);
1622
 *   if (regex == NULL)
1623
 *     {
1624
 *       g_printerr ("Error creating regex: %s\n", local_error->message);
1625
 *       return 1;
1626
 *     }
1627
 *
1628
 *   g_autoptr(GMatchInfo) match_info = NULL;
1629
 *   g_regex_match (regex, test_string, G_REGEX_MATCH_DEFAULT, &match_info);
1630
 *
1631
 *   int n_matched_strings = g_match_info_get_match_count (match_info);
1632
 *
1633
 *   // Print header line
1634
 *   g_print ("match_num Contents                  Return value returned start_pos returned end_pos\n");
1635
 *
1636
 *   // Iterate over each capture paren, including one that is out of range as a demonstration.
1637
 *   for (int match_num = 0; match_num <= n_matched_strings; match_num++)
1638
 *     {
1639
 *       gboolean found_match;
1640
 *       g_autofree char *paren_string = NULL;
1641
 *       int start_pos = G_MAXINT;
1642
 *       int end_pos = G_MAXINT;
1643
 *
1644
 *       found_match = g_match_info_fetch_pos (match_info,
1645
 *                                             match_num,
1646
 *                                             &start_pos,
1647
 *                                             &end_pos);
1648
 *
1649
 *       // If no match, display N/A as the found string.
1650
 *       if (start_pos == G_MAXINT || start_pos == -1)
1651
 *         paren_string = g_strdup ("N/A");
1652
 *       else
1653
 *         paren_string = g_strndup (test_string + start_pos, end_pos - start_pos);
1654
 *
1655
 *       g_print ("%-9d %-25s %-12d %-18d %d\n", match_num, paren_string, found_match, start_pos, end_pos);
1656
 *     }
1657
 *
1658
 *   return 0;
1659
 * }
1660
 * ```
1661
 *
1662
 * ```
1663
 * match_num Contents                  Return value returned start_pos returned end_pos
1664
 * 0         glib regexes are the best 1            0                  25
1665
 * 1         N/A                       1            -1                 -1
1666
 * 2         glib regexes are          1            0                  17
1667
 * 3         best                      1            21                 25
1668
 * 4         N/A                       0            2147483647         2147483647
1669
 * ```
1670
 * ## Methods Using Deterministic Finite Automata Matching
1671
 *
1672
 * The methods [method@GLib.Regex.match_all] and 
1673
 * [method@GLib.Regex.match_all_full]
1674
 * return a `GMatchInfo` using
1675
 * [Deterministic Finite Automaton](https://en.wikipedia.org/wiki/Deterministic_finite_automaton)
1676
 * (DFA) pattern matching. This algorithm detects overlapping matches. You pass
1677
 * the returned `GMatchInfo` from these methods to `g_match_info_fetch_pos()`
1678
 * to determine the start and end positions of each overlapping match. Use the 
1679
 * method [method@GLib.MatchInfo.get_match_count] to determine the number 
1680
 * of overlapping matches.
1681
 *
1682
 * For example, a regex pattern is `<.*>`, and a candidate string is 
1683
 * `<a> <b> <c>`. In this scenario there are three implicit capture 
1684
 * parentheses: one for the entire string, one for `<a> <b>`, and one for `<a>`.
1685
 *
1686
 * Given this example, the following table describes the return values from
1687
 * `g_match_info_fetch_pos()` for various values of @match_num.
1688
 *
1689
 * `match_num` | Contents | Return value | Returned `start_pos` | Returned `end_pos`
1690
 * ----------- | -------- | ------------ | -------------------- | ------------------
1691
 * 0 | Matches entire string | True | 0 | 11
1692
 * 1 | Matches `<a> <b>` | True | 0 | 7
1693
 * 2 | Matches `<a>` | True | 0 | 3
1694
 * 3 | Capture paren out of range | False | Unchanged | Unchanged
1695
 *
1696
 * The following code sample and output implements this example.
1697
 *
1698
 * ``` { .c }
1699
 * #include <glib.h>
1700
 *
1701
 * int
1702
 * main (int argc, char *argv[])
1703
 * {
1704
 *   g_autoptr(GError) local_error = NULL;
1705
 *   const char *regex_pattern = "<.*>";
1706
 *   const char *test_string = "<a> <b> <c>";
1707
 *   g_autoptr(GRegex) regex = NULL;
1708
 * 
1709
 *   regex = g_regex_new (regex_pattern,
1710
 *                        G_REGEX_DEFAULT,
1711
 *                        G_REGEX_MATCH_DEFAULT,
1712
 *                        &local_error);
1713
 *   if (regex == NULL)
1714
 *     {
1715
 *       g_printerr ("Error creating regex: %s\n", local_error->message);
1716
 *       return -1;
1717
 *     }
1718
 *
1719
 *   g_autoptr(GMatchInfo) match_info = NULL;
1720
 *   g_regex_match_all (regex, test_string, G_REGEX_MATCH_DEFAULT, &match_info);
1721
 *
1722
 *   int n_matched_strings = g_match_info_get_match_count (match_info);
1723
 *
1724
 *   // Print header line 
1725
 *   g_print ("match_num Contents                  Return value returned start_pos returned end_pos\n");
1726
 * 
1727
 *   // Iterate over each capture paren, including one that is out of range as a demonstration.
1728
 *   for (int match_num = 0; match_num <= n_matched_strings; match_num++)
1729
 *     {
1730
 *       gboolean found_match;
1731
 *       g_autofree char *paren_string = NULL;
1732
 *       int start_pos = G_MAXINT;
1733
 *       int end_pos = G_MAXINT;
1734
 *
1735
 *       found_match = g_match_info_fetch_pos (match_info, match_num, &start_pos, &end_pos);
1736
 *
1737
 *       // If no match, display N/A as the found string.
1738
 *       if (start_pos == G_MAXINT || start_pos == -1)
1739
 *         paren_string = g_strdup ("N/A");
1740
 *       else
1741
 *         paren_string = g_strndup (test_string + start_pos, end_pos - start_pos);
1742
 *
1743
 *       g_print ("%-9d %-25s %-12d %-18d %d\n", match_num, paren_string, found_match, start_pos, end_pos);
1744
 *     }
1745
 *
1746
 *   return 0;
1747
 * }
1748
 * ```
1749
 *
1750
 * ```
1751
 * match_num Contents                  Return value returned start_pos returned end_pos
1752
 * 0         <a> <b> <c>               1            0                  11
1753
 * 1         <a> <b>                   1            0                  7
1754
 * 2         <a>                       1            0                  3
1755
 * 3         N/A                       0            2147483647         2147483647
1756
 * ```
1757
 *
1758
 * Returns: True if @match_num is within range, false otherwise. If
1759
 *   the capture paren has a match, @start_pos and @end_pos contain the 
1760
 *   start and end positions (in bytes) of the matching substring. If the 
1761
 *   capture paren has no match, @start_pos and @end_pos are `-1`. If 
1762
 *   @match_num is out of range, @start_pos and @end_pos are left unchanged.
1763
 *
1764
 * Since: 2.14
1765
 */
1766
gboolean
1767
g_match_info_fetch_pos (const GMatchInfo *match_info,
1768
                        gint              match_num,
1769
                        gint             *start_pos,
1770
                        gint             *end_pos)
1771
0
{
1772
0
  size_t match_num_unsigned;
1773
0
  gint matches;
1774
1775
0
  g_return_val_if_fail (match_info != NULL, FALSE);
1776
0
  g_return_val_if_fail (match_num >= 0, FALSE);
1777
1778
0
  match_num_unsigned = (size_t) match_num;
1779
1780
  /* check whether there was an error */
1781
0
  if (match_info->matches == PCRE2_ERROR_PARTIAL)
1782
0
    {
1783
0
      if (match_num_unsigned >= 1)
1784
0
        return FALSE;
1785
0
      matches = 1;
1786
0
    }
1787
0
  else
1788
0
    {
1789
0
      matches = match_info->matches;
1790
0
      if (matches < 0)
1791
0
        return FALSE;
1792
      /* make sure the sub expression number they're requesting is less than
1793
       * the total number of sub expressions in the regex. When matching all
1794
       * (g_regex_match_all()), also compare against the number of matches */
1795
0
      if (match_num_unsigned >= MAX ((size_t) match_info->n_subpatterns + 1, (size_t) matches))
1796
0
        return FALSE;
1797
0
    }
1798
1799
0
  if (start_pos != NULL)
1800
0
    *start_pos = (match_num_unsigned < (size_t) matches) ? match_info->offsets[2 * match_num_unsigned] : -1;
1801
1802
0
  if (end_pos != NULL)
1803
0
    *end_pos = (match_num_unsigned < (size_t) matches) ? match_info->offsets[2 * match_num_unsigned + 1] : -1;
1804
1805
0
  return TRUE;
1806
0
}
1807
1808
/*
1809
 * Returns number of first matched subpattern with name @name.
1810
 * There may be more than one in case when DUPNAMES is used,
1811
 * and not all subpatterns with that name match;
1812
 * pcre2_substring_number_from_name() does not work in that case.
1813
 */
1814
static gint
1815
get_matched_substring_number (const GMatchInfo *match_info,
1816
                              const gchar      *name)
1817
0
{
1818
0
  gint entrysize;
1819
0
  PCRE2_SPTR first, last;
1820
0
  guchar *entry;
1821
1822
0
  if (!(match_info->regex->pcre2_compile_opts & PCRE2_DUPNAMES))
1823
0
    return pcre2_substring_number_from_name (match_info->regex->pcre_re, (PCRE2_SPTR8) name);
1824
1825
  /* This code is analogous to code from pcre2_substring.c:
1826
   * pcre2_substring_get_byname() */
1827
0
  entrysize = pcre2_substring_nametable_scan (match_info->regex->pcre_re,
1828
0
                                              (PCRE2_SPTR8) name,
1829
0
                                              &first,
1830
0
                                              &last);
1831
1832
0
  if (entrysize <= 0)
1833
0
    return entrysize;
1834
1835
0
  for (entry = (guchar*) first; entry <= (guchar*) last; entry += entrysize)
1836
0
    {
1837
0
      guint n = (entry[0] << 8) + entry[1];
1838
0
      if (n * 2 < match_info->n_offsets && match_info->offsets[n * 2] >= 0)
1839
0
        return n;
1840
0
    }
1841
1842
0
  return (first[0] << 8) + first[1];
1843
0
}
1844
1845
/**
1846
 * g_match_info_fetch_named:
1847
 * @match_info: #GMatchInfo structure
1848
 * @name: name of the subexpression
1849
 *
1850
 * Retrieves the text matching the capturing parentheses named @name.
1851
 *
1852
 * If @name is a valid sub pattern name but it didn't match anything
1853
 * (e.g. sub pattern `"X"`, matching `"b"` against `"(?P<X>a)?b"`)
1854
 * then an empty string is returned.
1855
 *
1856
 * The string is fetched from the string passed to the match function,
1857
 * so you cannot call this function after freeing the string.
1858
 *
1859
 * Returns: (nullable): The matched substring, or %NULL if an error
1860
 *     occurred. You have to free the string yourself
1861
 *
1862
 * Since: 2.14
1863
 */
1864
gchar *
1865
g_match_info_fetch_named (const GMatchInfo *match_info,
1866
                          const gchar      *name)
1867
0
{
1868
0
  gint num;
1869
1870
0
  g_return_val_if_fail (match_info != NULL, NULL);
1871
0
  g_return_val_if_fail (name != NULL, NULL);
1872
1873
0
  num = get_matched_substring_number (match_info, name);
1874
0
  if (num < 0)
1875
0
    return NULL;
1876
0
  else
1877
0
    return g_match_info_fetch (match_info, num);
1878
0
}
1879
1880
/**
1881
 * g_match_info_fetch_named_pos:
1882
 * @match_info: #GMatchInfo structure
1883
 * @name: name of the subexpression
1884
 * @start_pos: (out) (optional): pointer to location where to store
1885
 *     the start position, or %NULL
1886
 * @end_pos: (out) (optional): pointer to location where to store
1887
 *     the end position (the byte after the final byte of the match), or %NULL
1888
 *
1889
 * Retrieves the position in bytes of the capturing parentheses named @name.
1890
 *
1891
 * If @name is a valid sub pattern name but it didn't match anything
1892
 * (e.g. sub pattern `"X"`, matching `"b"` against `"(?P<X>a)?b"`)
1893
 * then @start_pos and @end_pos are set to -1 and %TRUE is returned.
1894
 *
1895
 * As @end_pos is set to the byte after the final byte of the match (on success),
1896
 * the length of the match can be calculated as `end_pos - start_pos`.
1897
 *
1898
 * Returns: %TRUE if the position was fetched, %FALSE otherwise.
1899
 *     If the position cannot be fetched, @start_pos and @end_pos
1900
 *     are left unchanged.
1901
 *
1902
 * Since: 2.14
1903
 */
1904
gboolean
1905
g_match_info_fetch_named_pos (const GMatchInfo *match_info,
1906
                              const gchar      *name,
1907
                              gint             *start_pos,
1908
                              gint             *end_pos)
1909
0
{
1910
0
  gint num;
1911
1912
0
  g_return_val_if_fail (match_info != NULL, FALSE);
1913
0
  g_return_val_if_fail (name != NULL, FALSE);
1914
1915
0
  num = get_matched_substring_number (match_info, name);
1916
0
  if (num < 0)
1917
0
    return FALSE;
1918
1919
0
  return g_match_info_fetch_pos (match_info, num, start_pos, end_pos);
1920
0
}
1921
1922
/**
1923
 * g_match_info_fetch_all:
1924
 * @match_info: a #GMatchInfo structure
1925
 *
1926
 * Bundles up pointers to each of the matching substrings from a match
1927
 * and stores them in an array of gchar pointers. The first element in
1928
 * the returned array is the match number 0, i.e. the entire matched
1929
 * text.
1930
 *
1931
 * If a sub pattern didn't match anything (e.g. sub pattern 1, matching
1932
 * "b" against "(a)?b") then an empty string is inserted.
1933
 *
1934
 * When a partial match is reported via g_match_info_is_partial_match()
1935
 * only the full text of the match will be returned, i.e. an array of size 1.
1936
 *
1937
 * If the last match was obtained using the DFA algorithm, that is using
1938
 * g_regex_match_all() or g_regex_match_all_full(), the retrieved
1939
 * strings are not that matched by sets of parentheses but that of the
1940
 * matched substring. Substrings are matched in reverse order of length,
1941
 * so the first one is the longest match.
1942
 *
1943
 * The strings are fetched from the string passed to the match function,
1944
 * so you cannot call this function after freeing the string.
1945
 *
1946
 * Returns: (transfer full): a %NULL-terminated array of gchar *
1947
 *     pointers.  It must be freed using g_strfreev(). If the previous
1948
 *     match failed %NULL is returned
1949
 *
1950
 * Since: 2.14
1951
 */
1952
gchar **
1953
g_match_info_fetch_all (const GMatchInfo *match_info)
1954
0
{
1955
0
  gchar **result;
1956
0
  gint matches, i;
1957
1958
0
  g_return_val_if_fail (match_info != NULL, NULL);
1959
1960
0
  matches = (match_info->matches == PCRE2_ERROR_PARTIAL) ? 1 : match_info->matches;
1961
0
  if (matches < 0)
1962
0
    return NULL;
1963
1964
0
  result = g_new (gchar *, matches + 1);
1965
0
  for (i = 0; i < matches; i++)
1966
0
    result[i] = g_match_info_fetch (match_info, i);
1967
0
  result[i] = NULL;
1968
1969
0
  return result;
1970
0
}
1971
1972
1973
/* GRegex */
1974
1975
G_DEFINE_QUARK (g-regex-error-quark, g_regex_error)
1976
1977
/**
1978
 * g_regex_ref:
1979
 * @regex: a #GRegex
1980
 *
1981
 * Increases reference count of @regex by 1.
1982
 *
1983
 * Returns: @regex
1984
 *
1985
 * Since: 2.14
1986
 */
1987
GRegex *
1988
g_regex_ref (GRegex *regex)
1989
0
{
1990
0
  g_return_val_if_fail (regex != NULL, NULL);
1991
0
  g_atomic_int_inc (&regex->ref_count);
1992
0
  return regex;
1993
0
}
1994
1995
/**
1996
 * g_regex_unref:
1997
 * @regex: a #GRegex
1998
 *
1999
 * Decreases reference count of @regex by 1. When reference count drops
2000
 * to zero, it frees all the memory associated with the regex structure.
2001
 *
2002
 * Since: 2.14
2003
 */
2004
void
2005
g_regex_unref (GRegex *regex)
2006
0
{
2007
0
  g_return_if_fail (regex != NULL);
2008
2009
0
  if (g_atomic_int_dec_and_test (&regex->ref_count))
2010
0
    {
2011
0
      g_free (regex->pattern);
2012
0
      if (regex->pcre_re != NULL)
2013
0
        pcre2_code_free (regex->pcre_re);
2014
0
      g_free (regex);
2015
0
    }
2016
0
}
2017
2018
static pcre2_code * regex_compile (const gchar  *pattern,
2019
                                   uint32_t      compile_options,
2020
                                   uint32_t      newline_options,
2021
                                   uint32_t      bsr_options,
2022
                                   GError      **error);
2023
2024
static uint32_t get_pcre2_inline_compile_options (pcre2_code *re,
2025
                                                  uint32_t    compile_options);
2026
2027
/**
2028
 * g_regex_new:
2029
 * @pattern: the regular expression
2030
 * @compile_options: compile options for the regular expression, or 0
2031
 * @match_options: match options for the regular expression, or 0
2032
 * @error: return location for a #GError
2033
 *
2034
 * Compiles the regular expression to an internal form, and does
2035
 * the initial setup of the #GRegex structure.
2036
 *
2037
 * Returns: (nullable): a #GRegex structure or %NULL if an error occurred. Call
2038
 *   g_regex_unref() when you are done with it
2039
 *
2040
 * Since: 2.14
2041
 */
2042
GRegex *
2043
g_regex_new (const gchar         *pattern,
2044
             GRegexCompileFlags   compile_options,
2045
             GRegexMatchFlags     match_options,
2046
             GError             **error)
2047
0
{
2048
0
  GRegex *regex;
2049
0
  pcre2_code *re;
2050
0
  static gsize initialised = 0;
2051
0
  uint32_t pcre_compile_options;
2052
0
  uint32_t pcre_match_options;
2053
0
  uint32_t newline_options;
2054
0
  uint32_t bsr_options;
2055
2056
0
  g_return_val_if_fail (pattern != NULL, NULL);
2057
0
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
2058
0
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
2059
0
  g_return_val_if_fail ((compile_options & ~(G_REGEX_COMPILE_MASK |
2060
0
                                             G_REGEX_JAVASCRIPT_COMPAT)) == 0, NULL);
2061
0
G_GNUC_END_IGNORE_DEPRECATIONS
2062
0
  g_return_val_if_fail ((match_options & ~G_REGEX_MATCH_MASK) == 0, NULL);
2063
2064
0
  if (g_once_init_enter (&initialised))
2065
0
    {
2066
0
      int supports_utf8;
2067
2068
0
      pcre2_config (PCRE2_CONFIG_UNICODE, &supports_utf8);
2069
0
      if (!supports_utf8)
2070
0
        g_critical (_("PCRE library is compiled without UTF8 support"));
2071
2072
0
      g_once_init_leave (&initialised, supports_utf8 ? 1 : 2);
2073
0
    }
2074
2075
0
  if (G_UNLIKELY (initialised != 1))
2076
0
    {
2077
0
      g_set_error_literal (error, G_REGEX_ERROR, G_REGEX_ERROR_COMPILE, 
2078
0
                           _("PCRE library is compiled with incompatible options"));
2079
0
      return NULL;
2080
0
    }
2081
2082
0
  pcre_compile_options = get_pcre2_compile_options (compile_options);
2083
0
  pcre_match_options = get_pcre2_match_options (match_options, compile_options);
2084
2085
0
  newline_options = get_pcre2_newline_match_options (match_options);
2086
0
  if (newline_options == 0)
2087
0
    newline_options = get_pcre2_newline_compile_options (compile_options);
2088
2089
0
  if (newline_options == 0)
2090
0
    {
2091
0
      g_set_error (error, G_REGEX_ERROR, G_REGEX_ERROR_INCONSISTENT_NEWLINE_OPTIONS,
2092
0
                   "Invalid newline flags");
2093
0
      return NULL;
2094
0
    }
2095
2096
0
  bsr_options = get_pcre2_bsr_match_options (match_options);
2097
0
  if (!bsr_options)
2098
0
    bsr_options = get_pcre2_bsr_compile_options (compile_options);
2099
2100
0
  re = regex_compile (pattern, pcre_compile_options,
2101
0
                      newline_options, bsr_options, error);
2102
0
  if (re == NULL)
2103
0
    return NULL;
2104
2105
0
  pcre_compile_options |=
2106
0
    get_pcre2_inline_compile_options (re, pcre_compile_options);
2107
2108
0
  regex = g_new0 (GRegex, 1);
2109
0
  regex->ref_count = 1;
2110
0
  regex->pattern = g_strdup (pattern);
2111
0
  regex->pcre_re = re;
2112
0
  regex->pcre2_compile_opts = pcre_compile_options;
2113
0
  regex->regex_compile_opts = compile_options;
2114
0
  regex->match_opts = pcre_match_options;
2115
0
  regex->orig_match_opts = match_options;
2116
2117
0
  return regex;
2118
0
}
2119
2120
static pcre2_code *
2121
regex_compile (const gchar  *pattern,
2122
               uint32_t      compile_options,
2123
               uint32_t      newline_options,
2124
               uint32_t      bsr_options,
2125
               GError      **error)
2126
0
{
2127
0
  pcre2_code *re;
2128
0
  pcre2_compile_context *context;
2129
0
  const gchar *errmsg;
2130
0
  PCRE2_SIZE erroffset;
2131
0
  gint errcode;
2132
2133
0
  context = pcre2_compile_context_create (NULL);
2134
2135
  /* set newline options */
2136
0
  if (pcre2_set_newline (context, newline_options) != 0)
2137
0
    {
2138
0
      g_set_error (error, G_REGEX_ERROR,
2139
0
                   G_REGEX_ERROR_INCONSISTENT_NEWLINE_OPTIONS,
2140
0
                   "Invalid newline flags");
2141
0
      pcre2_compile_context_free (context);
2142
0
      return NULL;
2143
0
    }
2144
2145
  /* set bsr options */
2146
0
  if (pcre2_set_bsr (context, bsr_options) != 0)
2147
0
    {
2148
0
      g_set_error (error, G_REGEX_ERROR,
2149
0
                   G_REGEX_ERROR_INCONSISTENT_NEWLINE_OPTIONS,
2150
0
                   "Invalid BSR flags");
2151
0
      pcre2_compile_context_free (context);
2152
0
      return NULL;
2153
0
    }
2154
2155
  /* In case UTF-8 mode is used, also set PCRE2_NO_UTF_CHECK */
2156
0
  if (compile_options & PCRE2_UTF)
2157
0
    compile_options |= PCRE2_NO_UTF_CHECK;
2158
2159
0
  compile_options |= PCRE2_UCP;
2160
2161
  /* compile the pattern */
2162
0
  re = pcre2_compile ((PCRE2_SPTR8) pattern,
2163
0
                      PCRE2_ZERO_TERMINATED,
2164
0
                      compile_options,
2165
0
                      &errcode,
2166
0
                      &erroffset,
2167
0
                      context);
2168
0
  pcre2_compile_context_free (context);
2169
2170
  /* if the compilation failed, set the error member and return
2171
   * immediately */
2172
0
  if (re == NULL)
2173
0
    {
2174
0
      GError *tmp_error;
2175
0
      gchar *offset_str;
2176
0
      gchar *pcre2_errmsg = NULL;
2177
0
      int original_errcode;
2178
2179
      /* Translate the PCRE error code to GRegexError and use a translated
2180
       * error message if possible */
2181
0
      original_errcode = errcode;
2182
0
      translate_compile_error (&errcode, &errmsg);
2183
2184
0
      if (!errmsg)
2185
0
        {
2186
0
          errmsg = _("unknown error");
2187
0
          pcre2_errmsg = get_pcre2_error_string (original_errcode);
2188
0
        }
2189
2190
      /* PCRE uses byte offsets but we want to show character offsets */
2191
0
      erroffset = g_utf8_pointer_to_offset (pattern, &pattern[erroffset]);
2192
2193
0
      offset_str = g_strdup_printf ("%" G_GSIZE_FORMAT, erroffset);
2194
0
      tmp_error = g_error_new (G_REGEX_ERROR, errcode,
2195
0
                               _("Error while compiling regular expression ‘%s’ "
2196
0
                                 "at char %s: %s"),
2197
0
                               pattern, offset_str,
2198
0
                               pcre2_errmsg ? pcre2_errmsg : errmsg);
2199
0
      g_propagate_error (error, tmp_error);
2200
0
      g_free (offset_str);
2201
0
      g_clear_pointer (&pcre2_errmsg, g_free);
2202
2203
0
      return NULL;
2204
0
    }
2205
2206
0
  return re;
2207
0
}
2208
2209
static uint32_t
2210
get_pcre2_inline_compile_options (pcre2_code *re,
2211
                                  uint32_t    compile_options)
2212
0
{
2213
0
  uint32_t pcre_compile_options;
2214
0
  uint32_t nonpcre_compile_options;
2215
2216
  /* For options set at the beginning of the pattern, pcre puts them into
2217
   * compile options, e.g. "(?i)foo" will make the pcre structure store
2218
   * PCRE2_CASELESS even though it wasn't explicitly given for compilation. */
2219
0
  nonpcre_compile_options = compile_options & G_REGEX_COMPILE_NONPCRE_MASK;
2220
0
  pcre2_pattern_info (re, PCRE2_INFO_ALLOPTIONS, &pcre_compile_options);
2221
0
  compile_options = pcre_compile_options & G_REGEX_PCRE2_COMPILE_MASK;
2222
0
  compile_options |= nonpcre_compile_options;
2223
2224
0
  if (!(compile_options & PCRE2_DUPNAMES))
2225
0
    {
2226
0
      uint32_t jchanged = 0;
2227
0
      pcre2_pattern_info (re, PCRE2_INFO_JCHANGED, &jchanged);
2228
0
      if (jchanged)
2229
0
        compile_options |= PCRE2_DUPNAMES;
2230
0
    }
2231
2232
0
  return compile_options;
2233
0
}
2234
2235
/**
2236
 * g_regex_get_pattern:
2237
 * @regex: a #GRegex structure
2238
 *
2239
 * Gets the pattern string associated with @regex, i.e. a copy of
2240
 * the string passed to g_regex_new().
2241
 *
2242
 * Returns: the pattern of @regex
2243
 *
2244
 * Since: 2.14
2245
 */
2246
const gchar *
2247
g_regex_get_pattern (const GRegex *regex)
2248
0
{
2249
0
  g_return_val_if_fail (regex != NULL, NULL);
2250
2251
0
  return regex->pattern;
2252
0
}
2253
2254
/**
2255
 * g_regex_get_max_backref:
2256
 * @regex: a #GRegex
2257
 *
2258
 * Returns the number of the highest back reference
2259
 * in the pattern, or 0 if the pattern does not contain
2260
 * back references.
2261
 *
2262
 * Returns: the number of the highest back reference
2263
 *
2264
 * Since: 2.14
2265
 */
2266
gint
2267
g_regex_get_max_backref (const GRegex *regex)
2268
0
{
2269
0
  uint32_t value;
2270
2271
0
  pcre2_pattern_info (regex->pcre_re, PCRE2_INFO_BACKREFMAX, &value);
2272
2273
0
  return value;
2274
0
}
2275
2276
/**
2277
 * g_regex_get_capture_count:
2278
 * @regex: a #GRegex
2279
 *
2280
 * Returns the number of capturing subpatterns in the pattern.
2281
 *
2282
 * Returns: the number of capturing subpatterns
2283
 *
2284
 * Since: 2.14
2285
 */
2286
gint
2287
g_regex_get_capture_count (const GRegex *regex)
2288
0
{
2289
0
  uint32_t value;
2290
2291
0
  pcre2_pattern_info (regex->pcre_re, PCRE2_INFO_CAPTURECOUNT, &value);
2292
2293
0
  return value;
2294
0
}
2295
2296
/**
2297
 * g_regex_get_has_cr_or_lf:
2298
 * @regex: a #GRegex structure
2299
 *
2300
 * Checks whether the pattern contains explicit CR or LF references.
2301
 *
2302
 * Returns: %TRUE if the pattern contains explicit CR or LF references
2303
 *
2304
 * Since: 2.34
2305
 */
2306
gboolean
2307
g_regex_get_has_cr_or_lf (const GRegex *regex)
2308
0
{
2309
0
  uint32_t value;
2310
2311
0
  pcre2_pattern_info (regex->pcre_re, PCRE2_INFO_HASCRORLF, &value);
2312
2313
0
  return !!value;
2314
0
}
2315
2316
/**
2317
 * g_regex_get_max_lookbehind:
2318
 * @regex: a #GRegex structure
2319
 *
2320
 * Gets the number of characters in the longest lookbehind assertion in the
2321
 * pattern. This information is useful when doing multi-segment matching using
2322
 * the partial matching facilities.
2323
 *
2324
 * Returns: the number of characters in the longest lookbehind assertion.
2325
 *
2326
 * Since: 2.38
2327
 */
2328
gint
2329
g_regex_get_max_lookbehind (const GRegex *regex)
2330
0
{
2331
0
  uint32_t max_lookbehind;
2332
2333
0
  pcre2_pattern_info (regex->pcre_re, PCRE2_INFO_MAXLOOKBEHIND,
2334
0
                      &max_lookbehind);
2335
2336
0
  return max_lookbehind;
2337
0
}
2338
2339
/**
2340
 * g_regex_get_compile_flags:
2341
 * @regex: a #GRegex
2342
 *
2343
 * Returns the compile options that @regex was created with.
2344
 *
2345
 * Depending on the version of PCRE that is used, this may or may not
2346
 * include flags set by option expressions such as `(?i)` found at the
2347
 * top-level within the compiled pattern.
2348
 *
2349
 * Returns: flags from #GRegexCompileFlags
2350
 *
2351
 * Since: 2.26
2352
 */
2353
GRegexCompileFlags
2354
g_regex_get_compile_flags (const GRegex *regex)
2355
0
{
2356
0
  GRegexCompileFlags extra_flags;
2357
0
  uint32_t info_value;
2358
2359
0
  g_return_val_if_fail (regex != NULL, 0);
2360
2361
  /* Preserve original G_REGEX_OPTIMIZE */
2362
0
  extra_flags = (regex->regex_compile_opts & G_REGEX_OPTIMIZE);
2363
2364
  /* Also include the newline options */
2365
0
  pcre2_pattern_info (regex->pcre_re, PCRE2_INFO_NEWLINE, &info_value);
2366
0
  switch (info_value)
2367
0
    {
2368
0
    case PCRE2_NEWLINE_ANYCRLF:
2369
0
      extra_flags |= G_REGEX_NEWLINE_ANYCRLF;
2370
0
      break;
2371
0
    case PCRE2_NEWLINE_CRLF:
2372
0
      extra_flags |= G_REGEX_NEWLINE_CRLF;
2373
0
      break;
2374
0
    case PCRE2_NEWLINE_LF:
2375
0
      extra_flags |= G_REGEX_NEWLINE_LF;
2376
0
      break;
2377
0
    case PCRE2_NEWLINE_CR:
2378
0
      extra_flags |= G_REGEX_NEWLINE_CR;
2379
0
      break;
2380
0
    default:
2381
0
      break;
2382
0
    }
2383
2384
  /* Also include the bsr options */
2385
0
  pcre2_pattern_info (regex->pcre_re, PCRE2_INFO_BSR, &info_value);
2386
0
  switch (info_value)
2387
0
    {
2388
0
    case PCRE2_BSR_ANYCRLF:
2389
0
      extra_flags |= G_REGEX_BSR_ANYCRLF;
2390
0
      break;
2391
0
    default:
2392
0
      break;
2393
0
    }
2394
2395
0
  return g_regex_compile_flags_from_pcre2 (regex->pcre2_compile_opts) | extra_flags;
2396
0
}
2397
2398
/**
2399
 * g_regex_get_match_flags:
2400
 * @regex: a #GRegex
2401
 *
2402
 * Returns the match options that @regex was created with.
2403
 *
2404
 * Returns: flags from #GRegexMatchFlags
2405
 *
2406
 * Since: 2.26
2407
 */
2408
GRegexMatchFlags
2409
g_regex_get_match_flags (const GRegex *regex)
2410
0
{
2411
0
  uint32_t flags;
2412
2413
0
  g_return_val_if_fail (regex != NULL, 0);
2414
2415
0
  flags = g_regex_match_flags_from_pcre2 (regex->match_opts);
2416
0
  flags |= (regex->orig_match_opts & G_REGEX_MATCH_NEWLINE_MASK);
2417
0
  flags |= (regex->orig_match_opts & (G_REGEX_MATCH_BSR_ANY | G_REGEX_MATCH_BSR_ANYCRLF));
2418
2419
0
  return flags;
2420
0
}
2421
2422
/**
2423
 * g_regex_match_simple:
2424
 * @pattern: the regular expression
2425
 * @string: the string to scan for matches
2426
 * @compile_options: compile options for the regular expression, or 0
2427
 * @match_options: match options, or 0
2428
 *
2429
 * Scans for a match in @string for @pattern.
2430
 *
2431
 * This function is equivalent to g_regex_match() but it does not
2432
 * require to compile the pattern with g_regex_new(), avoiding some
2433
 * lines of code when you need just to do a match without extracting
2434
 * substrings, capture counts, and so on.
2435
 *
2436
 * If this function is to be called on the same @pattern more than
2437
 * once, it's more efficient to compile the pattern once with
2438
 * g_regex_new() and then use g_regex_match().
2439
 *
2440
 * Returns: %TRUE if the string matched, %FALSE otherwise
2441
 *
2442
 * Since: 2.14
2443
 */
2444
gboolean
2445
g_regex_match_simple (const gchar        *pattern,
2446
                      const gchar        *string,
2447
                      GRegexCompileFlags  compile_options,
2448
                      GRegexMatchFlags    match_options)
2449
0
{
2450
0
  GRegex *regex;
2451
0
  gboolean result;
2452
2453
0
  regex = g_regex_new (pattern, compile_options, G_REGEX_MATCH_DEFAULT, NULL);
2454
0
  if (!regex)
2455
0
    return FALSE;
2456
0
  result = g_regex_match_full (regex, string, -1, 0, match_options, NULL, NULL);
2457
0
  g_regex_unref (regex);
2458
0
  return result;
2459
0
}
2460
2461
/**
2462
 * g_regex_match:
2463
 * @regex: a #GRegex structure from g_regex_new()
2464
 * @string: the string to scan for matches
2465
 * @match_options: match options
2466
 * @match_info: (out) (optional): pointer to location where to store
2467
 *     the #GMatchInfo, or %NULL if you do not need it
2468
 *
2469
 * Scans for a match in @string for the pattern in @regex.
2470
 * The @match_options are combined with the match options specified
2471
 * when the @regex structure was created, letting you have more
2472
 * flexibility in reusing #GRegex structures.
2473
 *
2474
 * Unless %G_REGEX_RAW is specified in the options, @string must be valid UTF-8.
2475
 *
2476
 * A #GMatchInfo structure, used to get information on the match,
2477
 * is stored in @match_info if not %NULL. Note that if @match_info
2478
 * is not %NULL then it is created even if the function returns %FALSE,
2479
 * i.e. you must free it regardless if regular expression actually matched.
2480
 *
2481
 * To retrieve all the non-overlapping matches of the pattern in
2482
 * string you can use g_match_info_next().
2483
 *
2484
 * |[<!-- language="C" --> 
2485
 * static void
2486
 * print_uppercase_words (const gchar *string)
2487
 * {
2488
 *   // Print all uppercase-only words.
2489
 *   GRegex *regex;
2490
 *   GMatchInfo *match_info;
2491
 *  
2492
 *   regex = g_regex_new ("[A-Z]+", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL);
2493
 *   g_regex_match (regex, string, 0, &match_info);
2494
 *   while (g_match_info_matches (match_info))
2495
 *     {
2496
 *       gchar *word = g_match_info_fetch (match_info, 0);
2497
 *       g_print ("Found: %s\n", word);
2498
 *       g_free (word);
2499
 *       g_match_info_next (match_info, NULL);
2500
 *     }
2501
 *   g_match_info_free (match_info);
2502
 *   g_regex_unref (regex);
2503
 * }
2504
 * ]|
2505
 *
2506
 * @string is not copied and is used in #GMatchInfo internally. If
2507
 * you use any #GMatchInfo method (except g_match_info_free()) after
2508
 * freeing or modifying @string then the behaviour is undefined.
2509
 *
2510
 * Returns: %TRUE is the string matched, %FALSE otherwise
2511
 *
2512
 * Since: 2.14
2513
 */
2514
gboolean
2515
g_regex_match (const GRegex      *regex,
2516
               const gchar       *string,
2517
               GRegexMatchFlags   match_options,
2518
               GMatchInfo       **match_info)
2519
1.52k
{
2520
1.52k
  return g_regex_match_full (regex, string, -1, 0, match_options,
2521
1.52k
                             match_info, NULL);
2522
1.52k
}
2523
2524
/**
2525
 * g_regex_match_full:
2526
 * @regex: a #GRegex structure from g_regex_new()
2527
 * @string: the string to scan for matches
2528
 * @string_len: the length of @string, in bytes, or -1 if @string is nul-terminated
2529
 * @start_position: starting index of the string to match, in bytes
2530
 * @match_options: match options
2531
 * @match_info: (out) (optional): pointer to location where to store
2532
 *     the #GMatchInfo, or %NULL if you do not need it
2533
 * @error: location to store the error occurring, or %NULL to ignore errors
2534
 *
2535
 * Scans for a match in @string for the pattern in @regex.
2536
 * The @match_options are combined with the match options specified
2537
 * when the @regex structure was created, letting you have more
2538
 * flexibility in reusing #GRegex structures.
2539
 *
2540
 * Setting @start_position differs from just passing over a shortened
2541
 * string and setting %G_REGEX_MATCH_NOTBOL in the case of a pattern
2542
 * that begins with any kind of lookbehind assertion, such as "\b".
2543
 *
2544
 * Unless %G_REGEX_RAW is specified in the options, @string must be valid UTF-8.
2545
 *
2546
 * A #GMatchInfo structure, used to get information on the match, is
2547
 * stored in @match_info if not %NULL. Note that if @match_info is
2548
 * not %NULL then it is created even if the function returns %FALSE,
2549
 * i.e. you must free it regardless if regular expression actually
2550
 * matched.
2551
 *
2552
 * @string is not copied and is used in #GMatchInfo internally. If
2553
 * you use any #GMatchInfo method (except g_match_info_free()) after
2554
 * freeing or modifying @string then the behaviour is undefined.
2555
 *
2556
 * To retrieve all the non-overlapping matches of the pattern in
2557
 * string you can use g_match_info_next().
2558
 *
2559
 * |[<!-- language="C" --> 
2560
 * static void
2561
 * print_uppercase_words (const gchar *string)
2562
 * {
2563
 *   // Print all uppercase-only words.
2564
 *   GRegex *regex;
2565
 *   GMatchInfo *match_info;
2566
 *   GError *error = NULL;
2567
 *   
2568
 *   regex = g_regex_new ("[A-Z]+", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL);
2569
 *   g_regex_match_full (regex, string, -1, 0, 0, &match_info, &error);
2570
 *   while (g_match_info_matches (match_info))
2571
 *     {
2572
 *       gchar *word = g_match_info_fetch (match_info, 0);
2573
 *       g_print ("Found: %s\n", word);
2574
 *       g_free (word);
2575
 *       g_match_info_next (match_info, &error);
2576
 *     }
2577
 *   g_match_info_free (match_info);
2578
 *   g_regex_unref (regex);
2579
 *   if (error != NULL)
2580
 *     {
2581
 *       g_printerr ("Error while matching: %s\n", error->message);
2582
 *       g_error_free (error);
2583
 *     }
2584
 * }
2585
 * ]|
2586
 *
2587
 * Returns: %TRUE is the string matched, %FALSE otherwise
2588
 *
2589
 * Since: 2.14
2590
 */
2591
gboolean
2592
g_regex_match_full (const GRegex      *regex,
2593
                    const gchar       *string,
2594
                    gssize             string_len,
2595
                    gint               start_position,
2596
                    GRegexMatchFlags   match_options,
2597
                    GMatchInfo       **match_info,
2598
                    GError           **error)
2599
1.52k
{
2600
1.52k
  GMatchInfo *info;
2601
1.52k
  gboolean match_ok;
2602
1.52k
  size_t string_len_unsigned;
2603
2604
1.52k
  g_return_val_if_fail (regex != NULL, FALSE);
2605
1.52k
  g_return_val_if_fail (string != NULL, FALSE);
2606
0
  g_return_val_if_fail (start_position >= 0, FALSE);
2607
0
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
2608
0
  g_return_val_if_fail ((match_options & ~G_REGEX_MATCH_MASK) == 0, FALSE);
2609
2610
0
  string_len_unsigned = (string_len < 0) ? strlen (string) : (size_t) string_len;
2611
2612
0
  info = match_info_new (regex, string, string_len_unsigned, start_position,
2613
0
                         match_options, FALSE);
2614
0
  match_ok = g_match_info_next (info, error);
2615
0
  if (match_info != NULL)
2616
0
    *match_info = info;
2617
0
  else
2618
0
    g_match_info_free (info);
2619
2620
0
  return match_ok;
2621
0
}
2622
2623
/**
2624
 * g_regex_match_all:
2625
 * @regex: a #GRegex structure from g_regex_new()
2626
 * @string: the string to scan for matches
2627
 * @match_options: match options
2628
 * @match_info: (out) (optional): pointer to location where to store
2629
 *     the #GMatchInfo, or %NULL if you do not need it
2630
 *
2631
 * Using the standard algorithm for regular expression matching only
2632
 * the longest match in the string is retrieved. This function uses
2633
 * a different algorithm so it can retrieve all the possible matches.
2634
 * For more documentation see g_regex_match_all_full().
2635
 *
2636
 * A #GMatchInfo structure, used to get information on the match, is
2637
 * stored in @match_info if not %NULL. Note that if @match_info is
2638
 * not %NULL then it is created even if the function returns %FALSE,
2639
 * i.e. you must free it regardless if regular expression actually
2640
 * matched.
2641
 *
2642
 * @string is not copied and is used in #GMatchInfo internally. If
2643
 * you use any #GMatchInfo method (except g_match_info_free()) after
2644
 * freeing or modifying @string then the behaviour is undefined.
2645
 *
2646
 * Returns: %TRUE is the string matched, %FALSE otherwise
2647
 *
2648
 * Since: 2.14
2649
 */
2650
gboolean
2651
g_regex_match_all (const GRegex      *regex,
2652
                   const gchar       *string,
2653
                   GRegexMatchFlags   match_options,
2654
                   GMatchInfo       **match_info)
2655
0
{
2656
0
  return g_regex_match_all_full (regex, string, -1, 0, match_options,
2657
0
                                 match_info, NULL);
2658
0
}
2659
2660
/**
2661
 * g_regex_match_all_full:
2662
 * @regex: a #GRegex structure from g_regex_new()
2663
 * @string: the string to scan for matches
2664
 * @string_len: the length of @string, in bytes, or -1 if @string is nul-terminated
2665
 * @start_position: starting index of the string to match, in bytes
2666
 * @match_options: match options
2667
 * @match_info: (out) (optional): pointer to location where to store
2668
 *     the #GMatchInfo, or %NULL if you do not need it
2669
 * @error: location to store the error occurring, or %NULL to ignore errors
2670
 *
2671
 * Using the standard algorithm for regular expression matching only
2672
 * the longest match in the @string is retrieved, it is not possible
2673
 * to obtain all the available matches. For instance matching
2674
 * `"<a> <b> <c>"` against the pattern `"<.*>"`
2675
 * you get `"<a> <b> <c>"`.
2676
 *
2677
 * This function uses a different algorithm (called DFA, i.e. deterministic
2678
 * finite automaton), so it can retrieve all the possible matches, all
2679
 * starting at the same point in the string. For instance matching
2680
 * `"<a> <b> <c>"` against the pattern `"<.*>"`
2681
 * you would obtain three matches: `"<a> <b> <c>"`,
2682
 * `"<a> <b>"` and `"<a>"`.
2683
 *
2684
 * The number of matched strings is retrieved using
2685
 * g_match_info_get_match_count(). To obtain the matched strings and
2686
 * their position you can use, respectively, g_match_info_fetch() and
2687
 * g_match_info_fetch_pos(). Note that the strings are returned in
2688
 * reverse order of length; that is, the longest matching string is
2689
 * given first.
2690
 *
2691
 * Note that the DFA algorithm is slower than the standard one and it
2692
 * is not able to capture substrings, so backreferences do not work.
2693
 *
2694
 * Setting @start_position differs from just passing over a shortened
2695
 * string and setting %G_REGEX_MATCH_NOTBOL in the case of a pattern
2696
 * that begins with any kind of lookbehind assertion, such as "\b".
2697
 *
2698
 * Unless %G_REGEX_RAW is specified in the options, @string must be valid UTF-8.
2699
 *
2700
 * A #GMatchInfo structure, used to get information on the match, is
2701
 * stored in @match_info if not %NULL. Note that if @match_info is
2702
 * not %NULL then it is created even if the function returns %FALSE,
2703
 * i.e. you must free it regardless if regular expression actually
2704
 * matched.
2705
 *
2706
 * @string is not copied and is used in #GMatchInfo internally. If
2707
 * you use any #GMatchInfo method (except g_match_info_free()) after
2708
 * freeing or modifying @string then the behaviour is undefined.
2709
 *
2710
 * Returns: %TRUE is the string matched, %FALSE otherwise
2711
 *
2712
 * Since: 2.14
2713
 */
2714
gboolean
2715
g_regex_match_all_full (const GRegex      *regex,
2716
                        const gchar       *string,
2717
                        gssize             string_len,
2718
                        gint               start_position,
2719
                        GRegexMatchFlags   match_options,
2720
                        GMatchInfo       **match_info,
2721
                        GError           **error)
2722
0
{
2723
0
  GMatchInfo *info;
2724
0
  gboolean done;
2725
0
  pcre2_code *pcre_re;
2726
0
  gboolean retval;
2727
0
  uint32_t newline_options;
2728
0
  uint32_t bsr_options;
2729
0
  size_t string_len_unsigned;
2730
2731
0
  g_return_val_if_fail (regex != NULL, FALSE);
2732
0
  g_return_val_if_fail (string != NULL, FALSE);
2733
0
  g_return_val_if_fail (start_position >= 0, FALSE);
2734
0
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
2735
0
  g_return_val_if_fail ((match_options & ~G_REGEX_MATCH_MASK) == 0, FALSE);
2736
2737
0
  string_len_unsigned = (string_len < 0) ? strlen (string) : (size_t) string_len;
2738
2739
0
  newline_options = get_pcre2_newline_match_options (match_options);
2740
0
  if (!newline_options)
2741
0
    newline_options = get_pcre2_newline_compile_options (regex->regex_compile_opts);
2742
2743
0
  bsr_options = get_pcre2_bsr_match_options (match_options);
2744
0
  if (!bsr_options)
2745
0
    bsr_options = get_pcre2_bsr_compile_options (regex->regex_compile_opts);
2746
2747
  /* For PCRE2 we need to turn off PCRE2_NO_AUTO_POSSESS, which is an
2748
   * optimization for normal regex matching, but results in omitting some
2749
   * shorter matches here, and an observable behaviour change.
2750
   *
2751
   * DFA matching is rather niche, and very rarely used according to
2752
   * codesearch.debian.net, so don't bother caching the recompiled RE. */
2753
0
  pcre_re = regex_compile (regex->pattern,
2754
0
                           regex->pcre2_compile_opts | PCRE2_NO_AUTO_POSSESS,
2755
0
                           newline_options, bsr_options, error);
2756
0
  if (pcre_re == NULL)
2757
0
    return FALSE;
2758
2759
0
  info = match_info_new (regex, string, string_len_unsigned, start_position,
2760
0
                         match_options, TRUE);
2761
2762
0
  done = FALSE;
2763
0
  while (!done)
2764
0
    {
2765
0
      done = TRUE;
2766
0
      info->matches = pcre2_dfa_match (pcre_re,
2767
0
                                       (PCRE2_SPTR8) info->string, info->string_len,
2768
0
                                       info->pos,
2769
0
                                       (regex->match_opts | info->match_opts),
2770
0
                                       info->match_data,
2771
0
                                       info->match_context,
2772
0
                                       info->workspace, info->n_workspace);
2773
0
      if (info->matches == PCRE2_ERROR_DFA_WSSIZE)
2774
0
        {
2775
          /* info->workspace is too small. */
2776
0
          info->n_workspace *= 2;
2777
0
          info->workspace = g_realloc_n (info->workspace,
2778
0
                                         info->n_workspace,
2779
0
                                         sizeof (gint));
2780
0
          done = FALSE;
2781
0
        }
2782
0
      else if (info->matches == 0)
2783
0
        {
2784
          /* info->offsets is too small. */
2785
0
          info->n_offsets *= 2;
2786
2787
          /* uint32_t is the type accepted by pcre2_match_data_create() */
2788
0
          g_assert (info->n_offsets <= UINT32_MAX);
2789
2790
0
          info->offsets = g_realloc_n (info->offsets,
2791
0
                                       info->n_offsets,
2792
0
                                       sizeof (gint));
2793
0
          pcre2_match_data_free (info->match_data);
2794
0
          info->match_data = pcre2_match_data_create (info->n_offsets, NULL);
2795
0
          done = FALSE;
2796
0
        }
2797
0
      else if (IS_PCRE2_ERROR (info->matches))
2798
0
        {
2799
0
          gchar *error_msg = get_match_error_message (info->matches);
2800
2801
0
          g_set_error (error, G_REGEX_ERROR, G_REGEX_ERROR_MATCH,
2802
0
                       _("Error while matching regular expression %s: %s"),
2803
0
                       regex->pattern, error_msg);
2804
0
          g_clear_pointer (&error_msg, g_free);
2805
0
        }
2806
0
      else if (info->matches != PCRE2_ERROR_NOMATCH)
2807
0
        {
2808
0
          if (!recalc_match_offsets (info, error))
2809
0
            info->matches = PCRE2_ERROR_NOMATCH;
2810
0
        }
2811
0
    }
2812
2813
0
  pcre2_code_free (pcre_re);
2814
2815
  /* don’t assert that (info->matches <= info->n_subpatterns + 1) as that only
2816
   * holds true for a single match, rather than matching all */
2817
2818
  /* set info->pos_valid to false so that a call to g_match_info_next() fails. */
2819
0
  info->pos_valid = FALSE;
2820
0
  retval = info->matches >= 0;
2821
2822
0
  if (match_info != NULL)
2823
0
    *match_info = info;
2824
0
  else
2825
0
    g_match_info_free (info);
2826
2827
0
  return retval;
2828
0
}
2829
2830
/**
2831
 * g_regex_get_string_number:
2832
 * @regex: #GRegex structure
2833
 * @name: name of the subexpression
2834
 *
2835
 * Retrieves the number of the subexpression named @name.
2836
 *
2837
 * Returns: The number of the subexpression or -1 if @name
2838
 *   does not exists
2839
 *
2840
 * Since: 2.14
2841
 */
2842
gint
2843
g_regex_get_string_number (const GRegex *regex,
2844
                           const gchar  *name)
2845
0
{
2846
0
  gint num;
2847
2848
0
  g_return_val_if_fail (regex != NULL, -1);
2849
0
  g_return_val_if_fail (name != NULL, -1);
2850
2851
0
  num = pcre2_substring_number_from_name (regex->pcre_re, (PCRE2_SPTR8) name);
2852
0
  if (num == PCRE2_ERROR_NOSUBSTRING)
2853
0
    num = -1;
2854
2855
0
  return num;
2856
0
}
2857
2858
/**
2859
 * g_regex_split_simple:
2860
 * @pattern: the regular expression
2861
 * @string: the string to scan for matches
2862
 * @compile_options: compile options for the regular expression, or 0
2863
 * @match_options: match options, or 0
2864
 *
2865
 * Breaks the string on the pattern, and returns an array of
2866
 * the tokens. If the pattern contains capturing parentheses,
2867
 * then the text for each of the substrings will also be returned.
2868
 * If the pattern does not match anywhere in the string, then the
2869
 * whole string is returned as the first token.
2870
 *
2871
 * This function is equivalent to g_regex_split() but it does
2872
 * not require to compile the pattern with g_regex_new(), avoiding
2873
 * some lines of code when you need just to do a split without
2874
 * extracting substrings, capture counts, and so on.
2875
 *
2876
 * If this function is to be called on the same @pattern more than
2877
 * once, it's more efficient to compile the pattern once with
2878
 * g_regex_new() and then use g_regex_split().
2879
 *
2880
 * As a special case, the result of splitting the empty string ""
2881
 * is an empty vector, not a vector containing a single string.
2882
 * The reason for this special case is that being able to represent
2883
 * an empty vector is typically more useful than consistent handling
2884
 * of empty elements. If you do need to represent empty elements,
2885
 * you'll need to check for the empty string before calling this
2886
 * function.
2887
 *
2888
 * A pattern that can match empty strings splits @string into
2889
 * separate characters wherever it matches the empty string between
2890
 * characters. For example splitting "ab c" using as a separator
2891
 * "\s*", you will get "a", "b" and "c".
2892
 *
2893
 * Returns: (transfer full): a %NULL-terminated array of strings. Free
2894
 * it using g_strfreev()
2895
 *
2896
 * Since: 2.14
2897
 **/
2898
gchar **
2899
g_regex_split_simple (const gchar        *pattern,
2900
                      const gchar        *string,
2901
                      GRegexCompileFlags  compile_options,
2902
                      GRegexMatchFlags    match_options)
2903
0
{
2904
0
  GRegex *regex;
2905
0
  gchar **result;
2906
2907
0
  regex = g_regex_new (pattern, compile_options, 0, NULL);
2908
0
  if (!regex)
2909
0
    return NULL;
2910
2911
0
  result = g_regex_split_full (regex, string, -1, 0, match_options, 0, NULL);
2912
0
  g_regex_unref (regex);
2913
0
  return result;
2914
0
}
2915
2916
/**
2917
 * g_regex_split:
2918
 * @regex: a #GRegex structure
2919
 * @string: the string to split with the pattern
2920
 * @match_options: match time option flags
2921
 *
2922
 * Breaks the string on the pattern, and returns an array of the tokens.
2923
 * If the pattern contains capturing parentheses, then the text for each
2924
 * of the substrings will also be returned. If the pattern does not match
2925
 * anywhere in the string, then the whole string is returned as the first
2926
 * token.
2927
 *
2928
 * As a special case, the result of splitting the empty string "" is an
2929
 * empty vector, not a vector containing a single string. The reason for
2930
 * this special case is that being able to represent an empty vector is
2931
 * typically more useful than consistent handling of empty elements. If
2932
 * you do need to represent empty elements, you'll need to check for the
2933
 * empty string before calling this function.
2934
 *
2935
 * A pattern that can match empty strings splits @string into separate
2936
 * characters wherever it matches the empty string between characters.
2937
 * For example splitting "ab c" using as a separator "\s*", you will get
2938
 * "a", "b" and "c".
2939
 *
2940
 * Returns: (transfer full): a %NULL-terminated gchar ** array. Free
2941
 * it using g_strfreev()
2942
 *
2943
 * Since: 2.14
2944
 **/
2945
gchar **
2946
g_regex_split (const GRegex     *regex,
2947
               const gchar      *string,
2948
               GRegexMatchFlags  match_options)
2949
0
{
2950
0
  return g_regex_split_full (regex, string, -1, 0,
2951
0
                             match_options, 0, NULL);
2952
0
}
2953
2954
/**
2955
 * g_regex_split_full:
2956
 * @regex: a #GRegex structure
2957
 * @string: the string to split with the pattern
2958
 * @string_len: the length of @string, in bytes, or -1 if @string is nul-terminated
2959
 * @start_position: starting index of the string to match, in bytes
2960
 * @match_options: match time option flags
2961
 * @max_tokens: the maximum number of tokens to split @string into.
2962
 *   If this is less than 1, the string is split completely
2963
 * @error: return location for a #GError
2964
 *
2965
 * Breaks the string on the pattern, and returns an array of the tokens.
2966
 * If the pattern contains capturing parentheses, then the text for each
2967
 * of the substrings will also be returned. If the pattern does not match
2968
 * anywhere in the string, then the whole string is returned as the first
2969
 * token.
2970
 *
2971
 * As a special case, the result of splitting the empty string "" is an
2972
 * empty vector, not a vector containing a single string. The reason for
2973
 * this special case is that being able to represent an empty vector is
2974
 * typically more useful than consistent handling of empty elements. If
2975
 * you do need to represent empty elements, you'll need to check for the
2976
 * empty string before calling this function.
2977
 *
2978
 * A pattern that can match empty strings splits @string into separate
2979
 * characters wherever it matches the empty string between characters.
2980
 * For example splitting "ab c" using as a separator "\s*", you will get
2981
 * "a", "b" and "c".
2982
 *
2983
 * Setting @start_position differs from just passing over a shortened
2984
 * string and setting %G_REGEX_MATCH_NOTBOL in the case of a pattern
2985
 * that begins with any kind of lookbehind assertion, such as "\b".
2986
 *
2987
 * Returns: (transfer full): a %NULL-terminated gchar ** array. Free
2988
 * it using g_strfreev()
2989
 *
2990
 * Since: 2.14
2991
 **/
2992
gchar **
2993
g_regex_split_full (const GRegex      *regex,
2994
                    const gchar       *string,
2995
                    gssize             string_len,
2996
                    gint               start_position,
2997
                    GRegexMatchFlags   match_options,
2998
                    gint               max_tokens,
2999
                    GError           **error)
3000
0
{
3001
0
  GError *tmp_error = NULL;
3002
0
  GMatchInfo *match_info;
3003
0
  GList *list, *last;
3004
0
  gint i;
3005
0
  gint token_count;
3006
0
  gboolean match_ok;
3007
  /* position of the last separator. */
3008
0
  size_t last_separator_end;
3009
  /* was the last match 0 bytes long? */
3010
0
  gboolean last_match_is_empty;
3011
  /* the returned array of char **s */
3012
0
  gchar **string_list;
3013
0
  size_t string_len_unsigned, start_position_unsigned;
3014
3015
0
  g_return_val_if_fail (regex != NULL, NULL);
3016
0
  g_return_val_if_fail (string != NULL, NULL);
3017
0
  g_return_val_if_fail (start_position >= 0, NULL);
3018
0
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
3019
0
  g_return_val_if_fail ((match_options & ~G_REGEX_MATCH_MASK) == 0, NULL);
3020
3021
0
  if (max_tokens <= 0)
3022
0
    max_tokens = G_MAXINT;
3023
3024
0
  string_len_unsigned = (string_len < 0) ? strlen (string) : (size_t) string_len;
3025
0
  start_position_unsigned = (size_t) start_position;  /* see pre-condition above */
3026
3027
  /* zero-length string */
3028
0
  if (string_len_unsigned - start_position_unsigned == 0)
3029
0
    return g_new0 (gchar *, 1);
3030
3031
0
  if (max_tokens == 1)
3032
0
    {
3033
0
      string_list = g_new0 (gchar *, 2);
3034
0
      string_list[0] = g_strndup (&string[start_position_unsigned],
3035
0
                                  string_len_unsigned - start_position_unsigned);
3036
0
      return string_list;
3037
0
    }
3038
3039
0
  list = NULL;
3040
0
  token_count = 0;
3041
0
  last_separator_end = start_position_unsigned;
3042
0
  last_match_is_empty = FALSE;
3043
3044
0
  match_ok = g_regex_match_full (regex, string, string_len_unsigned, start_position_unsigned,
3045
0
                                 match_options, &match_info, &tmp_error);
3046
3047
0
  while (tmp_error == NULL)
3048
0
    {
3049
0
      if (match_ok)
3050
0
        {
3051
0
          last_match_is_empty =
3052
0
                    (match_info->offsets[0] == match_info->offsets[1]);
3053
3054
          /* we need to skip empty separators at the same position of the end
3055
           * of another separator. e.g. the string is "a b" and the separator
3056
           * is " *", so from 1 to 2 we have a match and at position 2 we have
3057
           * an empty match. */
3058
0
          g_assert (match_info->offsets[1] >= 0);
3059
0
          if (last_separator_end != (size_t) match_info->offsets[1])
3060
0
            {
3061
0
              gchar *token;
3062
0
              gint match_count;
3063
3064
0
              token = g_strndup (string + last_separator_end,
3065
0
                                 match_info->offsets[0] - last_separator_end);
3066
0
              list = g_list_prepend (list, token);
3067
0
              token_count++;
3068
3069
              /* if there were substrings, these need to be added to
3070
               * the list. */
3071
0
              match_count = g_match_info_get_match_count (match_info);
3072
0
              if (match_count > 1)
3073
0
                {
3074
0
                  for (i = 1; i < match_count; i++)
3075
0
                    list = g_list_prepend (list, g_match_info_fetch (match_info, i));
3076
0
                }
3077
0
            }
3078
0
        }
3079
0
      else
3080
0
        {
3081
          /* if there was no match, copy to end of string. */
3082
0
          if (!last_match_is_empty)
3083
0
            {
3084
0
              gchar *token = g_strndup (string + last_separator_end,
3085
0
                                        match_info->string_len - last_separator_end);
3086
0
              list = g_list_prepend (list, token);
3087
0
            }
3088
          /* no more tokens, end the loop. */
3089
0
          break;
3090
0
        }
3091
3092
      /* -1 to leave room for the last part. */
3093
0
      if (token_count >= max_tokens - 1)
3094
0
        {
3095
          /* we have reached the maximum number of tokens, so we copy
3096
           * the remaining part of the string. */
3097
0
          if (last_match_is_empty)
3098
0
            {
3099
              /* the last match was empty, so we have moved one char
3100
               * after the real position to avoid empty matches at the
3101
               * same position. */
3102
0
              const char *prev_char = PREV_CHAR (regex, &string[match_info->pos]);
3103
0
              g_assert (prev_char >= string);
3104
0
              match_info->pos = prev_char - string;
3105
0
              match_info->pos_valid = TRUE;
3106
0
            }
3107
3108
0
          g_assert (match_info->pos_valid);
3109
3110
          /* the if is needed in the case we have terminated the available
3111
           * tokens, but we are at the end of the string, so there are no
3112
           * characters left to copy. */
3113
0
          if (string_len_unsigned > match_info->pos)
3114
0
            {
3115
0
              gchar *token = g_strndup (string + match_info->pos,
3116
0
                                        string_len_unsigned - match_info->pos);
3117
0
              list = g_list_prepend (list, token);
3118
0
            }
3119
          /* end the loop. */
3120
0
          break;
3121
0
        }
3122
3123
0
      last_separator_end = match_info->pos;
3124
0
      if (last_match_is_empty)
3125
        /* if the last match was empty, g_match_info_next() has moved
3126
         * forward to avoid infinite loops, but we still need to copy that
3127
         * character. */
3128
0
        last_separator_end = PREV_CHAR (regex, &string[last_separator_end]) - string;
3129
3130
0
      match_ok = g_match_info_next (match_info, &tmp_error);
3131
0
    }
3132
0
  g_match_info_free (match_info);
3133
0
  if (tmp_error != NULL)
3134
0
    {
3135
0
      g_propagate_error (error, tmp_error);
3136
0
      g_list_free_full (list, g_free);
3137
0
      return NULL;
3138
0
    }
3139
3140
0
  string_list = g_new (gchar *, g_list_length (list) + 1);
3141
0
  i = 0;
3142
0
  for (last = g_list_last (list); last; last = g_list_previous (last))
3143
0
    string_list[i++] = last->data;
3144
0
  string_list[i] = NULL;
3145
0
  g_list_free (list);
3146
3147
0
  return string_list;
3148
0
}
3149
3150
enum
3151
{
3152
  REPL_TYPE_STRING,
3153
  REPL_TYPE_CHARACTER,
3154
  REPL_TYPE_SYMBOLIC_REFERENCE,
3155
  REPL_TYPE_NUMERIC_REFERENCE,
3156
  REPL_TYPE_CHANGE_CASE
3157
};
3158
3159
typedef enum
3160
{
3161
  CHANGE_CASE_NONE         = 1 << 0,
3162
  CHANGE_CASE_UPPER        = 1 << 1,
3163
  CHANGE_CASE_LOWER        = 1 << 2,
3164
  CHANGE_CASE_UPPER_SINGLE = 1 << 3,
3165
  CHANGE_CASE_LOWER_SINGLE = 1 << 4,
3166
  CHANGE_CASE_SINGLE_MASK  = CHANGE_CASE_UPPER_SINGLE | CHANGE_CASE_LOWER_SINGLE,
3167
  CHANGE_CASE_LOWER_MASK   = CHANGE_CASE_LOWER | CHANGE_CASE_LOWER_SINGLE,
3168
  CHANGE_CASE_UPPER_MASK   = CHANGE_CASE_UPPER | CHANGE_CASE_UPPER_SINGLE
3169
} G_GNUC_FLAG_ENUM ChangeCase;
3170
3171
struct _InterpolationData
3172
{
3173
  gchar     *text;
3174
  gint       type;
3175
  gint       num;
3176
  gchar      c;
3177
  ChangeCase change_case;
3178
};
3179
3180
static void
3181
free_interpolation_data (InterpolationData *data)
3182
0
{
3183
0
  g_free (data->text);
3184
0
  g_free (data);
3185
0
}
3186
3187
static const gchar *
3188
expand_escape (const gchar        *replacement,
3189
               const gchar        *p,
3190
               InterpolationData  *data,
3191
               GError            **error)
3192
0
{
3193
0
  const gchar *q, *r;
3194
0
  gint x, d, h, i;
3195
0
  const gchar *error_detail;
3196
0
  gint base = 0;
3197
0
  GError *tmp_error = NULL;
3198
3199
0
  p++;
3200
0
  switch (*p)
3201
0
    {
3202
0
    case 't':
3203
0
      p++;
3204
0
      data->c = '\t';
3205
0
      data->type = REPL_TYPE_CHARACTER;
3206
0
      break;
3207
0
    case 'n':
3208
0
      p++;
3209
0
      data->c = '\n';
3210
0
      data->type = REPL_TYPE_CHARACTER;
3211
0
      break;
3212
0
    case 'v':
3213
0
      p++;
3214
0
      data->c = '\v';
3215
0
      data->type = REPL_TYPE_CHARACTER;
3216
0
      break;
3217
0
    case 'r':
3218
0
      p++;
3219
0
      data->c = '\r';
3220
0
      data->type = REPL_TYPE_CHARACTER;
3221
0
      break;
3222
0
    case 'f':
3223
0
      p++;
3224
0
      data->c = '\f';
3225
0
      data->type = REPL_TYPE_CHARACTER;
3226
0
      break;
3227
0
    case 'a':
3228
0
      p++;
3229
0
      data->c = '\a';
3230
0
      data->type = REPL_TYPE_CHARACTER;
3231
0
      break;
3232
0
    case 'b':
3233
0
      p++;
3234
0
      data->c = '\b';
3235
0
      data->type = REPL_TYPE_CHARACTER;
3236
0
      break;
3237
0
    case '\\':
3238
0
      p++;
3239
0
      data->c = '\\';
3240
0
      data->type = REPL_TYPE_CHARACTER;
3241
0
      break;
3242
0
    case 'x':
3243
0
      p++;
3244
0
      x = 0;
3245
0
      if (*p == '{')
3246
0
        {
3247
0
          p++;
3248
0
          do
3249
0
            {
3250
0
              h = g_ascii_xdigit_value (*p);
3251
0
              if (h < 0)
3252
0
                {
3253
0
                  error_detail = _("hexadecimal digit or “}” expected");
3254
0
                  goto error;
3255
0
                }
3256
0
              x = x * 16 + h;
3257
0
              p++;
3258
0
            }
3259
0
          while (*p != '}');
3260
0
          p++;
3261
0
        }
3262
0
      else
3263
0
        {
3264
0
          for (i = 0; i < 2; i++)
3265
0
            {
3266
0
              h = g_ascii_xdigit_value (*p);
3267
0
              if (h < 0)
3268
0
                {
3269
0
                  error_detail = _("hexadecimal digit expected");
3270
0
                  goto error;
3271
0
                }
3272
0
              x = x * 16 + h;
3273
0
              p++;
3274
0
            }
3275
0
        }
3276
0
      data->type = REPL_TYPE_STRING;
3277
0
      data->text = g_new0 (gchar, 8);
3278
0
      g_unichar_to_utf8 (x, data->text);
3279
0
      break;
3280
0
    case 'l':
3281
0
      p++;
3282
0
      data->type = REPL_TYPE_CHANGE_CASE;
3283
0
      data->change_case = CHANGE_CASE_LOWER_SINGLE;
3284
0
      break;
3285
0
    case 'u':
3286
0
      p++;
3287
0
      data->type = REPL_TYPE_CHANGE_CASE;
3288
0
      data->change_case = CHANGE_CASE_UPPER_SINGLE;
3289
0
      break;
3290
0
    case 'L':
3291
0
      p++;
3292
0
      data->type = REPL_TYPE_CHANGE_CASE;
3293
0
      data->change_case = CHANGE_CASE_LOWER;
3294
0
      break;
3295
0
    case 'U':
3296
0
      p++;
3297
0
      data->type = REPL_TYPE_CHANGE_CASE;
3298
0
      data->change_case = CHANGE_CASE_UPPER;
3299
0
      break;
3300
0
    case 'E':
3301
0
      p++;
3302
0
      data->type = REPL_TYPE_CHANGE_CASE;
3303
0
      data->change_case = CHANGE_CASE_NONE;
3304
0
      break;
3305
0
    case 'g':
3306
0
      p++;
3307
0
      if (*p != '<')
3308
0
        {
3309
0
          error_detail = _("missing “<” in symbolic reference");
3310
0
          goto error;
3311
0
        }
3312
0
      q = p + 1;
3313
0
      do
3314
0
        {
3315
0
          p++;
3316
0
          if (!*p)
3317
0
            {
3318
0
              error_detail = _("unfinished symbolic reference");
3319
0
              goto error;
3320
0
            }
3321
0
        }
3322
0
      while (*p != '>');
3323
0
      if (p - q == 0)
3324
0
        {
3325
0
          error_detail = _("zero-length symbolic reference");
3326
0
          goto error;
3327
0
        }
3328
0
      if (g_ascii_isdigit (*q))
3329
0
        {
3330
0
          x = 0;
3331
0
          do
3332
0
            {
3333
0
              h = g_ascii_digit_value (*q);
3334
0
              if (h < 0)
3335
0
                {
3336
0
                  error_detail = _("digit expected");
3337
0
                  p = q;
3338
0
                  goto error;
3339
0
                }
3340
0
              x = x * 10 + h;
3341
0
              q++;
3342
0
            }
3343
0
          while (q != p);
3344
0
          data->num = x;
3345
0
          data->type = REPL_TYPE_NUMERIC_REFERENCE;
3346
0
        }
3347
0
      else
3348
0
        {
3349
0
          r = q;
3350
0
          do
3351
0
            {
3352
0
              if (!g_ascii_isalnum (*r))
3353
0
                {
3354
0
                  error_detail = _("illegal symbolic reference");
3355
0
                  p = r;
3356
0
                  goto error;
3357
0
                }
3358
0
              r++;
3359
0
            }
3360
0
          while (r != p);
3361
0
          data->text = g_strndup (q, p - q);
3362
0
          data->type = REPL_TYPE_SYMBOLIC_REFERENCE;
3363
0
        }
3364
0
      p++;
3365
0
      break;
3366
0
    case '0':
3367
      /* if \0 is followed by a number is an octal number representing a
3368
       * character, else it is a numeric reference. */
3369
0
      if (g_ascii_digit_value (*g_utf8_next_char (p)) >= 0)
3370
0
        {
3371
0
          base = 8;
3372
0
          p = g_utf8_next_char (p);
3373
0
        }
3374
0
      G_GNUC_FALLTHROUGH;
3375
0
    case '1':
3376
0
    case '2':
3377
0
    case '3':
3378
0
    case '4':
3379
0
    case '5':
3380
0
    case '6':
3381
0
    case '7':
3382
0
    case '8':
3383
0
    case '9':
3384
0
      x = 0;
3385
0
      d = 0;
3386
0
      for (i = 0; i < 3; i++)
3387
0
        {
3388
0
          h = g_ascii_digit_value (*p);
3389
0
          if (h < 0)
3390
0
            break;
3391
0
          if (h > 7)
3392
0
            {
3393
0
              if (base == 8)
3394
0
                break;
3395
0
              else
3396
0
                base = 10;
3397
0
            }
3398
0
          if (i == 2 && base == 10)
3399
0
            break;
3400
0
          x = x * 8 + h;
3401
0
          d = d * 10 + h;
3402
0
          p++;
3403
0
        }
3404
0
      if (base == 8 || i == 3)
3405
0
        {
3406
0
          data->type = REPL_TYPE_STRING;
3407
0
          data->text = g_new0 (gchar, 8);
3408
0
          g_unichar_to_utf8 (x, data->text);
3409
0
        }
3410
0
      else
3411
0
        {
3412
0
          data->type = REPL_TYPE_NUMERIC_REFERENCE;
3413
0
          data->num = d;
3414
0
        }
3415
0
      break;
3416
0
    case 0:
3417
0
      error_detail = _("stray final “\\”");
3418
0
      goto error;
3419
0
      break;
3420
0
    default:
3421
0
      error_detail = _("unknown escape sequence");
3422
0
      goto error;
3423
0
    }
3424
3425
0
  return p;
3426
3427
0
 error:
3428
  /* G_GSSIZE_FORMAT doesn't work with gettext, so we use %lu */
3429
0
  tmp_error = g_error_new (G_REGEX_ERROR,
3430
0
                           G_REGEX_ERROR_REPLACE,
3431
0
                           _("Error while parsing replacement "
3432
0
                             "text “%s” at char %lu: %s"),
3433
0
                           replacement,
3434
0
                           (gulong)(p - replacement),
3435
0
                           error_detail);
3436
0
  g_propagate_error (error, tmp_error);
3437
3438
0
  return NULL;
3439
0
}
3440
3441
static GList *
3442
split_replacement (const gchar  *replacement,
3443
                   GError      **error)
3444
0
{
3445
0
  GList *list = NULL;
3446
0
  InterpolationData *data;
3447
0
  const gchar *p, *start;
3448
3449
0
  start = p = replacement;
3450
0
  while (*p)
3451
0
    {
3452
0
      if (*p == '\\')
3453
0
        {
3454
0
          data = g_new0 (InterpolationData, 1);
3455
0
          start = p = expand_escape (replacement, p, data, error);
3456
0
          if (p == NULL)
3457
0
            {
3458
0
              g_list_free_full (list, (GDestroyNotify) free_interpolation_data);
3459
0
              free_interpolation_data (data);
3460
3461
0
              return NULL;
3462
0
            }
3463
0
          list = g_list_prepend (list, data);
3464
0
        }
3465
0
      else
3466
0
        {
3467
0
          p++;
3468
0
          if (*p == '\\' || *p == '\0')
3469
0
            {
3470
0
              if (p - start > 0)
3471
0
                {
3472
0
                  data = g_new0 (InterpolationData, 1);
3473
0
                  data->text = g_strndup (start, p - start);
3474
0
                  data->type = REPL_TYPE_STRING;
3475
0
                  list = g_list_prepend (list, data);
3476
0
                }
3477
0
            }
3478
0
        }
3479
0
    }
3480
3481
0
  return g_list_reverse (list);
3482
0
}
3483
3484
/* Change the case of c based on change_case.
3485
 * g_ascii_to*() will happily pass through non-ASCII bytes unchanged. */
3486
#define UTF8_CHANGE_CASE(c, change_case) \
3487
0
        (((change_case) & CHANGE_CASE_LOWER_MASK) ? \
3488
0
                g_unichar_tolower (c) : \
3489
0
                g_unichar_toupper (c))
3490
#define RAW_CHANGE_CASE(c, change_case) \
3491
        (((change_case) & CHANGE_CASE_LOWER_MASK) ? \
3492
                g_ascii_tolower (c) : \
3493
                g_ascii_toupper (c))
3494
3495
/* If @text_is_raw is set, @text might not be valid UTF-8 (but will be
3496
 * nul-terminated). */
3497
static void
3498
string_append (GString     *string,
3499
               const gchar *text,
3500
               gboolean     text_is_raw,
3501
               ChangeCase  *change_case)
3502
0
{
3503
0
  if (text[0] == '\0')
3504
0
    return;
3505
3506
0
  if (*change_case == CHANGE_CASE_NONE)
3507
0
    {
3508
0
      g_string_append (string, text);
3509
0
    }
3510
0
  else if (*change_case & CHANGE_CASE_SINGLE_MASK)
3511
0
    {
3512
0
      if (!text_is_raw)
3513
0
        {
3514
0
          gunichar c = g_utf8_get_char (text);
3515
0
          g_string_append_unichar (string, UTF8_CHANGE_CASE (c, *change_case));
3516
0
          g_string_append (string, g_utf8_next_char (text));
3517
0
        }
3518
0
      else
3519
0
        {
3520
0
          g_string_append_c (string, RAW_CHANGE_CASE (text[0], *change_case));
3521
0
          g_string_append (string, text + 1);
3522
0
        }
3523
3524
0
      *change_case = CHANGE_CASE_NONE;
3525
0
    }
3526
0
  else
3527
0
    {
3528
0
      if (!text_is_raw)
3529
0
        {
3530
0
          while (*text != '\0')
3531
0
            {
3532
0
              gunichar c = g_utf8_get_char (text);
3533
0
              g_string_append_unichar (string, UTF8_CHANGE_CASE (c, *change_case));
3534
0
              text = g_utf8_next_char (text);
3535
0
            }
3536
0
        }
3537
0
      else
3538
0
        {
3539
0
          while (*text != '\0')
3540
0
            {
3541
0
              char c = *text;
3542
0
              g_string_append_c (string, RAW_CHANGE_CASE (c, *change_case));
3543
0
              text++;
3544
0
            }
3545
0
        }
3546
0
    }
3547
0
}
3548
3549
/* @match_info is (nullable) */
3550
static gboolean
3551
interpolate_replacement (const GMatchInfo *match_info,
3552
                         GString          *result,
3553
                         gpointer          data)
3554
0
{
3555
0
  GList *list;
3556
0
  InterpolationData *idata;
3557
0
  gchar *match;
3558
0
  ChangeCase change_case = CHANGE_CASE_NONE;
3559
0
  gboolean is_raw = (match_info != NULL && (match_info->regex->regex_compile_opts & G_REGEX_RAW));
3560
3561
0
  for (list = data; list; list = list->next)
3562
0
    {
3563
0
      idata = list->data;
3564
0
      switch (idata->type)
3565
0
        {
3566
0
        case REPL_TYPE_STRING:
3567
0
          string_append (result, idata->text, is_raw, &change_case);
3568
0
          break;
3569
0
        case REPL_TYPE_CHARACTER:
3570
0
          g_string_append_c (result, UTF8_CHANGE_CASE (idata->c, change_case));
3571
0
          if (change_case & CHANGE_CASE_SINGLE_MASK)
3572
0
            change_case = CHANGE_CASE_NONE;
3573
0
          break;
3574
0
        case REPL_TYPE_NUMERIC_REFERENCE:
3575
0
          match = g_match_info_fetch (match_info, idata->num);
3576
0
          if (match)
3577
0
            {
3578
0
              string_append (result, match, is_raw, &change_case);
3579
0
              g_free (match);
3580
0
            }
3581
0
          break;
3582
0
        case REPL_TYPE_SYMBOLIC_REFERENCE:
3583
0
          match = g_match_info_fetch_named (match_info, idata->text);
3584
0
          if (match)
3585
0
            {
3586
0
              string_append (result, match, is_raw, &change_case);
3587
0
              g_free (match);
3588
0
            }
3589
0
          break;
3590
0
        case REPL_TYPE_CHANGE_CASE:
3591
0
          change_case = idata->change_case;
3592
0
          break;
3593
0
        }
3594
0
    }
3595
3596
0
  return FALSE;
3597
0
}
3598
3599
/* whether actual match_info is needed for replacement, i.e.
3600
 * whether there are references
3601
 */
3602
static gboolean
3603
interpolation_list_needs_match (GList *list)
3604
0
{
3605
0
  while (list != NULL)
3606
0
    {
3607
0
      InterpolationData *data = list->data;
3608
3609
0
      if (data->type == REPL_TYPE_SYMBOLIC_REFERENCE ||
3610
0
          data->type == REPL_TYPE_NUMERIC_REFERENCE)
3611
0
        {
3612
0
          return TRUE;
3613
0
        }
3614
3615
0
      list = list->next;
3616
0
    }
3617
3618
0
  return FALSE;
3619
0
}
3620
3621
/**
3622
 * g_regex_replace:
3623
 * @regex: a #GRegex structure
3624
 * @string: the string to perform matches against
3625
 * @string_len: the length of @string, in bytes, or -1 if @string is nul-terminated
3626
 * @start_position: starting index of the string to match, in bytes
3627
 * @replacement: text to replace each match with
3628
 * @match_options: options for the match
3629
 * @error: location to store the error occurring, or %NULL to ignore errors
3630
 *
3631
 * Replaces all occurrences of the pattern in @regex with the
3632
 * replacement text. Backreferences of the form `\number` or
3633
 * `\g<number>` in the replacement text are interpolated by the
3634
 * number-th captured subexpression of the match, `\g<name>` refers
3635
 * to the captured subexpression with the given name. `\0` refers
3636
 * to the complete match, but `\0` followed by a number is the octal
3637
 * representation of a character. To include a literal `\` in the
3638
 * replacement, write `\\\\`.
3639
 *
3640
 * There are also escapes that changes the case of the following text:
3641
 *
3642
 * - `\l`: Convert to lower case the next character
3643
 * - `\u`: Convert to upper case the next character
3644
 * - `\L`: Convert to lower case until the next `\E`
3645
 * - `\U`: Convert to upper case until the next `\E`
3646
 * - `\E`: End case modification
3647
 *
3648
 * If you do not need to use backreferences use g_regex_replace_literal().
3649
 *
3650
 * The @replacement string must be UTF-8 encoded even if %G_REGEX_RAW was
3651
 * passed to g_regex_new(). If you want to use not UTF-8 encoded strings
3652
 * you can use g_regex_replace_literal().
3653
 *
3654
 * Setting @start_position differs from just passing over a shortened
3655
 * string and setting %G_REGEX_MATCH_NOTBOL in the case of a pattern that
3656
 * begins with any kind of lookbehind assertion, such as `"\b"`.
3657
 *
3658
 * Returns: a newly allocated string containing the replacements
3659
 *
3660
 * Since: 2.14
3661
 */
3662
gchar *
3663
g_regex_replace (const GRegex      *regex,
3664
                 const gchar       *string,
3665
                 gssize             string_len,
3666
                 gint               start_position,
3667
                 const gchar       *replacement,
3668
                 GRegexMatchFlags   match_options,
3669
                 GError           **error)
3670
0
{
3671
0
  gchar *result;
3672
0
  GList *list;
3673
0
  GError *tmp_error = NULL;
3674
3675
0
  g_return_val_if_fail (regex != NULL, NULL);
3676
0
  g_return_val_if_fail (string != NULL, NULL);
3677
0
  g_return_val_if_fail (start_position >= 0, NULL);
3678
0
  g_return_val_if_fail (replacement != NULL, NULL);
3679
0
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
3680
0
  g_return_val_if_fail ((match_options & ~G_REGEX_MATCH_MASK) == 0, NULL);
3681
3682
0
  list = split_replacement (replacement, &tmp_error);
3683
0
  if (tmp_error != NULL)
3684
0
    {
3685
0
      g_propagate_error (error, tmp_error);
3686
0
      return NULL;
3687
0
    }
3688
3689
0
  result = g_regex_replace_eval (regex,
3690
0
                                 string, string_len, start_position,
3691
0
                                 match_options,
3692
0
                                 interpolate_replacement,
3693
0
                                 (gpointer)list,
3694
0
                                 &tmp_error);
3695
0
  if (tmp_error != NULL)
3696
0
    g_propagate_error (error, tmp_error);
3697
3698
0
  g_list_free_full (list, (GDestroyNotify) free_interpolation_data);
3699
3700
0
  return result;
3701
0
}
3702
3703
static gboolean
3704
literal_replacement (const GMatchInfo *match_info,
3705
                     GString          *result,
3706
                     gpointer          data)
3707
0
{
3708
0
  g_string_append (result, data);
3709
0
  return FALSE;
3710
0
}
3711
3712
/**
3713
 * g_regex_replace_literal:
3714
 * @regex: a #GRegex structure
3715
 * @string: the string to perform matches against
3716
 * @string_len: the length of @string, in bytes, or -1 if @string is nul-terminated
3717
 * @start_position: starting index of the string to match, in bytes
3718
 * @replacement: text to replace each match with
3719
 * @match_options: options for the match
3720
 * @error: location to store the error occurring, or %NULL to ignore errors
3721
 *
3722
 * Replaces all occurrences of the pattern in @regex with the
3723
 * replacement text. @replacement is replaced literally, to
3724
 * include backreferences use g_regex_replace().
3725
 *
3726
 * Setting @start_position differs from just passing over a
3727
 * shortened string and setting %G_REGEX_MATCH_NOTBOL in the
3728
 * case of a pattern that begins with any kind of lookbehind
3729
 * assertion, such as "\b".
3730
 *
3731
 * Returns: a newly allocated string containing the replacements
3732
 *
3733
 * Since: 2.14
3734
 */
3735
gchar *
3736
g_regex_replace_literal (const GRegex      *regex,
3737
                         const gchar       *string,
3738
                         gssize             string_len,
3739
                         gint               start_position,
3740
                         const gchar       *replacement,
3741
                         GRegexMatchFlags   match_options,
3742
                         GError           **error)
3743
0
{
3744
0
  g_return_val_if_fail (replacement != NULL, NULL);
3745
0
  g_return_val_if_fail ((match_options & ~G_REGEX_MATCH_MASK) == 0, NULL);
3746
3747
0
  return g_regex_replace_eval (regex,
3748
0
                               string, string_len, start_position,
3749
0
                               match_options,
3750
0
                               literal_replacement,
3751
0
                               (gpointer)replacement,
3752
0
                               error);
3753
0
}
3754
3755
/**
3756
 * g_regex_replace_eval:
3757
 * @regex: a #GRegex structure from g_regex_new()
3758
 * @string: string to perform matches against
3759
 * @string_len: the length of @string, in bytes, or -1 if @string is nul-terminated
3760
 * @start_position: starting index of the string to match, in bytes
3761
 * @match_options: options for the match
3762
 * @eval: (scope call): a function to call for each match
3763
 * @user_data: user data to pass to the function
3764
 * @error: location to store the error occurring, or %NULL to ignore errors
3765
 *
3766
 * Replaces occurrences of the pattern in regex with the output of
3767
 * @eval for that occurrence.
3768
 *
3769
 * Setting @start_position differs from just passing over a shortened
3770
 * string and setting %G_REGEX_MATCH_NOTBOL in the case of a pattern
3771
 * that begins with any kind of lookbehind assertion, such as "\b".
3772
 *
3773
 * The following example uses g_regex_replace_eval() to replace multiple
3774
 * strings at once:
3775
 * |[<!-- language="C" --> 
3776
 * static gboolean
3777
 * eval_cb (const GMatchInfo *info,
3778
 *          GString          *res,
3779
 *          gpointer          data)
3780
 * {
3781
 *   gchar *match;
3782
 *   gchar *r;
3783
 *
3784
 *    match = g_match_info_fetch (info, 0);
3785
 *    r = g_hash_table_lookup ((GHashTable *)data, match);
3786
 *    g_string_append (res, r);
3787
 *    g_free (match);
3788
 *
3789
 *    return FALSE;
3790
 * }
3791
 *
3792
 * ...
3793
 *
3794
 * GRegex *reg;
3795
 * GHashTable *h;
3796
 * gchar *res;
3797
 *
3798
 * h = g_hash_table_new (g_str_hash, g_str_equal);
3799
 *
3800
 * g_hash_table_insert (h, "1", "ONE");
3801
 * g_hash_table_insert (h, "2", "TWO");
3802
 * g_hash_table_insert (h, "3", "THREE");
3803
 * g_hash_table_insert (h, "4", "FOUR");
3804
 *
3805
 * reg = g_regex_new ("1|2|3|4", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL);
3806
 * res = g_regex_replace_eval (reg, text, -1, 0, 0, eval_cb, h, NULL);
3807
 * g_hash_table_destroy (h);
3808
 *
3809
 * ...
3810
 * ]|
3811
 *
3812
 * Returns: a newly allocated string containing the replacements
3813
 *
3814
 * Since: 2.14
3815
 */
3816
gchar *
3817
g_regex_replace_eval (const GRegex        *regex,
3818
                      const gchar         *string,
3819
                      gssize               string_len,
3820
                      gint                 start_position,
3821
                      GRegexMatchFlags     match_options,
3822
                      GRegexEvalCallback   eval,
3823
                      gpointer             user_data,
3824
                      GError             **error)
3825
0
{
3826
0
  GMatchInfo *match_info;
3827
0
  GString *result;
3828
0
  size_t str_pos = 0;
3829
0
  gboolean done = FALSE;
3830
0
  GError *tmp_error = NULL;
3831
0
  size_t string_len_unsigned;
3832
3833
0
  g_return_val_if_fail (regex != NULL, NULL);
3834
0
  g_return_val_if_fail (string != NULL, NULL);
3835
0
  g_return_val_if_fail (start_position >= 0, NULL);
3836
0
  g_return_val_if_fail (eval != NULL, NULL);
3837
0
  g_return_val_if_fail ((match_options & ~G_REGEX_MATCH_MASK) == 0, NULL);
3838
3839
0
  string_len_unsigned = (string_len < 0) ? strlen (string) : (size_t) string_len;
3840
3841
0
  result = g_string_sized_new (string_len_unsigned);
3842
3843
  /* run down the string making matches. */
3844
0
  g_regex_match_full (regex, string, string_len_unsigned, start_position,
3845
0
                      match_options, &match_info, &tmp_error);
3846
0
  while (!done && g_match_info_matches (match_info))
3847
0
    {
3848
0
      g_string_append_len (result,
3849
0
                           string + str_pos,
3850
0
                           match_info->offsets[0] - str_pos);
3851
0
      done = (*eval) (match_info, result, user_data);
3852
0
      str_pos = match_info->offsets[1];
3853
0
      g_match_info_next (match_info, &tmp_error);
3854
0
    }
3855
0
  g_match_info_free (match_info);
3856
0
  if (tmp_error != NULL)
3857
0
    {
3858
0
      g_propagate_error (error, tmp_error);
3859
0
      g_string_free (result, TRUE);
3860
0
      return NULL;
3861
0
    }
3862
3863
0
  g_string_append_len (result, string + str_pos, string_len_unsigned - str_pos);
3864
0
  return g_string_free (result, FALSE);
3865
0
}
3866
3867
/**
3868
 * g_regex_check_replacement:
3869
 * @replacement: the replacement string
3870
 * @has_references: (out) (optional): location to store information about
3871
 *   references in @replacement or %NULL
3872
 * @error: location to store error
3873
 *
3874
 * Checks whether @replacement is a valid replacement string
3875
 * (see g_regex_replace()), i.e. that all escape sequences in
3876
 * it are valid.
3877
 *
3878
 * If @has_references is not %NULL then @replacement is checked
3879
 * for pattern references. For instance, replacement text 'foo\n'
3880
 * does not contain references and may be evaluated without information
3881
 * about actual match, but '\0\1' (whole match followed by first
3882
 * subpattern) requires valid #GMatchInfo object.
3883
 *
3884
 * Returns: whether @replacement is a valid replacement string
3885
 *
3886
 * Since: 2.14
3887
 */
3888
gboolean
3889
g_regex_check_replacement (const gchar  *replacement,
3890
                           gboolean     *has_references,
3891
                           GError      **error)
3892
0
{
3893
0
  GList *list;
3894
0
  GError *tmp = NULL;
3895
3896
0
  list = split_replacement (replacement, &tmp);
3897
3898
0
  if (tmp)
3899
0
  {
3900
0
    g_propagate_error (error, tmp);
3901
0
    return FALSE;
3902
0
  }
3903
3904
0
  if (has_references)
3905
0
    *has_references = interpolation_list_needs_match (list);
3906
3907
0
  g_list_free_full (list, (GDestroyNotify) free_interpolation_data);
3908
3909
0
  return TRUE;
3910
0
}
3911
3912
/**
3913
 * g_regex_escape_nul:
3914
 * @string: the string to escape
3915
 * @length: the length of @string
3916
 *
3917
 * Escapes the nul characters in @string to "\x00".  It can be used
3918
 * to compile a regex with embedded nul characters.
3919
 *
3920
 * For completeness, @length can be -1 for a nul-terminated string.
3921
 * In this case the output string will be of course equal to @string.
3922
 *
3923
 * Returns: a newly-allocated escaped string
3924
 *
3925
 * Since: 2.30
3926
 */
3927
gchar *
3928
g_regex_escape_nul (const gchar *string,
3929
                    gint         length)
3930
0
{
3931
0
  GString *escaped;
3932
0
  const gchar *p, *piece_start, *end;
3933
0
  gint backslashes;
3934
3935
0
  g_return_val_if_fail (string != NULL, NULL);
3936
3937
0
  if (length < 0)
3938
0
    return g_strdup (string);
3939
3940
0
  end = string + length;
3941
0
  p = piece_start = string;
3942
0
  escaped = g_string_sized_new (length + 1);
3943
3944
0
  backslashes = 0;
3945
0
  while (p < end)
3946
0
    {
3947
0
      switch (*p)
3948
0
        {
3949
0
        case '\0':
3950
0
          if (p != piece_start)
3951
0
            {
3952
              /* copy the previous piece. */
3953
0
              g_string_append_len (escaped, piece_start, p - piece_start);
3954
0
            }
3955
0
          if ((backslashes & 1) == 0)
3956
0
            g_string_append_c (escaped, '\\');
3957
0
          g_string_append_c (escaped, 'x');
3958
0
          g_string_append_c (escaped, '0');
3959
0
          g_string_append_c (escaped, '0');
3960
0
          piece_start = ++p;
3961
0
          backslashes = 0;
3962
0
          break;
3963
0
        case '\\':
3964
0
          backslashes++;
3965
0
          ++p;
3966
0
          break;
3967
0
        default:
3968
0
          backslashes = 0;
3969
0
          p = g_utf8_next_char (p);
3970
0
          break;
3971
0
        }
3972
0
    }
3973
3974
0
  if (piece_start < end)
3975
0
    g_string_append_len (escaped, piece_start, end - piece_start);
3976
3977
0
  return g_string_free (escaped, FALSE);
3978
0
}
3979
3980
/**
3981
 * g_regex_escape_string:
3982
 * @string: the string to escape
3983
 * @length: the length of @string, in bytes, or -1 if @string is nul-terminated
3984
 *
3985
 * Escapes the special characters used for regular expressions
3986
 * in @string, for instance "a.b*c" becomes "a\.b\*c". This
3987
 * function is useful to dynamically generate regular expressions.
3988
 *
3989
 * @string can contain nul characters that are replaced with "\0",
3990
 * in this case remember to specify the correct length of @string
3991
 * in @length.
3992
 *
3993
 * Returns: a newly-allocated escaped string
3994
 *
3995
 * Since: 2.14
3996
 */
3997
gchar *
3998
g_regex_escape_string (const gchar *string,
3999
                       gint         length)
4000
0
{
4001
0
  GString *escaped;
4002
0
  const char *p, *piece_start, *end;
4003
0
  size_t length_unsigned;
4004
4005
0
  g_return_val_if_fail (string != NULL, NULL);
4006
4007
0
  length_unsigned = (length < 0) ? strlen (string) : (size_t) length;
4008
4009
0
  end = string + length_unsigned;
4010
0
  p = piece_start = string;
4011
0
  escaped = g_string_sized_new (length_unsigned + 1);
4012
4013
0
  while (p < end)
4014
0
    {
4015
0
      switch (*p)
4016
0
        {
4017
0
        case '\0':
4018
0
        case '\\':
4019
0
        case '|':
4020
0
        case '(':
4021
0
        case ')':
4022
0
        case '[':
4023
0
        case ']':
4024
0
        case '{':
4025
0
        case '}':
4026
0
        case '^':
4027
0
        case '$':
4028
0
        case '*':
4029
0
        case '+':
4030
0
        case '?':
4031
0
        case '.':
4032
0
          if (p != piece_start)
4033
            /* copy the previous piece. */
4034
0
            g_string_append_len (escaped, piece_start, p - piece_start);
4035
0
          g_string_append_c (escaped, '\\');
4036
0
          if (*p == '\0')
4037
0
            g_string_append_c (escaped, '0');
4038
0
          else
4039
0
            g_string_append_c (escaped, *p);
4040
0
          piece_start = ++p;
4041
0
          break;
4042
0
        default:
4043
0
          p = g_utf8_next_char (p);
4044
0
          break;
4045
0
        }
4046
0
  }
4047
4048
0
  if (piece_start < end)
4049
0
    g_string_append_len (escaped, piece_start, end - piece_start);
4050
4051
0
  return g_string_free (escaped, FALSE);
4052
0
}