Coverage Report

Created: 2026-10-14 08:19

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