/* GRegex -- regular expression API wrapper around PCRE.
 *
 * Copyright (C) 1999, 2000 Scott Wimer
 * Copyright (C) 2004, Matthias Clasen <mclasen@redhat.com>
 * Copyright (C) 2005 - 2007, Marco Barisione <marco@barisione.org>
 * Copyright (C) 2022, Marco Trevisan <marco.trevisan@canonical.com>
 *
 * SPDX-License-Identifier: LGPL-2.1-or-later
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, see <http://www.gnu.org/licenses/>.
 */

#include "config.h"

#include <stdint.h>
#include <string.h>

#define PCRE2_CODE_UNIT_WIDTH 8
#include <pcre2.h>

#include "gtypes.h"
#include "gregex.h"
#include "glibintl.h"
#include "glist.h"
#include "gmessages.h"
#include "gstrfuncs.h"
#include "gatomic.h"
#include "gtestutils.h"
#include "gthread.h"

/**
 * GRegex:
 *
 * A `GRegex` is the "compiled" form of a regular expression pattern.
 *
 * `GRegex` implements regular expression pattern matching using syntax and
 * semantics similar to Perl regular expression. See the
 * [PCRE documentation](man:pcrepattern(3)) for the syntax definition.
 *
 * Some functions accept a @start_position argument, setting it differs
 * from just passing over a shortened string and setting %G_REGEX_MATCH_NOTBOL
 * in the case of a pattern that begins with any kind of lookbehind assertion.
 * For example, consider the pattern "\Biss\B" which finds occurrences of "iss"
 * in the middle of words. ("\B" matches only if the current position in the
 * subject is not a word boundary.) When applied to the string "Mississipi"
 * from the fourth byte, namely "issipi", it does not match, because "\B" is
 * always false at the start of the subject, which is deemed to be a word
 * boundary. However, if the entire string is passed , but with
 * @start_position set to 4, it finds the second occurrence of "iss" because
 * it is able to look behind the starting point to discover that it is
 * preceded by a letter.
 *
 * Note that, unless you set the %G_REGEX_RAW flag, all the strings passed
 * to these functions must be encoded in UTF-8. The lengths and the positions
 * inside the strings are in bytes and not in characters, so, for instance,
 * "\xc3\xa0" (i.e. "à") is two bytes long but it is treated as a
 * single character. If you set %G_REGEX_RAW the strings can be non-valid
 * UTF-8 strings and a byte is treated as a character, so "\xc3\xa0" is two
 * bytes and two characters long.
 *
 * When matching a pattern, "\n" matches only against a "\n" character in
 * the string, and "\r" matches only a "\r" character. To match any newline
 * sequence use "\R". This particular group matches either the two-character
 * sequence CR + LF ("\r\n"), or one of the single characters LF (linefeed,
 * U+000A, "\n"), VT vertical tab, U+000B, "\v"), FF (formfeed, U+000C, "\f"),
 * CR (carriage return, U+000D, "\r"), NEL (next line, U+0085), LS (line
 * separator, U+2028), or PS (paragraph separator, U+2029).
 *
 * The behaviour of the dot, circumflex, and dollar metacharacters are
 * affected by newline characters, the default is to recognize any newline
 * character (the same characters recognized by "\R"). This can be changed
 * with `G_REGEX_NEWLINE_CR`, `G_REGEX_NEWLINE_LF` and `G_REGEX_NEWLINE_CRLF`
 * compile options, and with `G_REGEX_MATCH_NEWLINE_ANY`,
 * `G_REGEX_MATCH_NEWLINE_CR`, `G_REGEX_MATCH_NEWLINE_LF` and
 * `G_REGEX_MATCH_NEWLINE_CRLF` match options. These settings are also
 * relevant when compiling a pattern if `G_REGEX_EXTENDED` is set, and an
 * unescaped "#" outside a character class is encountered. This indicates
 * a comment that lasts until after the next newline.
 *
 * Creating and manipulating the same `GRegex` structure from different
 * threads is not a problem as `GRegex` does not modify its internal
 * state between creation and destruction, on the other hand `GMatchInfo`
 * is not threadsafe.
 *
 * The regular expressions low-level functionalities are obtained through
 * the excellent [PCRE](http://www.pcre.org/) library written by Philip Hazel.
 *
 * Since: 2.14
 */

#define G_REGEX_PCRE_GENERIC_MASK (PCRE2_ANCHORED       | \
                                   PCRE2_NO_UTF_CHECK   | \
                                   PCRE2_ENDANCHORED)

/* Mask of all the possible values for GRegexCompileFlags. */
#define G_REGEX_COMPILE_MASK (G_REGEX_DEFAULT          | \
                              G_REGEX_CASELESS         | \
                              G_REGEX_MULTILINE        | \
                              G_REGEX_DOTALL           | \
                              G_REGEX_EXTENDED         | \
                              G_REGEX_ANCHORED         | \
                              G_REGEX_DOLLAR_ENDONLY   | \
                              G_REGEX_UNGREEDY         | \
                              G_REGEX_RAW              | \
                              G_REGEX_NO_AUTO_CAPTURE  | \
                              G_REGEX_OPTIMIZE         | \
                              G_REGEX_FIRSTLINE        | \
                              G_REGEX_DUPNAMES         | \
                              G_REGEX_NEWLINE_CR       | \
                              G_REGEX_NEWLINE_LF       | \
                              G_REGEX_NEWLINE_CRLF     | \
                              G_REGEX_NEWLINE_ANYCRLF  | \
                              G_REGEX_BSR_ANYCRLF)

#define G_REGEX_PCRE2_COMPILE_MASK (PCRE2_ALLOW_EMPTY_CLASS    | \
                                    PCRE2_ALT_BSUX             | \
                                    PCRE2_AUTO_CALLOUT         | \
                                    PCRE2_CASELESS             | \
                                    PCRE2_DOLLAR_ENDONLY       | \
                                    PCRE2_DOTALL               | \
                                    PCRE2_DUPNAMES             | \
                                    PCRE2_EXTENDED             | \
                                    PCRE2_FIRSTLINE            | \
                                    PCRE2_MATCH_UNSET_BACKREF  | \
                                    PCRE2_MULTILINE            | \
                                    PCRE2_NEVER_UCP            | \
                                    PCRE2_NEVER_UTF            | \
                                    PCRE2_NO_AUTO_CAPTURE      | \
                                    PCRE2_NO_AUTO_POSSESS      | \
                                    PCRE2_NO_DOTSTAR_ANCHOR    | \
                                    PCRE2_NO_START_OPTIMIZE    | \
                                    PCRE2_UCP                  | \
                                    PCRE2_UNGREEDY             | \
                                    PCRE2_UTF                  | \
                                    PCRE2_NEVER_BACKSLASH_C    | \
                                    PCRE2_ALT_CIRCUMFLEX       | \
                                    PCRE2_ALT_VERBNAMES        | \
                                    PCRE2_USE_OFFSET_LIMIT     | \
                                    PCRE2_EXTENDED_MORE        | \
                                    PCRE2_LITERAL              | \
                                    PCRE2_MATCH_INVALID_UTF    | \
                                    G_REGEX_PCRE_GENERIC_MASK)

#define G_REGEX_COMPILE_NONPCRE_MASK (PCRE2_UTF)

/* Mask of all the possible values for GRegexMatchFlags. */
#define G_REGEX_MATCH_MASK (G_REGEX_MATCH_DEFAULT          | \
                            G_REGEX_MATCH_ANCHORED         | \
                            G_REGEX_MATCH_NOTBOL           | \
                            G_REGEX_MATCH_NOTEOL           | \
                            G_REGEX_MATCH_NOTEMPTY         | \
                            G_REGEX_MATCH_PARTIAL          | \
                            G_REGEX_MATCH_NEWLINE_CR       | \
                            G_REGEX_MATCH_NEWLINE_LF       | \
                            G_REGEX_MATCH_NEWLINE_CRLF     | \
                            G_REGEX_MATCH_NEWLINE_ANY      | \
                            G_REGEX_MATCH_NEWLINE_ANYCRLF  | \
                            G_REGEX_MATCH_BSR_ANYCRLF      | \
                            G_REGEX_MATCH_BSR_ANY          | \
                            G_REGEX_MATCH_PARTIAL_SOFT     | \
                            G_REGEX_MATCH_PARTIAL_HARD     | \
                            G_REGEX_MATCH_NOTEMPTY_ATSTART)

#define G_REGEX_PCRE2_MATCH_MASK (PCRE2_NOTBOL                      |\
                                  PCRE2_NOTEOL                      |\
                                  PCRE2_NOTEMPTY                    |\
                                  PCRE2_NOTEMPTY_ATSTART            |\
                                  PCRE2_PARTIAL_SOFT                |\
                                  PCRE2_PARTIAL_HARD                |\
                                  PCRE2_NO_JIT                      |\
                                  PCRE2_COPY_MATCHED_SUBJECT        |\
                                  G_REGEX_PCRE_GENERIC_MASK)

/* TODO: Support PCRE2_NEWLINE_NUL */
#define G_REGEX_NEWLINE_MASK (PCRE2_NEWLINE_CR |     \
                              PCRE2_NEWLINE_LF |     \
                              PCRE2_NEWLINE_CRLF |   \
                              PCRE2_NEWLINE_ANYCRLF)

/* Some match options are not supported when using JIT as stated in the
 * pcre2jit man page under the «UNSUPPORTED OPTIONS AND PATTERN ITEMS» section:
 *   https://www.pcre.org/current/doc/html/pcre2jit.html#SEC5
 */
#define G_REGEX_PCRE2_JIT_UNSUPPORTED_OPTIONS (PCRE2_ANCHORED | \
                                               PCRE2_ENDANCHORED)

#define G_REGEX_COMPILE_NEWLINE_MASK (G_REGEX_NEWLINE_CR      | \
                                      G_REGEX_NEWLINE_LF      | \
                                      G_REGEX_NEWLINE_CRLF    | \
                                      G_REGEX_NEWLINE_ANYCRLF)

#define G_REGEX_MATCH_NEWLINE_MASK (G_REGEX_MATCH_NEWLINE_CR      | \
                                    G_REGEX_MATCH_NEWLINE_LF      | \
                                    G_REGEX_MATCH_NEWLINE_CRLF    | \
                                    G_REGEX_MATCH_NEWLINE_ANY    | \
                                    G_REGEX_MATCH_NEWLINE_ANYCRLF)

/* if the string is in UTF-8 use g_utf8_ functions, else use
 * use just +/- 1. */
#define NEXT_CHAR(re, s) (((re)->compile_opts & G_REGEX_RAW) ? \
                                ((s) + 1) : \
                                g_utf8_next_char (s))
#define PREV_CHAR(re, s) (((re)->compile_opts & G_REGEX_RAW) ? \
                                ((s) - 1) : \
                                g_utf8_prev_char (s))

struct _GMatchInfo
{
  gint ref_count;               /* the ref count (atomic) */
  GRegex *regex;                /* the regex */
  uint32_t match_opts;          /* pcre match options used at match time on the regex */
  gint matches;                 /* number of matching sub patterns, guaranteed to be <= (n_subpatterns + 1) if doing a single match (rather than matching all) */
  uint32_t n_subpatterns;       /* total number of sub patterns in the regex */
  gint pos;                     /* position in the string where last match left off */
  uint32_t n_offsets;           /* number of offsets */
  gint *offsets;                /* array of offsets paired 0,1 ; 2,3 ; 3,4 etc */
  gint *workspace;              /* workspace for pcre2_dfa_match() */
  PCRE2_SIZE n_workspace;       /* number of workspace elements */
  const gchar *string;          /* string passed to the match function */
  gssize string_len;            /* length of string, in bytes */
  pcre2_match_context *match_context;
  pcre2_match_data *match_data;
  pcre2_jit_stack *jit_stack;
};

typedef enum
{
  JIT_STATUS_DEFAULT,
  JIT_STATUS_ENABLED,
  JIT_STATUS_DISABLED
} JITStatus;

struct _GRegex
{
  gint ref_count;               /* the ref count for the immutable part (atomic) */
  gchar *pattern;               /* the pattern */
  pcre2_code *pcre_re;          /* compiled form of the pattern */
  uint32_t compile_opts;        /* options used at compile time on the pattern, pcre2 values */
  GRegexCompileFlags orig_compile_opts; /* options used at compile time on the pattern, gregex values */
  uint32_t match_opts;          /* pcre2 options used at match time on the regex */
  GRegexMatchFlags orig_match_opts; /* options used as default match options, gregex values */
  uint32_t jit_options;         /* options which were enabled for jit compiler */
  JITStatus jit_status;         /* indicates the status of jit compiler for this compiled regex */
  /* The jit_status here does _not_ correspond to whether we used the JIT in the last invocation,
   * which may be affected by match_options or a JIT_STACK_LIMIT error, but whether it was ever
   * enabled for the current regex AND current set of jit_options.
   * JIT_STATUS_DEFAULT means enablement was never tried,
   * JIT_STATUS_ENABLED means it was tried and successful (even if we're not currently using it),
   * and JIT_STATUS_DISABLED means it was tried and failed (so we shouldn't try again).
   */
};

/* TRUE if ret is an error code, FALSE otherwise. */
#define IS_PCRE2_ERROR(ret) ((ret) < PCRE2_ERROR_NOMATCH && (ret) != PCRE2_ERROR_PARTIAL)

typedef struct _InterpolationData InterpolationData;
static gboolean  interpolation_list_needs_match (GList *list);
static gboolean  interpolate_replacement        (const GMatchInfo *match_info,
                                                 GString *result,
                                                 gpointer data);
static GList    *split_replacement              (const gchar *replacement,
                                                 GError **error);
static void      free_interpolation_data        (InterpolationData *data);

static uint32_t
get_pcre2_compile_options (GRegexCompileFlags compile_flags)
{
  /* Maps compile flags to pcre2 values */
  uint32_t pcre2_flags = 0;

  if (compile_flags & G_REGEX_CASELESS)
    pcre2_flags |= PCRE2_CASELESS;
  if (compile_flags & G_REGEX_MULTILINE)
    pcre2_flags |= PCRE2_MULTILINE;
  if (compile_flags & G_REGEX_DOTALL)
    pcre2_flags |= PCRE2_DOTALL;
  if (compile_flags & G_REGEX_EXTENDED)
    pcre2_flags |= PCRE2_EXTENDED;
  if (compile_flags & G_REGEX_ANCHORED)
    pcre2_flags |= PCRE2_ANCHORED;
  if (compile_flags & G_REGEX_DOLLAR_ENDONLY)
    pcre2_flags |= PCRE2_DOLLAR_ENDONLY;
  if (compile_flags & G_REGEX_UNGREEDY)
    pcre2_flags |= PCRE2_UNGREEDY;
  if (!(compile_flags & G_REGEX_RAW))
    pcre2_flags |= PCRE2_UTF;
  if (compile_flags & G_REGEX_NO_AUTO_CAPTURE)
    pcre2_flags |= PCRE2_NO_AUTO_CAPTURE;
  if (compile_flags & G_REGEX_FIRSTLINE)
    pcre2_flags |= PCRE2_FIRSTLINE;
  if (compile_flags & G_REGEX_DUPNAMES)
    pcre2_flags |= PCRE2_DUPNAMES;

  return pcre2_flags & G_REGEX_PCRE2_COMPILE_MASK;
}

static uint32_t
get_pcre2_match_options (GRegexMatchFlags   match_flags,
                         GRegexCompileFlags compile_flags)
{
  /* Maps match flags to pcre2 values */
  uint32_t pcre2_flags = 0;

  if (match_flags & G_REGEX_MATCH_ANCHORED)
    pcre2_flags |= PCRE2_ANCHORED;
  if (match_flags & G_REGEX_MATCH_NOTBOL)
    pcre2_flags |= PCRE2_NOTBOL;
  if (match_flags & G_REGEX_MATCH_NOTEOL)
    pcre2_flags |= PCRE2_NOTEOL;
  if (match_flags & G_REGEX_MATCH_NOTEMPTY)
    pcre2_flags |= PCRE2_NOTEMPTY;
  if (match_flags & G_REGEX_MATCH_PARTIAL_SOFT)
    pcre2_flags |= PCRE2_PARTIAL_SOFT;
  if (match_flags & G_REGEX_MATCH_PARTIAL_HARD)
    pcre2_flags |= PCRE2_PARTIAL_HARD;
  if (match_flags & G_REGEX_MATCH_NOTEMPTY_ATSTART)
    pcre2_flags |= PCRE2_NOTEMPTY_ATSTART;

  if (compile_flags & G_REGEX_RAW)
    pcre2_flags |= PCRE2_NO_UTF_CHECK;

  return pcre2_flags & G_REGEX_PCRE2_MATCH_MASK;
}

static GRegexCompileFlags
g_regex_compile_flags_from_pcre2 (uint32_t pcre2_flags)
{
  GRegexCompileFlags compile_flags = G_REGEX_DEFAULT;

  if (pcre2_flags & PCRE2_CASELESS)
    compile_flags |= G_REGEX_CASELESS;
  if (pcre2_flags & PCRE2_MULTILINE)
    compile_flags |= G_REGEX_MULTILINE;
  if (pcre2_flags & PCRE2_DOTALL)
    compile_flags |= G_REGEX_DOTALL;
  if (pcre2_flags & PCRE2_EXTENDED)
    compile_flags |= G_REGEX_EXTENDED;
  if (pcre2_flags & PCRE2_ANCHORED)
    compile_flags |= G_REGEX_ANCHORED;
  if (pcre2_flags & PCRE2_DOLLAR_ENDONLY)
    compile_flags |= G_REGEX_DOLLAR_ENDONLY;
  if (pcre2_flags & PCRE2_UNGREEDY)
    compile_flags |= G_REGEX_UNGREEDY;
  if (!(pcre2_flags & PCRE2_UTF))
    compile_flags |= G_REGEX_RAW;
  if (pcre2_flags & PCRE2_NO_AUTO_CAPTURE)
    compile_flags |= G_REGEX_NO_AUTO_CAPTURE;
  if (pcre2_flags & PCRE2_FIRSTLINE)
    compile_flags |= G_REGEX_FIRSTLINE;
  if (pcre2_flags & PCRE2_DUPNAMES)
    compile_flags |= G_REGEX_DUPNAMES;

  return compile_flags & G_REGEX_COMPILE_MASK;
}

static GRegexMatchFlags
g_regex_match_flags_from_pcre2 (uint32_t pcre2_flags)
{
  GRegexMatchFlags match_flags = G_REGEX_MATCH_DEFAULT;

  if (pcre2_flags & PCRE2_ANCHORED)
    match_flags |= G_REGEX_MATCH_ANCHORED;
  if (pcre2_flags & PCRE2_NOTBOL)
    match_flags |= G_REGEX_MATCH_NOTBOL;
  if (pcre2_flags & PCRE2_NOTEOL)
    match_flags |= G_REGEX_MATCH_NOTEOL;
  if (pcre2_flags & PCRE2_NOTEMPTY)
    match_flags |= G_REGEX_MATCH_NOTEMPTY;
  if (pcre2_flags & PCRE2_PARTIAL_SOFT)
    match_flags |= G_REGEX_MATCH_PARTIAL_SOFT;
  if (pcre2_flags & PCRE2_PARTIAL_HARD)
    match_flags |= G_REGEX_MATCH_PARTIAL_HARD;
  if (pcre2_flags & PCRE2_NOTEMPTY_ATSTART)
    match_flags |= G_REGEX_MATCH_NOTEMPTY_ATSTART;

  return (match_flags & G_REGEX_MATCH_MASK);
}

static uint32_t
get_pcre2_newline_compile_options (GRegexCompileFlags compile_flags)
{
  compile_flags &= G_REGEX_COMPILE_NEWLINE_MASK;

  switch (compile_flags)
    {
    case G_REGEX_NEWLINE_CR:
      return PCRE2_NEWLINE_CR;
    case G_REGEX_NEWLINE_LF:
      return PCRE2_NEWLINE_LF;
    case G_REGEX_NEWLINE_CRLF:
      return PCRE2_NEWLINE_CRLF;
    case G_REGEX_NEWLINE_ANYCRLF:
      return PCRE2_NEWLINE_ANYCRLF;
    default:
      if (compile_flags != 0)
        return 0;

      return PCRE2_NEWLINE_ANY;
    }
}

static uint32_t
get_pcre2_newline_match_options (GRegexMatchFlags match_flags)
{
  switch (match_flags & G_REGEX_MATCH_NEWLINE_MASK)
    {
    case G_REGEX_MATCH_NEWLINE_CR:
      return PCRE2_NEWLINE_CR;
    case G_REGEX_MATCH_NEWLINE_LF:
      return PCRE2_NEWLINE_LF;
    case G_REGEX_MATCH_NEWLINE_CRLF:
      return PCRE2_NEWLINE_CRLF;
    case G_REGEX_MATCH_NEWLINE_ANY:
      return PCRE2_NEWLINE_ANY;
    case G_REGEX_MATCH_NEWLINE_ANYCRLF:
      return PCRE2_NEWLINE_ANYCRLF;
    default:
      return 0;
    }
}

static uint32_t
get_pcre2_bsr_compile_options (GRegexCompileFlags compile_flags)
{
  if (compile_flags & G_REGEX_BSR_ANYCRLF)
    return PCRE2_BSR_ANYCRLF;

  return PCRE2_BSR_UNICODE;
}

static uint32_t
get_pcre2_bsr_match_options (GRegexMatchFlags match_flags)
{
  if (match_flags & G_REGEX_MATCH_BSR_ANYCRLF)
    return PCRE2_BSR_ANYCRLF;

  if (match_flags & G_REGEX_MATCH_BSR_ANY)
    return PCRE2_BSR_UNICODE;

  return 0;
}

static char *
get_pcre2_error_string (int errcode)
{
  PCRE2_UCHAR8 error_msg[2048];
  int err_length;

  err_length = pcre2_get_error_message (errcode, error_msg,
                                        G_N_ELEMENTS (error_msg));

  if (err_length <= 0)
    return NULL;

  /* The array is always filled with a trailing zero */
  g_assert ((size_t) err_length < G_N_ELEMENTS (error_msg));
  return g_memdup2 (error_msg, err_length + 1);
}

static const gchar *
translate_match_error (gint errcode)
{
  switch (errcode)
    {
    case PCRE2_ERROR_NOMATCH:
      /* not an error */
      break;
    case PCRE2_ERROR_NULL:
      /* NULL argument, this should not happen in GRegex */
      g_critical ("A NULL argument was passed to PCRE");
      break;
    case PCRE2_ERROR_BADOPTION:
      return "bad options";
    case PCRE2_ERROR_BADMAGIC:
      return _("corrupted object");
    case PCRE2_ERROR_NOMEMORY:
      return _("out of memory");
    case PCRE2_ERROR_NOSUBSTRING:
      /* not used by pcre2_match() */
      break;
    case PCRE2_ERROR_MATCHLIMIT:
    case PCRE2_ERROR_CALLOUT:
      /* callouts are not implemented */
      break;
    case PCRE2_ERROR_BADUTFOFFSET:
      /* we do not check if strings are valid */
      break;
    case PCRE2_ERROR_PARTIAL:
      /* not an error */
      break;
    case PCRE2_ERROR_INTERNAL:
      return _("internal error");
    case PCRE2_ERROR_DFA_UITEM:
      return _("the pattern contains items not supported for partial matching");
    case PCRE2_ERROR_DFA_UCOND:
      return _("back references as conditions are not supported for partial matching");
    case PCRE2_ERROR_DFA_WSSIZE:
      /* handled expanding the workspace */
      break;
    case PCRE2_ERROR_DFA_RECURSE:
    case PCRE2_ERROR_RECURSIONLIMIT:
      return _("recursion limit reached");
    case PCRE2_ERROR_BADOFFSET:
      return _("bad offset");
    case PCRE2_ERROR_RECURSELOOP:
      return _("recursion loop");
    case PCRE2_ERROR_JIT_BADOPTION:
      /* should not happen in GRegex since we check modes before each match */
      return _("matching mode is requested that was not compiled for JIT");
    default:
      break;
    }
  return NULL;
}

static char *
get_match_error_message (int errcode)
{
  const char *msg = translate_match_error (errcode);
  char *error_string;

  if (msg)
    return g_strdup (msg);

  error_string = get_pcre2_error_string (errcode);

  if (error_string)
    return error_string;

  return g_strdup (_("unknown error"));
}

static void
translate_compile_error (gint *errcode, const gchar **errmsg)
{
  /* If errcode is known we put the translatable error message in
   * errmsg. If errcode is unknown we put the generic
   * G_REGEX_ERROR_COMPILE error code in errcode.
   * Note that there can be more PCRE errors with the same GRegexError
   * and that some PCRE errors are useless for us.
   */
  gint original_errcode = *errcode;

  *errcode = -1;
  *errmsg = NULL;

  switch (original_errcode)
    {
    case PCRE2_ERROR_END_BACKSLASH:
      *errcode = G_REGEX_ERROR_STRAY_BACKSLASH;
      *errmsg = _("\\ at end of pattern");
      break;
    case PCRE2_ERROR_END_BACKSLASH_C:
      *errcode = G_REGEX_ERROR_MISSING_CONTROL_CHAR;
      *errmsg = _("\\c at end of pattern");
      break;
    case PCRE2_ERROR_UNKNOWN_ESCAPE:
    case PCRE2_ERROR_UNSUPPORTED_ESCAPE_SEQUENCE:
      *errcode = G_REGEX_ERROR_UNRECOGNIZED_ESCAPE;
      *errmsg = _("unrecognized character following \\");
      break;
    case PCRE2_ERROR_QUANTIFIER_OUT_OF_ORDER:
      *errcode = G_REGEX_ERROR_QUANTIFIERS_OUT_OF_ORDER;
      *errmsg = _("numbers out of order in {} quantifier");
      break;
    case PCRE2_ERROR_QUANTIFIER_TOO_BIG:
      *errcode = G_REGEX_ERROR_QUANTIFIER_TOO_BIG;
      *errmsg = _("number too big in {} quantifier");
      break;
    case PCRE2_ERROR_MISSING_SQUARE_BRACKET:
      *errcode = G_REGEX_ERROR_UNTERMINATED_CHARACTER_CLASS;
      *errmsg = _("missing terminating ] for character class");
      break;
    case PCRE2_ERROR_ESCAPE_INVALID_IN_CLASS:
      *errcode = G_REGEX_ERROR_INVALID_ESCAPE_IN_CHARACTER_CLASS;
      *errmsg = _("invalid escape sequence in character class");
      break;
    case PCRE2_ERROR_CLASS_RANGE_ORDER:
      *errcode = G_REGEX_ERROR_RANGE_OUT_OF_ORDER;
      *errmsg = _("range out of order in character class");
      break;
    case PCRE2_ERROR_QUANTIFIER_INVALID:
    case PCRE2_ERROR_INTERNAL_UNEXPECTED_REPEAT:
      *errcode = G_REGEX_ERROR_NOTHING_TO_REPEAT;
      *errmsg = _("nothing to repeat");
      break;
    case PCRE2_ERROR_INVALID_AFTER_PARENS_QUERY:
      *errcode = G_REGEX_ERROR_UNRECOGNIZED_CHARACTER;
      *errmsg = _("unrecognized character after (? or (?-");
      break;
    case PCRE2_ERROR_POSIX_CLASS_NOT_IN_CLASS:
      *errcode = G_REGEX_ERROR_POSIX_NAMED_CLASS_OUTSIDE_CLASS;
      *errmsg = _("POSIX named classes are supported only within a class");
      break;
    case PCRE2_ERROR_POSIX_NO_SUPPORT_COLLATING:
      *errcode = G_REGEX_ERROR_POSIX_COLLATING_ELEMENTS_NOT_SUPPORTED;
      *errmsg = _("POSIX collating elements are not supported");
      break;
    case PCRE2_ERROR_MISSING_CLOSING_PARENTHESIS:
    case PCRE2_ERROR_UNMATCHED_CLOSING_PARENTHESIS:
    case PCRE2_ERROR_PARENS_QUERY_R_MISSING_CLOSING:
      *errcode = G_REGEX_ERROR_UNMATCHED_PARENTHESIS;
      *errmsg = _("missing terminating )");
      break;
    case PCRE2_ERROR_BAD_SUBPATTERN_REFERENCE:
      *errcode = G_REGEX_ERROR_INEXISTENT_SUBPATTERN_REFERENCE;
      *errmsg = _("reference to non-existent subpattern");
      break;
    case PCRE2_ERROR_MISSING_COMMENT_CLOSING:
      *errcode = G_REGEX_ERROR_UNTERMINATED_COMMENT;
      *errmsg = _("missing ) after comment");
      break;
    case PCRE2_ERROR_PATTERN_TOO_LARGE:
      *errcode = G_REGEX_ERROR_EXPRESSION_TOO_LARGE;
      *errmsg = _("regular expression is too large");
      break;
    case PCRE2_ERROR_MISSING_CONDITION_CLOSING:
      *errcode = G_REGEX_ERROR_MALFORMED_CONDITION;
      *errmsg = _("malformed number or name after (?(");
      break;
    case PCRE2_ERROR_LOOKBEHIND_NOT_FIXED_LENGTH:
      *errcode = G_REGEX_ERROR_VARIABLE_LENGTH_LOOKBEHIND;
      *errmsg = _("lookbehind assertion is not fixed length");
      break;
    case PCRE2_ERROR_TOO_MANY_CONDITION_BRANCHES:
      *errcode = G_REGEX_ERROR_TOO_MANY_CONDITIONAL_BRANCHES;
      *errmsg = _("conditional group contains more than two branches");
      break;
    case PCRE2_ERROR_CONDITION_ASSERTION_EXPECTED:
      *errcode = G_REGEX_ERROR_ASSERTION_EXPECTED;
      *errmsg = _("assertion expected after (?(");
      break;
    case PCRE2_ERROR_BAD_RELATIVE_REFERENCE:
      *errcode = G_REGEX_ERROR_INVALID_RELATIVE_REFERENCE;
      *errmsg = _("a numbered reference must not be zero");
      break;
    case PCRE2_ERROR_UNKNOWN_POSIX_CLASS:
      *errcode = G_REGEX_ERROR_UNKNOWN_POSIX_CLASS_NAME;
      *errmsg = _("unknown POSIX class name");
      break;
    case PCRE2_ERROR_CODE_POINT_TOO_BIG:
    case PCRE2_ERROR_INVALID_HEXADECIMAL:
      *errcode = G_REGEX_ERROR_HEX_CODE_TOO_LARGE;
      *errmsg = _("character value in \\x{...} sequence is too large");
      break;
    case PCRE2_ERROR_LOOKBEHIND_INVALID_BACKSLASH_C:
      *errcode = G_REGEX_ERROR_SINGLE_BYTE_MATCH_IN_LOOKBEHIND;
      *errmsg = _("\\C not allowed in lookbehind assertion");
      break;
    case PCRE2_ERROR_MISSING_NAME_TERMINATOR:
      *errcode = G_REGEX_ERROR_MISSING_SUBPATTERN_NAME_TERMINATOR;
      *errmsg = _("missing terminator in subpattern name");
      break;
    case PCRE2_ERROR_DUPLICATE_SUBPATTERN_NAME:
      *errcode = G_REGEX_ERROR_DUPLICATE_SUBPATTERN_NAME;
      *errmsg = _("two named subpatterns have the same name");
      break;
    case PCRE2_ERROR_MALFORMED_UNICODE_PROPERTY:
      *errcode = G_REGEX_ERROR_MALFORMED_PROPERTY;
      *errmsg = _("malformed \\P or \\p sequence");
      break;
    case PCRE2_ERROR_UNKNOWN_UNICODE_PROPERTY:
      *errcode = G_REGEX_ERROR_UNKNOWN_PROPERTY;
      *errmsg = _("unknown property name after \\P or \\p");
      break;
    case PCRE2_ERROR_SUBPATTERN_NAME_TOO_LONG:
      *errcode = G_REGEX_ERROR_SUBPATTERN_NAME_TOO_LONG;
      *errmsg = _("subpattern name is too long (maximum 32 characters)");
      break;
    case PCRE2_ERROR_TOO_MANY_NAMED_SUBPATTERNS:
      *errcode = G_REGEX_ERROR_TOO_MANY_SUBPATTERNS;
      *errmsg = _("too many named subpatterns (maximum 10,000)");
      break;
    case PCRE2_ERROR_OCTAL_BYTE_TOO_BIG:
      *errcode = G_REGEX_ERROR_INVALID_OCTAL_VALUE;
      *errmsg = _("octal value is greater than \\377");
      break;
    case PCRE2_ERROR_DEFINE_TOO_MANY_BRANCHES:
      *errcode = G_REGEX_ERROR_TOO_MANY_BRANCHES_IN_DEFINE;
      *errmsg = _("DEFINE group contains more than one branch");
      break;
    case PCRE2_ERROR_INTERNAL_UNKNOWN_NEWLINE:
      *errcode = G_REGEX_ERROR_INCONSISTENT_NEWLINE_OPTIONS;
      *errmsg = _("inconsistent NEWLINE options");
      break;
    case PCRE2_ERROR_BACKSLASH_G_SYNTAX:
      *errcode = G_REGEX_ERROR_MISSING_BACK_REFERENCE;
      *errmsg = _("\\g is not followed by a braced, angle-bracketed, or quoted name or "
                  "number, or by a plain number");
      break;
    case PCRE2_ERROR_VERB_ARGUMENT_NOT_ALLOWED:
      *errcode = G_REGEX_ERROR_BACKTRACKING_CONTROL_VERB_ARGUMENT_FORBIDDEN;
      *errmsg = _("an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)");
      break;
    case PCRE2_ERROR_VERB_UNKNOWN:
      *errcode = G_REGEX_ERROR_UNKNOWN_BACKTRACKING_CONTROL_VERB;
      *errmsg = _("(*VERB) not recognized");
      break;
    case PCRE2_ERROR_SUBPATTERN_NUMBER_TOO_BIG:
      *errcode = G_REGEX_ERROR_NUMBER_TOO_BIG;
      *errmsg = _("number is too big");
      break;
    case PCRE2_ERROR_SUBPATTERN_NAME_EXPECTED:
      *errcode = G_REGEX_ERROR_MISSING_SUBPATTERN_NAME;
      *errmsg = _("missing subpattern name after (?&");
      break;
    case PCRE2_ERROR_SUBPATTERN_NAMES_MISMATCH:
      *errcode = G_REGEX_ERROR_EXTRA_SUBPATTERN_NAME;
      *errmsg = _("different names for subpatterns of the same number are not allowed");
      break;
    case PCRE2_ERROR_MARK_MISSING_ARGUMENT:
      *errcode = G_REGEX_ERROR_BACKTRACKING_CONTROL_VERB_ARGUMENT_REQUIRED;
      *errmsg = _("(*MARK) must have an argument");
      break;
    case PCRE2_ERROR_BACKSLASH_C_SYNTAX:
      *errcode = G_REGEX_ERROR_INVALID_CONTROL_CHAR;
      *errmsg = _( "\\c must be followed by an ASCII character");
      break;
    case PCRE2_ERROR_BACKSLASH_K_SYNTAX:
      *errcode = G_REGEX_ERROR_MISSING_NAME;
      *errmsg = _("\\k is not followed by a braced, angle-bracketed, or quoted name");
      break;
    case PCRE2_ERROR_BACKSLASH_N_IN_CLASS:
      *errcode = G_REGEX_ERROR_NOT_SUPPORTED_IN_CLASS;
      *errmsg = _("\\N is not supported in a class");
      break;
    case PCRE2_ERROR_VERB_NAME_TOO_LONG:
      *errcode = G_REGEX_ERROR_NAME_TOO_LONG;
      *errmsg = _("name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)");
      break;
    case PCRE2_ERROR_INTERNAL_CODE_OVERFLOW:
      *errcode = G_REGEX_ERROR_INTERNAL;
      *errmsg = _("code overflow");
      break;
    case PCRE2_ERROR_UNRECOGNIZED_AFTER_QUERY_P:
      *errcode = G_REGEX_ERROR_UNRECOGNIZED_CHARACTER;
      *errmsg = _("unrecognized character after (?P");
      break;
    case PCRE2_ERROR_INTERNAL_OVERRAN_WORKSPACE:
      *errcode = G_REGEX_ERROR_INTERNAL;
      *errmsg = _("overran compiling workspace");
      break;
    case PCRE2_ERROR_INTERNAL_MISSING_SUBPATTERN:
      *errcode = G_REGEX_ERROR_INTERNAL;
      *errmsg = _("previously-checked referenced subpattern not found");
      break;
    case PCRE2_ERROR_HEAP_FAILED:
    case PCRE2_ERROR_INTERNAL_PARSED_OVERFLOW:
    case PCRE2_ERROR_UNICODE_NOT_SUPPORTED:
    case PCRE2_ERROR_UNICODE_DISALLOWED_CODE_POINT:
    case PCRE2_ERROR_NO_SURROGATES_IN_UTF16:
    case PCRE2_ERROR_INTERNAL_BAD_CODE_LOOKBEHINDS:
    case PCRE2_ERROR_UNICODE_PROPERTIES_UNAVAILABLE:
    case PCRE2_ERROR_INTERNAL_STUDY_ERROR:
    case PCRE2_ERROR_UTF_IS_DISABLED:
    case PCRE2_ERROR_UCP_IS_DISABLED:
    case PCRE2_ERROR_INTERNAL_BAD_CODE_AUTO_POSSESS:
    case PCRE2_ERROR_BACKSLASH_C_LIBRARY_DISABLED:
    case PCRE2_ERROR_INTERNAL_BAD_CODE:
    case PCRE2_ERROR_INTERNAL_BAD_CODE_IN_SKIP:
      *errcode = G_REGEX_ERROR_INTERNAL;
      break;
    case PCRE2_ERROR_INVALID_SUBPATTERN_NAME:
    case PCRE2_ERROR_CLASS_INVALID_RANGE:
    case PCRE2_ERROR_ZERO_RELATIVE_REFERENCE:
    case PCRE2_ERROR_PARENTHESES_STACK_CHECK:
    case PCRE2_ERROR_LOOKBEHIND_TOO_COMPLICATED:
    case PCRE2_ERROR_CALLOUT_NUMBER_TOO_BIG:
    case PCRE2_ERROR_MISSING_CALLOUT_CLOSING:
    case PCRE2_ERROR_ESCAPE_INVALID_IN_VERB:
    case PCRE2_ERROR_NULL_PATTERN:
    case PCRE2_ERROR_BAD_OPTIONS:
    case PCRE2_ERROR_PARENTHESES_NEST_TOO_DEEP:
    case PCRE2_ERROR_BACKSLASH_O_MISSING_BRACE:
    case PCRE2_ERROR_INVALID_OCTAL:
    case PCRE2_ERROR_CALLOUT_STRING_TOO_LONG:
    case PCRE2_ERROR_BACKSLASH_U_CODE_POINT_TOO_BIG:
    case PCRE2_ERROR_MISSING_OCTAL_OR_HEX_DIGITS:
    case PCRE2_ERROR_VERSION_CONDITION_SYNTAX:
    case PCRE2_ERROR_CALLOUT_NO_STRING_DELIMITER:
    case PCRE2_ERROR_CALLOUT_BAD_STRING_DELIMITER:
    case PCRE2_ERROR_BACKSLASH_C_CALLER_DISABLED:
    case PCRE2_ERROR_QUERY_BARJX_NEST_TOO_DEEP:
    case PCRE2_ERROR_PATTERN_TOO_COMPLICATED:
    case PCRE2_ERROR_LOOKBEHIND_TOO_LONG:
    case PCRE2_ERROR_PATTERN_STRING_TOO_LONG:
    case PCRE2_ERROR_BAD_LITERAL_OPTIONS:
    default:
      *errcode = G_REGEX_ERROR_COMPILE;
      break;
    }

  g_assert (*errcode != -1);
}

/* GMatchInfo */

static GMatchInfo *
match_info_new (const GRegex     *regex,
                const gchar      *string,
                gint              string_len,
                gint              start_position,
                GRegexMatchFlags  match_options,
                gboolean          is_dfa)
{
  GMatchInfo *match_info;

  if (string_len < 0)
    string_len = strlen (string);

  match_info = g_new0 (GMatchInfo, 1);
  match_info->ref_count = 1;
  match_info->regex = g_regex_ref ((GRegex *)regex);
  match_info->string = string;
  match_info->string_len = string_len;
  match_info->matches = PCRE2_ERROR_NOMATCH;
  match_info->pos = start_position;
  match_info->match_opts =
    get_pcre2_match_options (match_options, regex->orig_compile_opts);

  pcre2_pattern_info (regex->pcre_re, PCRE2_INFO_CAPTURECOUNT,
                      &match_info->n_subpatterns);

  match_info->match_context = pcre2_match_context_create (NULL);

  if (is_dfa)
    {
      /* These values should be enough for most cases, if they are not
       * enough g_regex_match_all_full() will expand them. */
      match_info->n_workspace = 100;
      match_info->workspace = g_new (gint, match_info->n_workspace);
    }

  match_info->n_offsets = 2;
  match_info->offsets = g_new0 (gint, match_info->n_offsets);
  /* Set an invalid position for the previous match. */
  match_info->offsets[0] = -1;
  match_info->offsets[1] = -1;

  match_info->match_data = pcre2_match_data_create_from_pattern (
      match_info->regex->pcre_re,
      NULL);

  return match_info;
}

static gboolean
recalc_match_offsets (GMatchInfo *match_info,
                      GError     **error)
{
  PCRE2_SIZE *ovector;
  uint32_t ovector_size = 0;
  uint32_t pre_n_offset;
  uint32_t i;

  g_assert (!IS_PCRE2_ERROR (match_info->matches));

  if (match_info->matches == PCRE2_ERROR_PARTIAL)
    ovector_size = 1;
  else if (match_info->matches > 0)
    ovector_size = match_info->matches;

  g_assert (ovector_size != 0);

  if (pcre2_get_ovector_count (match_info->match_data) < ovector_size)
    {
      g_set_error (error, G_REGEX_ERROR, G_REGEX_ERROR_MATCH,
                   _("Error while matching regular expression %s: %s"),
                   match_info->regex->pattern, _("code overflow"));
      return FALSE;
    }

  pre_n_offset = match_info->n_offsets;
  match_info->n_offsets = ovector_size * 2;
  ovector = pcre2_get_ovector_pointer (match_info->match_data);

  if (match_info->n_offsets != pre_n_offset)
    {
      match_info->offsets = g_realloc_n (match_info->offsets,
                                         match_info->n_offsets,
                                         sizeof (gint));
    }

  for (i = 0; i < match_info->n_offsets; i++)
    {
      match_info->offsets[i] = (int) ovector[i];
    }

  return TRUE;
}

static JITStatus
enable_jit_with_match_options (GMatchInfo  *match_info,
                               uint32_t  match_options)
{
  gint retval;
  uint32_t old_jit_options, new_jit_options;

  if (!(match_info->regex->orig_compile_opts & G_REGEX_OPTIMIZE))
    return JIT_STATUS_DISABLED;

  if (match_info->regex->jit_status == JIT_STATUS_DISABLED)
    return JIT_STATUS_DISABLED;

  if (match_options & G_REGEX_PCRE2_JIT_UNSUPPORTED_OPTIONS)
    return JIT_STATUS_DISABLED;

  old_jit_options = match_info->regex->jit_options;
  new_jit_options = old_jit_options | PCRE2_JIT_COMPLETE;
  if (match_options & PCRE2_PARTIAL_HARD)
    new_jit_options |= PCRE2_JIT_PARTIAL_HARD;
  if (match_options & PCRE2_PARTIAL_SOFT)
    new_jit_options |= PCRE2_JIT_PARTIAL_SOFT;

  /* no new options enabled */
  if (new_jit_options == old_jit_options)
    {
      g_assert (match_info->regex->jit_status != JIT_STATUS_DEFAULT);
      return match_info->regex->jit_status;
    }

  retval = pcre2_jit_compile (match_info->regex->pcre_re, new_jit_options);
  if (retval == 0)
    {
      match_info->regex->jit_status = JIT_STATUS_ENABLED;

      match_info->regex->jit_options = new_jit_options;
      /* Set min stack size for JIT to 32KiB and max to 512KiB */
      match_info->jit_stack = pcre2_jit_stack_create (1 << 15, 1 << 19, NULL);
      pcre2_jit_stack_assign (match_info->match_context, NULL, match_info->jit_stack);
    }
  else
    {
      match_info->regex->jit_status = JIT_STATUS_DISABLED;

      switch (retval)
        {
        case PCRE2_ERROR_NOMEMORY:
          g_debug ("JIT compilation was requested with G_REGEX_OPTIMIZE, "
                   "but JIT was unable to allocate executable memory for the "
                   "compiler. Falling back to interpretive code.");
          break;
        case PCRE2_ERROR_JIT_BADOPTION:
          g_debug ("JIT compilation was requested with G_REGEX_OPTIMIZE, "
                   "but JIT support is not available. Falling back to "
                   "interpretive code.");
          break;
        default:
          g_debug ("JIT compilation was requested with G_REGEX_OPTIMIZE, "
                   "but request for JIT support had unexpectedly failed (error %d). "
                   "Falling back to interpretive code.",
                   retval);
          break;
        }
    }

  return match_info->regex->jit_status;

  g_assert_not_reached ();
}

/**
 * g_match_info_get_regex:
 * @match_info: a #GMatchInfo
 *
 * Returns #GRegex object used in @match_info. It belongs to Glib
 * and must not be freed. Use g_regex_ref() if you need to keep it
 * after you free @match_info object.
 *
 * Returns: (transfer none): #GRegex object used in @match_info
 *
 * Since: 2.14
 */
GRegex *
g_match_info_get_regex (const GMatchInfo *match_info)
{
  g_return_val_if_fail (match_info != NULL, NULL);
  return match_info->regex;
}

/**
 * g_match_info_get_string:
 * @match_info: a #GMatchInfo
 *
 * Returns the string searched with @match_info. This is the
 * string passed to g_regex_match() or g_regex_replace() so
 * you may not free it before calling this function.
 *
 * Returns: the string searched with @match_info
 *
 * Since: 2.14
 */
const gchar *
g_match_info_get_string (const GMatchInfo *match_info)
{
  g_return_val_if_fail (match_info != NULL, NULL);
  return match_info->string;
}

/**
 * g_match_info_ref:
 * @match_info: a #GMatchInfo
 *
 * Increases reference count of @match_info by 1.
 *
 * Returns: @match_info
 *
 * Since: 2.30
 */
GMatchInfo       *
g_match_info_ref (GMatchInfo *match_info)
{
  g_return_val_if_fail (match_info != NULL, NULL);
  g_atomic_int_inc (&match_info->ref_count);
  return match_info;
}

/**
 * g_match_info_unref:
 * @match_info: a #GMatchInfo
 *
 * Decreases reference count of @match_info by 1. When reference count drops
 * to zero, it frees all the memory associated with the match_info structure.
 *
 * Since: 2.30
 */
void
g_match_info_unref (GMatchInfo *match_info)
{
  if (g_atomic_int_dec_and_test (&match_info->ref_count))
    {
      g_regex_unref (match_info->regex);
      if (match_info->match_context)
        pcre2_match_context_free (match_info->match_context);
      if (match_info->jit_stack)
        pcre2_jit_stack_free (match_info->jit_stack);
      if (match_info->match_data)
        pcre2_match_data_free (match_info->match_data);
      g_free (match_info->offsets);
      g_free (match_info->workspace);
      g_free (match_info);
    }
}

/**
 * g_match_info_free:
 * @match_info: (nullable): a #GMatchInfo, or %NULL
 *
 * If @match_info is not %NULL, calls g_match_info_unref(); otherwise does
 * nothing.
 *
 * Since: 2.14
 */
void
g_match_info_free (GMatchInfo *match_info)
{
  if (match_info == NULL)
    return;

  g_match_info_unref (match_info);
}

/**
 * g_match_info_next:
 * @match_info: a #GMatchInfo structure
 * @error: location to store the error occurring, or %NULL to ignore errors
 *
 * Scans for the next match using the same parameters of the previous
 * call to g_regex_match_full() or g_regex_match() that returned
 * @match_info.
 *
 * The match is done on the string passed to the match function, so you
 * cannot free it before calling this function.
 *
 * Returns: %TRUE is the string matched, %FALSE otherwise
 *
 * Since: 2.14
 */
gboolean
g_match_info_next (GMatchInfo  *match_info,
                   GError     **error)
{
  JITStatus jit_status;
  gint prev_match_start;
  gint prev_match_end;
  uint32_t opts;

  g_return_val_if_fail (match_info != NULL, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
  g_return_val_if_fail (match_info->pos >= 0, FALSE);

  prev_match_start = match_info->offsets[0];
  prev_match_end = match_info->offsets[1];

  if (match_info->pos > match_info->string_len)
    {
      /* we have reached the end of the string */
      match_info->pos = -1;
      match_info->matches = PCRE2_ERROR_NOMATCH;
      return FALSE;
    }

  opts = match_info->regex->match_opts | match_info->match_opts;

  jit_status = enable_jit_with_match_options (match_info, opts);
  if (jit_status == JIT_STATUS_ENABLED)
    {
      match_info->matches = pcre2_jit_match (match_info->regex->pcre_re,
                                             (PCRE2_SPTR8) match_info->string,
                                             match_info->string_len,
                                             match_info->pos,
                                             opts,
                                             match_info->match_data,
                                             match_info->match_context);
      /* if the JIT stack limit was reached, fall back to non-JIT matching in
       * the next conditional statement */
      if (match_info->matches == PCRE2_ERROR_JIT_STACKLIMIT)
        {
          g_debug ("PCRE2 JIT stack limit reached, falling back to "
                   "non-optimized matching.");
          opts |= PCRE2_NO_JIT;
          jit_status = JIT_STATUS_DISABLED;
        }
    }

  if (jit_status != JIT_STATUS_ENABLED)
    {
      match_info->matches = pcre2_match (match_info->regex->pcre_re,
                                         (PCRE2_SPTR8) match_info->string,
                                         match_info->string_len,
                                         match_info->pos,
                                         opts,
                                         match_info->match_data,
                                         match_info->match_context);
    }

  if (IS_PCRE2_ERROR (match_info->matches))
    {
      gchar *error_msg = get_match_error_message (match_info->matches);

      g_set_error (error, G_REGEX_ERROR, G_REGEX_ERROR_MATCH,
                   _("Error while matching regular expression %s: %s"),
                   match_info->regex->pattern, error_msg);
      g_clear_pointer (&error_msg, g_free);
      return FALSE;
    }
  else if (match_info->matches == 0)
    {
      /* info->offsets is too small. */
      match_info->n_offsets *= 2;
      match_info->offsets = g_realloc_n (match_info->offsets,
                                         match_info->n_offsets,
                                         sizeof (gint));

      pcre2_match_data_free (match_info->match_data);
      match_info->match_data = pcre2_match_data_create (match_info->n_offsets, NULL);

      return g_match_info_next (match_info, error);
    }
  else if (match_info->matches == PCRE2_ERROR_NOMATCH)
    {
      /* We're done with this match info */
      match_info->pos = -1;
      return FALSE;
    }
  else
    if (!recalc_match_offsets (match_info, error))
      return FALSE;

  /* avoid infinite loops if the pattern is an empty string or something
   * equivalent */
  if (match_info->pos == match_info->offsets[1])
    {
      if (match_info->pos > match_info->string_len)
        {
          /* we have reached the end of the string */
          match_info->pos = -1;
          match_info->matches = PCRE2_ERROR_NOMATCH;
          return FALSE;
        }

      match_info->pos = NEXT_CHAR (match_info->regex,
                                   &match_info->string[match_info->pos]) -
                                   match_info->string;
    }
  else
    {
      match_info->pos = match_info->offsets[1];
    }

  g_assert (match_info->matches < 0 ||
            (uint32_t) match_info->matches <= match_info->n_subpatterns + 1);

  /* it's possible to get two identical matches when we are matching
   * empty strings, for instance if the pattern is "(?=[A-Z0-9])" and
   * the string is "RegExTest" we have:
   *  - search at position 0: match from 0 to 0
   *  - search at position 1: match from 3 to 3
   *  - search at position 3: match from 3 to 3 (duplicate)
   *  - search at position 4: match from 5 to 5
   *  - search at position 5: match from 5 to 5 (duplicate)
   *  - search at position 6: no match -> stop
   * so we have to ignore the duplicates.
   * see bug #515944: http://bugzilla.gnome.org/show_bug.cgi?id=515944 */
  if (match_info->matches >= 0 &&
      prev_match_start == match_info->offsets[0] &&
      prev_match_end == match_info->offsets[1])
    {
      /* ignore this match and search the next one */
      return g_match_info_next (match_info, error);
    }

  return match_info->matches >= 0;
}

/**
 * g_match_info_matches:
 * @match_info: a #GMatchInfo structure
 *
 * Returns whether the previous match operation succeeded.
 *
 * Returns: %TRUE if the previous match operation succeeded,
 *   %FALSE otherwise
 *
 * Since: 2.14
 */
gboolean
g_match_info_matches (const GMatchInfo *match_info)
{
  g_return_val_if_fail (match_info != NULL, FALSE);

  return match_info->matches >= 0;
}

/**
 * g_match_info_get_match_count:
 * @match_info: a #GMatchInfo structure
 *
 * Retrieves the number of matched substrings (including substring 0,
 * that is the whole matched text), so 1 is returned if the pattern
 * has no substrings in it and 0 is returned if the match failed.
 *
 * If the last match was obtained using the DFA algorithm, that is
 * using g_regex_match_all() or g_regex_match_all_full(), the retrieved
 * count is not that of the number of capturing parentheses but that of
 * the number of matched substrings.
 *
 * Returns: Number of matched substrings, or -1 if an error occurred
 *
 * Since: 2.14
 */
gint
g_match_info_get_match_count (const GMatchInfo *match_info)
{
  g_return_val_if_fail (match_info, -1);

  if (match_info->matches == PCRE2_ERROR_NOMATCH)
    /* no match */
    return 0;
  else if (match_info->matches < PCRE2_ERROR_NOMATCH)
    /* error */
    return -1;
  else
    /* match */
    return match_info->matches;
}

/**
 * g_match_info_is_partial_match:
 * @match_info: a #GMatchInfo structure
 *
 * Usually if the string passed to g_regex_match*() matches as far as
 * it goes, but is too short to match the entire pattern, %FALSE is
 * returned. There are circumstances where it might be helpful to
 * distinguish this case from other cases in which there is no match.
 *
 * Consider, for example, an application where a human is required to
 * type in data for a field with specific formatting requirements. An
 * example might be a date in the form ddmmmyy, defined by the pattern
 * "^\d?\d(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d\d$".
 * If the application sees the user’s keystrokes one by one, and can
 * check that what has been typed so far is potentially valid, it is
 * able to raise an error as soon as a mistake is made.
 *
 * GRegex supports the concept of partial matching by means of the
 * %G_REGEX_MATCH_PARTIAL_SOFT and %G_REGEX_MATCH_PARTIAL_HARD flags.
 * When they are used, the return code for
 * g_regex_match() or g_regex_match_full() is, as usual, %TRUE
 * for a complete match, %FALSE otherwise. But, when these functions
 * return %FALSE, you can check if the match was partial calling
 * g_match_info_is_partial_match().
 *
 * The difference between %G_REGEX_MATCH_PARTIAL_SOFT and
 * %G_REGEX_MATCH_PARTIAL_HARD is that when a partial match is encountered
 * with %G_REGEX_MATCH_PARTIAL_SOFT, matching continues to search for a
 * possible complete match, while with %G_REGEX_MATCH_PARTIAL_HARD matching
 * stops at the partial match.
 * When both %G_REGEX_MATCH_PARTIAL_SOFT and %G_REGEX_MATCH_PARTIAL_HARD
 * are set, the latter takes precedence.
 *
 * There were formerly some restrictions on the pattern for partial matching.
 * The restrictions no longer apply.
 *
 * See pcrepartial(3) for more information on partial matching.
 *
 * Returns: %TRUE if the match was partial, %FALSE otherwise
 *
 * Since: 2.14
 */
gboolean
g_match_info_is_partial_match (const GMatchInfo *match_info)
{
  g_return_val_if_fail (match_info != NULL, FALSE);

  return match_info->matches == PCRE2_ERROR_PARTIAL;
}

/**
 * g_match_info_expand_references:
 * @match_info: (nullable): a #GMatchInfo or %NULL
 * @string_to_expand: the string to expand
 * @error: location to store the error occurring, or %NULL to ignore errors
 *
 * Returns a new string containing the text in @string_to_expand with
 * references and escape sequences expanded. References refer to the last
 * match done with @string against @regex and have the same syntax used by
 * g_regex_replace().
 *
 * The @string_to_expand must be UTF-8 encoded even if %G_REGEX_RAW was
 * passed to g_regex_new().
 *
 * The backreferences are extracted from the string passed to the match
 * function, so you cannot call this function after freeing the string.
 *
 * @match_info may be %NULL in which case @string_to_expand must not
 * contain references. For instance "foo\n" does not refer to an actual
 * pattern and '\n' merely will be replaced with \n character,
 * while to expand "\0" (whole match) one needs the result of a match.
 * Use g_regex_check_replacement() to find out whether @string_to_expand
 * contains references.
 *
 * Returns: (nullable): the expanded string, or %NULL if an error occurred
 *
 * Since: 2.14
 */
gchar *
g_match_info_expand_references (const GMatchInfo  *match_info,
                                const gchar       *string_to_expand,
                                GError           **error)
{
  GString *result;
  GList *list;
  GError *tmp_error = NULL;

  g_return_val_if_fail (string_to_expand != NULL, NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);

  list = split_replacement (string_to_expand, &tmp_error);
  if (tmp_error != NULL)
    {
      g_propagate_error (error, tmp_error);
      return NULL;
    }

  if (!match_info && interpolation_list_needs_match (list))
    {
      g_critical ("String '%s' contains references to the match, can't "
                  "expand references without GMatchInfo object",
                  string_to_expand);
      return NULL;
    }

  result = g_string_sized_new (strlen (string_to_expand));
  interpolate_replacement (match_info, result, list);

  g_list_free_full (list, (GDestroyNotify) free_interpolation_data);

  return g_string_free (result, FALSE);
}

/**
 * g_match_info_fetch:
 * @match_info: #GMatchInfo structure
 * @match_num: number of the sub expression
 *
 * Retrieves the text matching the @match_num'th capturing
 * parentheses. 0 is the full text of the match, 1 is the first paren
 * set, 2 the second, and so on.
 *
 * If @match_num is a valid sub pattern but it didn't match anything
 * (e.g. sub pattern 1, matching "b" against "(a)?b") then an empty
 * string is returned.
 *
 * If the match was obtained using the DFA algorithm, that is using
 * g_regex_match_all() or g_regex_match_all_full(), the retrieved
 * string is not that of a set of parentheses but that of a matched
 * substring. Substrings are matched in reverse order of length, so
 * 0 is the longest match.
 *
 * The string is fetched from the string passed to the match function,
 * so you cannot call this function after freeing the string.
 *
 * Returns: (nullable): The matched substring, or %NULL if an error
 *     occurred. You have to free the string yourself
 *
 * Since: 2.14
 */
gchar *
g_match_info_fetch (const GMatchInfo *match_info,
                    gint              match_num)
{
  gchar *match = NULL;
  gint start, end;

  g_return_val_if_fail (match_info != NULL, NULL);
  g_return_val_if_fail (match_num >= 0, NULL);

  /* match_num does not exist or it didn't matched, i.e. matching "b"
   * against "(a)?b" then group 0 is empty. */
  if (!g_match_info_fetch_pos (match_info, match_num, &start, &end))
    match = NULL;
  else if (start == -1)
    match = g_strdup ("");
  else
    match = g_strndup (&match_info->string[start], end - start);

  return match;
}

/**
 * g_match_info_fetch_pos:
 * @match_info: #GMatchInfo structure
 * @match_num: number of the sub expression
 * @start_pos: (out) (optional): pointer to location where to store
 *     the start position, or %NULL
 * @end_pos: (out) (optional): pointer to location where to store
 *     the end position, or %NULL
 *
 * Retrieves the position in bytes of the @match_num'th capturing
 * parentheses. 0 is the full text of the match, 1 is the first
 * paren set, 2 the second, and so on.
 *
 * If @match_num is a valid sub pattern but it didn't match anything
 * (e.g. sub pattern 1, matching "b" against "(a)?b") then @start_pos
 * and @end_pos are set to -1 and %TRUE is returned.
 *
 * If the match was obtained using the DFA algorithm, that is using
 * g_regex_match_all() or g_regex_match_all_full(), the retrieved
 * position is not that of a set of parentheses but that of a matched
 * substring. Substrings are matched in reverse order of length, so
 * 0 is the longest match.
 *
 * Returns: %TRUE if the position was fetched, %FALSE otherwise. If
 *   the position cannot be fetched, @start_pos and @end_pos are left
 *   unchanged
 *
 * Since: 2.14
 */
gboolean
g_match_info_fetch_pos (const GMatchInfo *match_info,
                        gint              match_num,
                        gint             *start_pos,
                        gint             *end_pos)
{
  g_return_val_if_fail (match_info != NULL, FALSE);
  g_return_val_if_fail (match_num >= 0, FALSE);

  /* check whether there was an error */
  if (match_info->matches < 0)
    return FALSE;

  /* make sure the sub expression number they're requesting is less than
   * the total number of sub expressions in the regex. When matching all
   * (g_regex_match_all()), also compare against the number of matches */
  if ((uint32_t) match_num >= MAX (match_info->n_subpatterns + 1, (uint32_t) match_info->matches))
    return FALSE;

  if (start_pos != NULL)
    *start_pos = (match_num < match_info->matches) ? match_info->offsets[2 * match_num] : -1;

  if (end_pos != NULL)
    *end_pos = (match_num < match_info->matches) ? match_info->offsets[2 * match_num + 1] : -1;

  return TRUE;
}

/*
 * Returns number of first matched subpattern with name @name.
 * There may be more than one in case when DUPNAMES is used,
 * and not all subpatterns with that name match;
 * pcre2_substring_number_from_name() does not work in that case.
 */
static gint
get_matched_substring_number (const GMatchInfo *match_info,
                              const gchar      *name)
{
  gint entrysize;
  PCRE2_SPTR first, last;
  guchar *entry;

  if (!(match_info->regex->compile_opts & PCRE2_DUPNAMES))
    return pcre2_substring_number_from_name (match_info->regex->pcre_re, (PCRE2_SPTR8) name);

  /* This code is analogous to code from pcre2_substring.c:
   * pcre2_substring_get_byname() */
  entrysize = pcre2_substring_nametable_scan (match_info->regex->pcre_re,
                                              (PCRE2_SPTR8) name,
                                              &first,
                                              &last);

  if (entrysize <= 0)
    return entrysize;

  for (entry = (guchar*) first; entry <= (guchar*) last; entry += entrysize)
    {
      guint n = (entry[0] << 8) + entry[1];
      if (n * 2 < match_info->n_offsets && match_info->offsets[n * 2] >= 0)
        return n;
    }

  return (first[0] << 8) + first[1];
}

/**
 * g_match_info_fetch_named:
 * @match_info: #GMatchInfo structure
 * @name: name of the subexpression
 *
 * Retrieves the text matching the capturing parentheses named @name.
 *
 * If @name is a valid sub pattern name but it didn't match anything
 * (e.g. sub pattern "X", matching "b" against "(?P<X>a)?b")
 * then an empty string is returned.
 *
 * The string is fetched from the string passed to the match function,
 * so you cannot call this function after freeing the string.
 *
 * Returns: (nullable): The matched substring, or %NULL if an error
 *     occurred. You have to free the string yourself
 *
 * Since: 2.14
 */
gchar *
g_match_info_fetch_named (const GMatchInfo *match_info,
                          const gchar      *name)
{
  gint num;

  g_return_val_if_fail (match_info != NULL, NULL);
  g_return_val_if_fail (name != NULL, NULL);

  num = get_matched_substring_number (match_info, name);
  if (num < 0)
    return NULL;
  else
    return g_match_info_fetch (match_info, num);
}

/**
 * g_match_info_fetch_named_pos:
 * @match_info: #GMatchInfo structure
 * @name: name of the subexpression
 * @start_pos: (out) (optional): pointer to location where to store
 *     the start position, or %NULL
 * @end_pos: (out) (optional): pointer to location where to store
 *     the end position, or %NULL
 *
 * Retrieves the position in bytes of the capturing parentheses named @name.
 *
 * If @name is a valid sub pattern name but it didn't match anything
 * (e.g. sub pattern "X", matching "b" against "(?P<X>a)?b")
 * then @start_pos and @end_pos are set to -1 and %TRUE is returned.
 *
 * Returns: %TRUE if the position was fetched, %FALSE otherwise.
 *     If the position cannot be fetched, @start_pos and @end_pos
 *     are left unchanged.
 *
 * Since: 2.14
 */
gboolean
g_match_info_fetch_named_pos (const GMatchInfo *match_info,
                              const gchar      *name,
                              gint             *start_pos,
                              gint             *end_pos)
{
  gint num;

  g_return_val_if_fail (match_info != NULL, FALSE);
  g_return_val_if_fail (name != NULL, FALSE);

  num = get_matched_substring_number (match_info, name);
  if (num < 0)
    return FALSE;

  return g_match_info_fetch_pos (match_info, num, start_pos, end_pos);
}

/**
 * g_match_info_fetch_all:
 * @match_info: a #GMatchInfo structure
 *
 * Bundles up pointers to each of the matching substrings from a match
 * and stores them in an array of gchar pointers. The first element in
 * the returned array is the match number 0, i.e. the entire matched
 * text.
 *
 * If a sub pattern didn't match anything (e.g. sub pattern 1, matching
 * "b" against "(a)?b") then an empty string is inserted.
 *
 * If the last match was obtained using the DFA algorithm, that is using
 * g_regex_match_all() or g_regex_match_all_full(), the retrieved
 * strings are not that matched by sets of parentheses but that of the
 * matched substring. Substrings are matched in reverse order of length,
 * so the first one is the longest match.
 *
 * The strings are fetched from the string passed to the match function,
 * so you cannot call this function after freeing the string.
 *
 * Returns: (transfer full): a %NULL-terminated array of gchar *
 *     pointers.  It must be freed using g_strfreev(). If the previous
 *     match failed %NULL is returned
 *
 * Since: 2.14
 */
gchar **
g_match_info_fetch_all (const GMatchInfo *match_info)
{
  gchar **result;
  gint i;

  g_return_val_if_fail (match_info != NULL, NULL);

  if (match_info->matches < 0)
    return NULL;

  result = g_new (gchar *, match_info->matches + 1);
  for (i = 0; i < match_info->matches; i++)
    result[i] = g_match_info_fetch (match_info, i);
  result[i] = NULL;

  return result;
}


/* GRegex */

G_DEFINE_QUARK (g-regex-error-quark, g_regex_error)

/**
 * g_regex_ref:
 * @regex: a #GRegex
 *
 * Increases reference count of @regex by 1.
 *
 * Returns: @regex
 *
 * Since: 2.14
 */
GRegex *
g_regex_ref (GRegex *regex)
{
  g_return_val_if_fail (regex != NULL, NULL);
  g_atomic_int_inc (&regex->ref_count);
  return regex;
}

/**
 * g_regex_unref:
 * @regex: a #GRegex
 *
 * Decreases reference count of @regex by 1. When reference count drops
 * to zero, it frees all the memory associated with the regex structure.
 *
 * Since: 2.14
 */
void
g_regex_unref (GRegex *regex)
{
  g_return_if_fail (regex != NULL);

  if (g_atomic_int_dec_and_test (&regex->ref_count))
    {
      g_free (regex->pattern);
      if (regex->pcre_re != NULL)
        pcre2_code_free (regex->pcre_re);
      g_free (regex);
    }
}

static pcre2_code * regex_compile (const gchar  *pattern,
                                   uint32_t      compile_options,
                                   uint32_t      newline_options,
                                   uint32_t      bsr_options,
                                   GError      **error);

static uint32_t get_pcre2_inline_compile_options (pcre2_code *re,
                                                  uint32_t    compile_options);

/**
 * g_regex_new:
 * @pattern: the regular expression
 * @compile_options: compile options for the regular expression, or 0
 * @match_options: match options for the regular expression, or 0
 * @error: return location for a #GError
 *
 * Compiles the regular expression to an internal form, and does
 * the initial setup of the #GRegex structure.
 *
 * Returns: (nullable): a #GRegex structure or %NULL if an error occurred. Call
 *   g_regex_unref() when you are done with it
 *
 * Since: 2.14
 */
GRegex *
g_regex_new (const gchar         *pattern,
             GRegexCompileFlags   compile_options,
             GRegexMatchFlags     match_options,
             GError             **error)
{
  GRegex *regex;
  pcre2_code *re;
  static gsize initialised = 0;
  uint32_t pcre_compile_options;
  uint32_t pcre_match_options;
  uint32_t newline_options;
  uint32_t bsr_options;

  g_return_val_if_fail (pattern != NULL, NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  g_return_val_if_fail ((compile_options & ~(G_REGEX_COMPILE_MASK |
                                             G_REGEX_JAVASCRIPT_COMPAT)) == 0, NULL);
G_GNUC_END_IGNORE_DEPRECATIONS
  g_return_val_if_fail ((match_options & ~G_REGEX_MATCH_MASK) == 0, NULL);

  if (g_once_init_enter (&initialised))
    {
      int supports_utf8;

      pcre2_config (PCRE2_CONFIG_UNICODE, &supports_utf8);
      if (!supports_utf8)
        g_critical (_("PCRE library is compiled without UTF8 support"));

      g_once_init_leave (&initialised, supports_utf8 ? 1 : 2);
    }

  if (G_UNLIKELY (initialised != 1))
    {
      g_set_error_literal (error, G_REGEX_ERROR, G_REGEX_ERROR_COMPILE, 
                           _("PCRE library is compiled with incompatible options"));
      return NULL;
    }

  pcre_compile_options = get_pcre2_compile_options (compile_options);
  pcre_match_options = get_pcre2_match_options (match_options, compile_options);

  newline_options = get_pcre2_newline_match_options (match_options);
  if (newline_options == 0)
    newline_options = get_pcre2_newline_compile_options (compile_options);

  if (newline_options == 0)
    {
      g_set_error (error, G_REGEX_ERROR, G_REGEX_ERROR_INCONSISTENT_NEWLINE_OPTIONS,
                   "Invalid newline flags");
      return NULL;
    }

  bsr_options = get_pcre2_bsr_match_options (match_options);
  if (!bsr_options)
    bsr_options = get_pcre2_bsr_compile_options (compile_options);

  re = regex_compile (pattern, pcre_compile_options,
                      newline_options, bsr_options, error);
  if (re == NULL)
    return NULL;

  pcre_compile_options |=
    get_pcre2_inline_compile_options (re, pcre_compile_options);

  regex = g_new0 (GRegex, 1);
  regex->ref_count = 1;
  regex->pattern = g_strdup (pattern);
  regex->pcre_re = re;
  regex->compile_opts = pcre_compile_options;
  regex->orig_compile_opts = compile_options;
  regex->match_opts = pcre_match_options;
  regex->orig_match_opts = match_options;

  return regex;
}

static pcre2_code *
regex_compile (const gchar  *pattern,
               uint32_t      compile_options,
               uint32_t      newline_options,
               uint32_t      bsr_options,
               GError      **error)
{
  pcre2_code *re;
  pcre2_compile_context *context;
  const gchar *errmsg;
  PCRE2_SIZE erroffset;
  gint errcode;

  context = pcre2_compile_context_create (NULL);

  /* set newline options */
  if (pcre2_set_newline (context, newline_options) != 0)
    {
      g_set_error (error, G_REGEX_ERROR,
                   G_REGEX_ERROR_INCONSISTENT_NEWLINE_OPTIONS,
                   "Invalid newline flags");
      pcre2_compile_context_free (context);
      return NULL;
    }

  /* set bsr options */
  if (pcre2_set_bsr (context, bsr_options) != 0)
    {
      g_set_error (error, G_REGEX_ERROR,
                   G_REGEX_ERROR_INCONSISTENT_NEWLINE_OPTIONS,
                   "Invalid BSR flags");
      pcre2_compile_context_free (context);
      return NULL;
    }

  /* In case UTF-8 mode is used, also set PCRE2_NO_UTF_CHECK */
  if (compile_options & PCRE2_UTF)
    compile_options |= PCRE2_NO_UTF_CHECK;

  compile_options |= PCRE2_UCP;

  /* compile the pattern */
  re = pcre2_compile ((PCRE2_SPTR8) pattern,
                      PCRE2_ZERO_TERMINATED,
                      compile_options,
                      &errcode,
                      &erroffset,
                      context);
  pcre2_compile_context_free (context);

  /* if the compilation failed, set the error member and return
   * immediately */
  if (re == NULL)
    {
      GError *tmp_error;
      gchar *offset_str;
      gchar *pcre2_errmsg = NULL;
      int original_errcode;

      /* Translate the PCRE error code to GRegexError and use a translated
       * error message if possible */
      original_errcode = errcode;
      translate_compile_error (&errcode, &errmsg);

      if (!errmsg)
        {
          errmsg = _("unknown error");
          pcre2_errmsg = get_pcre2_error_string (original_errcode);
        }

      /* PCRE uses byte offsets but we want to show character offsets */
      erroffset = g_utf8_pointer_to_offset (pattern, &pattern[erroffset]);

      offset_str = g_strdup_printf ("%" G_GSIZE_FORMAT, erroffset);
      tmp_error = g_error_new (G_REGEX_ERROR, errcode,
                               _("Error while compiling regular expression ‘%s’ "
                                 "at char %s: %s"),
                               pattern, offset_str,
                               pcre2_errmsg ? pcre2_errmsg : errmsg);
      g_propagate_error (error, tmp_error);
      g_free (offset_str);
      g_clear_pointer (&pcre2_errmsg, g_free);

      return NULL;
    }

  return re;
}

static uint32_t
get_pcre2_inline_compile_options (pcre2_code *re,
                                  uint32_t    compile_options)
{
  uint32_t pcre_compile_options;
  uint32_t nonpcre_compile_options;

  /* For options set at the beginning of the pattern, pcre puts them into
   * compile options, e.g. "(?i)foo" will make the pcre structure store
   * PCRE2_CASELESS even though it wasn't explicitly given for compilation. */
  nonpcre_compile_options = compile_options & G_REGEX_COMPILE_NONPCRE_MASK;
  pcre2_pattern_info (re, PCRE2_INFO_ALLOPTIONS, &pcre_compile_options);
  compile_options = pcre_compile_options & G_REGEX_PCRE2_COMPILE_MASK;
  compile_options |= nonpcre_compile_options;

  if (!(compile_options & PCRE2_DUPNAMES))
    {
      uint32_t jchanged = 0;
      pcre2_pattern_info (re, PCRE2_INFO_JCHANGED, &jchanged);
      if (jchanged)
        compile_options |= PCRE2_DUPNAMES;
    }

  return compile_options;
}

/**
 * g_regex_get_pattern:
 * @regex: a #GRegex structure
 *
 * Gets the pattern string associated with @regex, i.e. a copy of
 * the string passed to g_regex_new().
 *
 * Returns: the pattern of @regex
 *
 * Since: 2.14
 */
const gchar *
g_regex_get_pattern (const GRegex *regex)
{
  g_return_val_if_fail (regex != NULL, NULL);

  return regex->pattern;
}

/**
 * g_regex_get_max_backref:
 * @regex: a #GRegex
 *
 * Returns the number of the highest back reference
 * in the pattern, or 0 if the pattern does not contain
 * back references.
 *
 * Returns: the number of the highest back reference
 *
 * Since: 2.14
 */
gint
g_regex_get_max_backref (const GRegex *regex)
{
  uint32_t value;

  pcre2_pattern_info (regex->pcre_re, PCRE2_INFO_BACKREFMAX, &value);

  return value;
}

/**
 * g_regex_get_capture_count:
 * @regex: a #GRegex
 *
 * Returns the number of capturing subpatterns in the pattern.
 *
 * Returns: the number of capturing subpatterns
 *
 * Since: 2.14
 */
gint
g_regex_get_capture_count (const GRegex *regex)
{
  uint32_t value;

  pcre2_pattern_info (regex->pcre_re, PCRE2_INFO_CAPTURECOUNT, &value);

  return value;
}

/**
 * g_regex_get_has_cr_or_lf:
 * @regex: a #GRegex structure
 *
 * Checks whether the pattern contains explicit CR or LF references.
 *
 * Returns: %TRUE if the pattern contains explicit CR or LF references
 *
 * Since: 2.34
 */
gboolean
g_regex_get_has_cr_or_lf (const GRegex *regex)
{
  uint32_t value;

  pcre2_pattern_info (regex->pcre_re, PCRE2_INFO_HASCRORLF, &value);

  return !!value;
}

/**
 * g_regex_get_max_lookbehind:
 * @regex: a #GRegex structure
 *
 * Gets the number of characters in the longest lookbehind assertion in the
 * pattern. This information is useful when doing multi-segment matching using
 * the partial matching facilities.
 *
 * Returns: the number of characters in the longest lookbehind assertion.
 *
 * Since: 2.38
 */
gint
g_regex_get_max_lookbehind (const GRegex *regex)
{
  uint32_t max_lookbehind;

  pcre2_pattern_info (regex->pcre_re, PCRE2_INFO_MAXLOOKBEHIND,
                      &max_lookbehind);

  return max_lookbehind;
}

/**
 * g_regex_get_compile_flags:
 * @regex: a #GRegex
 *
 * Returns the compile options that @regex was created with.
 *
 * Depending on the version of PCRE that is used, this may or may not
 * include flags set by option expressions such as `(?i)` found at the
 * top-level within the compiled pattern.
 *
 * Returns: flags from #GRegexCompileFlags
 *
 * Since: 2.26
 */
GRegexCompileFlags
g_regex_get_compile_flags (const GRegex *regex)
{
  GRegexCompileFlags extra_flags;
  uint32_t info_value;

  g_return_val_if_fail (regex != NULL, 0);

  /* Preserve original G_REGEX_OPTIMIZE */
  extra_flags = (regex->orig_compile_opts & G_REGEX_OPTIMIZE);

  /* Also include the newline options */
  pcre2_pattern_info (regex->pcre_re, PCRE2_INFO_NEWLINE, &info_value);
  switch (info_value)
    {
    case PCRE2_NEWLINE_ANYCRLF:
      extra_flags |= G_REGEX_NEWLINE_ANYCRLF;
      break;
    case PCRE2_NEWLINE_CRLF:
      extra_flags |= G_REGEX_NEWLINE_CRLF;
      break;
    case PCRE2_NEWLINE_LF:
      extra_flags |= G_REGEX_NEWLINE_LF;
      break;
    case PCRE2_NEWLINE_CR:
      extra_flags |= G_REGEX_NEWLINE_CR;
      break;
    default:
      break;
    }

  /* Also include the bsr options */
  pcre2_pattern_info (regex->pcre_re, PCRE2_INFO_BSR, &info_value);
  switch (info_value)
    {
    case PCRE2_BSR_ANYCRLF:
      extra_flags |= G_REGEX_BSR_ANYCRLF;
      break;
    default:
      break;
    }

  return g_regex_compile_flags_from_pcre2 (regex->compile_opts) | extra_flags;
}

/**
 * g_regex_get_match_flags:
 * @regex: a #GRegex
 *
 * Returns the match options that @regex was created with.
 *
 * Returns: flags from #GRegexMatchFlags
 *
 * Since: 2.26
 */
GRegexMatchFlags
g_regex_get_match_flags (const GRegex *regex)
{
  uint32_t flags;

  g_return_val_if_fail (regex != NULL, 0);

  flags = g_regex_match_flags_from_pcre2 (regex->match_opts);
  flags |= (regex->orig_match_opts & G_REGEX_MATCH_NEWLINE_MASK);
  flags |= (regex->orig_match_opts & (G_REGEX_MATCH_BSR_ANY | G_REGEX_MATCH_BSR_ANYCRLF));

  return flags;
}

/**
 * g_regex_match_simple:
 * @pattern: the regular expression
 * @string: the string to scan for matches
 * @compile_options: compile options for the regular expression, or 0
 * @match_options: match options, or 0
 *
 * Scans for a match in @string for @pattern.
 *
 * This function is equivalent to g_regex_match() but it does not
 * require to compile the pattern with g_regex_new(), avoiding some
 * lines of code when you need just to do a match without extracting
 * substrings, capture counts, and so on.
 *
 * If this function is to be called on the same @pattern more than
 * once, it's more efficient to compile the pattern once with
 * g_regex_new() and then use g_regex_match().
 *
 * Returns: %TRUE if the string matched, %FALSE otherwise
 *
 * Since: 2.14
 */
gboolean
g_regex_match_simple (const gchar        *pattern,
                      const gchar        *string,
                      GRegexCompileFlags  compile_options,
                      GRegexMatchFlags    match_options)
{
  GRegex *regex;
  gboolean result;

  regex = g_regex_new (pattern, compile_options, G_REGEX_MATCH_DEFAULT, NULL);
  if (!regex)
    return FALSE;
  result = g_regex_match_full (regex, string, -1, 0, match_options, NULL, NULL);
  g_regex_unref (regex);
  return result;
}

/**
 * g_regex_match:
 * @regex: a #GRegex structure from g_regex_new()
 * @string: the string to scan for matches
 * @match_options: match options
 * @match_info: (out) (optional): pointer to location where to store
 *     the #GMatchInfo, or %NULL if you do not need it
 *
 * Scans for a match in @string for the pattern in @regex.
 * The @match_options are combined with the match options specified
 * when the @regex structure was created, letting you have more
 * flexibility in reusing #GRegex structures.
 *
 * Unless %G_REGEX_RAW is specified in the options, @string must be valid UTF-8.
 *
 * A #GMatchInfo structure, used to get information on the match,
 * is stored in @match_info if not %NULL. Note that if @match_info
 * is not %NULL then it is created even if the function returns %FALSE,
 * i.e. you must free it regardless if regular expression actually matched.
 *
 * To retrieve all the non-overlapping matches of the pattern in
 * string you can use g_match_info_next().
 *
 * |[<!-- language="C" --> 
 * static void
 * print_uppercase_words (const gchar *string)
 * {
 *   // Print all uppercase-only words.
 *   GRegex *regex;
 *   GMatchInfo *match_info;
 *  
 *   regex = g_regex_new ("[A-Z]+", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL);
 *   g_regex_match (regex, string, 0, &match_info);
 *   while (g_match_info_matches (match_info))
 *     {
 *       gchar *word = g_match_info_fetch (match_info, 0);
 *       g_print ("Found: %s\n", word);
 *       g_free (word);
 *       g_match_info_next (match_info, NULL);
 *     }
 *   g_match_info_free (match_info);
 *   g_regex_unref (regex);
 * }
 * ]|
 *
 * @string is not copied and is used in #GMatchInfo internally. If
 * you use any #GMatchInfo method (except g_match_info_free()) after
 * freeing or modifying @string then the behaviour is undefined.
 *
 * Returns: %TRUE is the string matched, %FALSE otherwise
 *
 * Since: 2.14
 */
gboolean
g_regex_match (const GRegex      *regex,
               const gchar       *string,
               GRegexMatchFlags   match_options,
               GMatchInfo       **match_info)
{
  return g_regex_match_full (regex, string, -1, 0, match_options,
                             match_info, NULL);
}

/**
 * g_regex_match_full:
 * @regex: a #GRegex structure from g_regex_new()
 * @string: (array length=string_len): the string to scan for matches
 * @string_len: the length of @string, in bytes, or -1 if @string is nul-terminated
 * @start_position: starting index of the string to match, in bytes
 * @match_options: match options
 * @match_info: (out) (optional): pointer to location where to store
 *     the #GMatchInfo, or %NULL if you do not need it
 * @error: location to store the error occurring, or %NULL to ignore errors
 *
 * Scans for a match in @string for the pattern in @regex.
 * The @match_options are combined with the match options specified
 * when the @regex structure was created, letting you have more
 * flexibility in reusing #GRegex structures.
 *
 * Setting @start_position differs from just passing over a shortened
 * string and setting %G_REGEX_MATCH_NOTBOL in the case of a pattern
 * that begins with any kind of lookbehind assertion, such as "\b".
 *
 * Unless %G_REGEX_RAW is specified in the options, @string must be valid UTF-8.
 *
 * A #GMatchInfo structure, used to get information on the match, is
 * stored in @match_info if not %NULL. Note that if @match_info is
 * not %NULL then it is created even if the function returns %FALSE,
 * i.e. you must free it regardless if regular expression actually
 * matched.
 *
 * @string is not copied and is used in #GMatchInfo internally. If
 * you use any #GMatchInfo method (except g_match_info_free()) after
 * freeing or modifying @string then the behaviour is undefined.
 *
 * To retrieve all the non-overlapping matches of the pattern in
 * string you can use g_match_info_next().
 *
 * |[<!-- language="C" --> 
 * static void
 * print_uppercase_words (const gchar *string)
 * {
 *   // Print all uppercase-only words.
 *   GRegex *regex;
 *   GMatchInfo *match_info;
 *   GError *error = NULL;
 *   
 *   regex = g_regex_new ("[A-Z]+", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL);
 *   g_regex_match_full (regex, string, -1, 0, 0, &match_info, &error);
 *   while (g_match_info_matches (match_info))
 *     {
 *       gchar *word = g_match_info_fetch (match_info, 0);
 *       g_print ("Found: %s\n", word);
 *       g_free (word);
 *       g_match_info_next (match_info, &error);
 *     }
 *   g_match_info_free (match_info);
 *   g_regex_unref (regex);
 *   if (error != NULL)
 *     {
 *       g_printerr ("Error while matching: %s\n", error->message);
 *       g_error_free (error);
 *     }
 * }
 * ]|
 *
 * Returns: %TRUE is the string matched, %FALSE otherwise
 *
 * Since: 2.14
 */
gboolean
g_regex_match_full (const GRegex      *regex,
                    const gchar       *string,
                    gssize             string_len,
                    gint               start_position,
                    GRegexMatchFlags   match_options,
                    GMatchInfo       **match_info,
                    GError           **error)
{
  GMatchInfo *info;
  gboolean match_ok;

  g_return_val_if_fail (regex != NULL, FALSE);
  g_return_val_if_fail (string != NULL, FALSE);
  g_return_val_if_fail (start_position >= 0, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
  g_return_val_if_fail ((match_options & ~G_REGEX_MATCH_MASK) == 0, FALSE);

  info = match_info_new (regex, string, string_len, start_position,
                         match_options, FALSE);
  match_ok = g_match_info_next (info, error);
  if (match_info != NULL)
    *match_info = info;
  else
    g_match_info_free (info);

  return match_ok;
}

/**
 * g_regex_match_all:
 * @regex: a #GRegex structure from g_regex_new()
 * @string: the string to scan for matches
 * @match_options: match options
 * @match_info: (out) (optional): pointer to location where to store
 *     the #GMatchInfo, or %NULL if you do not need it
 *
 * Using the standard algorithm for regular expression matching only
 * the longest match in the string is retrieved. This function uses
 * a different algorithm so it can retrieve all the possible matches.
 * For more documentation see g_regex_match_all_full().
 *
 * A #GMatchInfo structure, used to get information on the match, is
 * stored in @match_info if not %NULL. Note that if @match_info is
 * not %NULL then it is created even if the function returns %FALSE,
 * i.e. you must free it regardless if regular expression actually
 * matched.
 *
 * @string is not copied and is used in #GMatchInfo internally. If
 * you use any #GMatchInfo method (except g_match_info_free()) after
 * freeing or modifying @string then the behaviour is undefined.
 *
 * Returns: %TRUE is the string matched, %FALSE otherwise
 *
 * Since: 2.14
 */
gboolean
g_regex_match_all (const GRegex      *regex,
                   const gchar       *string,
                   GRegexMatchFlags   match_options,
                   GMatchInfo       **match_info)
{
  return g_regex_match_all_full (regex, string, -1, 0, match_options,
                                 match_info, NULL);
}

/**
 * g_regex_match_all_full:
 * @regex: a #GRegex structure from g_regex_new()
 * @string: (array length=string_len): the string to scan for matches
 * @string_len: the length of @string, in bytes, or -1 if @string is nul-terminated
 * @start_position: starting index of the string to match, in bytes
 * @match_options: match options
 * @match_info: (out) (optional): pointer to location where to store
 *     the #GMatchInfo, or %NULL if you do not need it
 * @error: location to store the error occurring, or %NULL to ignore errors
 *
 * Using the standard algorithm for regular expression matching only
 * the longest match in the @string is retrieved, it is not possible
 * to obtain all the available matches. For instance matching
 * "<a> <b> <c>" against the pattern "<.*>"
 * you get "<a> <b> <c>".
 *
 * This function uses a different algorithm (called DFA, i.e. deterministic
 * finite automaton), so it can retrieve all the possible matches, all
 * starting at the same point in the string. For instance matching
 * "<a> <b> <c>" against the pattern "<.*>;"
 * you would obtain three matches: "<a> <b> <c>",
 * "<a> <b>" and "<a>".
 *
 * The number of matched strings is retrieved using
 * g_match_info_get_match_count(). To obtain the matched strings and
 * their position you can use, respectively, g_match_info_fetch() and
 * g_match_info_fetch_pos(). Note that the strings are returned in
 * reverse order of length; that is, the longest matching string is
 * given first.
 *
 * Note that the DFA algorithm is slower than the standard one and it
 * is not able to capture substrings, so backreferences do not work.
 *
 * Setting @start_position differs from just passing over a shortened
 * string and setting %G_REGEX_MATCH_NOTBOL in the case of a pattern
 * that begins with any kind of lookbehind assertion, such as "\b".
 *
 * Unless %G_REGEX_RAW is specified in the options, @string must be valid UTF-8.
 *
 * A #GMatchInfo structure, used to get information on the match, is
 * stored in @match_info if not %NULL. Note that if @match_info is
 * not %NULL then it is created even if the function returns %FALSE,
 * i.e. you must free it regardless if regular expression actually
 * matched.
 *
 * @string is not copied and is used in #GMatchInfo internally. If
 * you use any #GMatchInfo method (except g_match_info_free()) after
 * freeing or modifying @string then the behaviour is undefined.
 *
 * Returns: %TRUE is the string matched, %FALSE otherwise
 *
 * Since: 2.14
 */
gboolean
g_regex_match_all_full (const GRegex      *regex,
                        const gchar       *string,
                        gssize             string_len,
                        gint               start_position,
                        GRegexMatchFlags   match_options,
                        GMatchInfo       **match_info,
                        GError           **error)
{
  GMatchInfo *info;
  gboolean done;
  pcre2_code *pcre_re;
  gboolean retval;
  uint32_t newline_options;
  uint32_t bsr_options;

  g_return_val_if_fail (regex != NULL, FALSE);
  g_return_val_if_fail (string != NULL, FALSE);
  g_return_val_if_fail (start_position >= 0, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
  g_return_val_if_fail ((match_options & ~G_REGEX_MATCH_MASK) == 0, FALSE);

  newline_options = get_pcre2_newline_match_options (match_options);
  if (!newline_options)
    newline_options = get_pcre2_newline_compile_options (regex->orig_compile_opts);

  bsr_options = get_pcre2_bsr_match_options (match_options);
  if (!bsr_options)
    bsr_options = get_pcre2_bsr_compile_options (regex->orig_compile_opts);

  /* For PCRE2 we need to turn off PCRE2_NO_AUTO_POSSESS, which is an
   * optimization for normal regex matching, but results in omitting some
   * shorter matches here, and an observable behaviour change.
   *
   * DFA matching is rather niche, and very rarely used according to
   * codesearch.debian.net, so don't bother caching the recompiled RE. */
  pcre_re = regex_compile (regex->pattern,
                           regex->compile_opts | PCRE2_NO_AUTO_POSSESS,
                           newline_options, bsr_options, error);
  if (pcre_re == NULL)
    return FALSE;

  info = match_info_new (regex, string, string_len, start_position,
                         match_options, TRUE);

  done = FALSE;
  while (!done)
    {
      done = TRUE;
      info->matches = pcre2_dfa_match (pcre_re,
                                       (PCRE2_SPTR8) info->string, info->string_len,
                                       info->pos,
                                       (regex->match_opts | info->match_opts),
                                       info->match_data,
                                       info->match_context,
                                       info->workspace, info->n_workspace);
      if (info->matches == PCRE2_ERROR_DFA_WSSIZE)
        {
          /* info->workspace is too small. */
          info->n_workspace *= 2;
          info->workspace = g_realloc_n (info->workspace,
                                         info->n_workspace,
                                         sizeof (gint));
          done = FALSE;
        }
      else if (info->matches == 0)
        {
          /* info->offsets is too small. */
          info->n_offsets *= 2;
          info->offsets = g_realloc_n (info->offsets,
                                       info->n_offsets,
                                       sizeof (gint));
          pcre2_match_data_free (info->match_data);
          info->match_data = pcre2_match_data_create (info->n_offsets, NULL);
          done = FALSE;
        }
      else if (IS_PCRE2_ERROR (info->matches))
        {
          gchar *error_msg = get_match_error_message (info->matches);

          g_set_error (error, G_REGEX_ERROR, G_REGEX_ERROR_MATCH,
                       _("Error while matching regular expression %s: %s"),
                       regex->pattern, error_msg);
          g_clear_pointer (&error_msg, g_free);
        }
      else if (info->matches != PCRE2_ERROR_NOMATCH)
        {
          if (!recalc_match_offsets (info, error))
            info->matches = PCRE2_ERROR_NOMATCH;
        }
    }

  pcre2_code_free (pcre_re);

  /* don’t assert that (info->matches <= info->n_subpatterns + 1) as that only
   * holds true for a single match, rather than matching all */

  /* set info->pos to -1 so that a call to g_match_info_next() fails. */
  info->pos = -1;
  retval = info->matches >= 0;

  if (match_info != NULL)
    *match_info = info;
  else
    g_match_info_free (info);

  return retval;
}

/**
 * g_regex_get_string_number:
 * @regex: #GRegex structure
 * @name: name of the subexpression
 *
 * Retrieves the number of the subexpression named @name.
 *
 * Returns: The number of the subexpression or -1 if @name
 *   does not exists
 *
 * Since: 2.14
 */
gint
g_regex_get_string_number (const GRegex *regex,
                           const gchar  *name)
{
  gint num;

  g_return_val_if_fail (regex != NULL, -1);
  g_return_val_if_fail (name != NULL, -1);

  num = pcre2_substring_number_from_name (regex->pcre_re, (PCRE2_SPTR8) name);
  if (num == PCRE2_ERROR_NOSUBSTRING)
    num = -1;

  return num;
}

/**
 * g_regex_split_simple:
 * @pattern: the regular expression
 * @string: the string to scan for matches
 * @compile_options: compile options for the regular expression, or 0
 * @match_options: match options, or 0
 *
 * Breaks the string on the pattern, and returns an array of
 * the tokens. If the pattern contains capturing parentheses,
 * then the text for each of the substrings will also be returned.
 * If the pattern does not match anywhere in the string, then the
 * whole string is returned as the first token.
 *
 * This function is equivalent to g_regex_split() but it does
 * not require to compile the pattern with g_regex_new(), avoiding
 * some lines of code when you need just to do a split without
 * extracting substrings, capture counts, and so on.
 *
 * If this function is to be called on the same @pattern more than
 * once, it's more efficient to compile the pattern once with
 * g_regex_new() and then use g_regex_split().
 *
 * As a special case, the result of splitting the empty string ""
 * is an empty vector, not a vector containing a single string.
 * The reason for this special case is that being able to represent
 * an empty vector is typically more useful than consistent handling
 * of empty elements. If you do need to represent empty elements,
 * you'll need to check for the empty string before calling this
 * function.
 *
 * A pattern that can match empty strings splits @string into
 * separate characters wherever it matches the empty string between
 * characters. For example splitting "ab c" using as a separator
 * "\s*", you will get "a", "b" and "c".
 *
 * Returns: (transfer full): a %NULL-terminated array of strings. Free
 * it using g_strfreev()
 *
 * Since: 2.14
 **/
gchar **
g_regex_split_simple (const gchar        *pattern,
                      const gchar        *string,
                      GRegexCompileFlags  compile_options,
                      GRegexMatchFlags    match_options)
{
  GRegex *regex;
  gchar **result;

  regex = g_regex_new (pattern, compile_options, 0, NULL);
  if (!regex)
    return NULL;

  result = g_regex_split_full (regex, string, -1, 0, match_options, 0, NULL);
  g_regex_unref (regex);
  return result;
}

/**
 * g_regex_split:
 * @regex: a #GRegex structure
 * @string: the string to split with the pattern
 * @match_options: match time option flags
 *
 * Breaks the string on the pattern, and returns an array of the tokens.
 * If the pattern contains capturing parentheses, then the text for each
 * of the substrings will also be returned. If the pattern does not match
 * anywhere in the string, then the whole string is returned as the first
 * token.
 *
 * As a special case, the result of splitting the empty string "" is an
 * empty vector, not a vector containing a single string. The reason for
 * this special case is that being able to represent an empty vector is
 * typically more useful than consistent handling of empty elements. If
 * you do need to represent empty elements, you'll need to check for the
 * empty string before calling this function.
 *
 * A pattern that can match empty strings splits @string into separate
 * characters wherever it matches the empty string between characters.
 * For example splitting "ab c" using as a separator "\s*", you will get
 * "a", "b" and "c".
 *
 * Returns: (transfer full): a %NULL-terminated gchar ** array. Free
 * it using g_strfreev()
 *
 * Since: 2.14
 **/
gchar **
g_regex_split (const GRegex     *regex,
               const gchar      *string,
               GRegexMatchFlags  match_options)
{
  return g_regex_split_full (regex, string, -1, 0,
                             match_options, 0, NULL);
}

/**
 * g_regex_split_full:
 * @regex: a #GRegex structure
 * @string: (array length=string_len): the string to split with the pattern
 * @string_len: the length of @string, in bytes, or -1 if @string is nul-terminated
 * @start_position: starting index of the string to match, in bytes
 * @match_options: match time option flags
 * @max_tokens: the maximum number of tokens to split @string into.
 *   If this is less than 1, the string is split completely
 * @error: return location for a #GError
 *
 * Breaks the string on the pattern, and returns an array of the tokens.
 * If the pattern contains capturing parentheses, then the text for each
 * of the substrings will also be returned. If the pattern does not match
 * anywhere in the string, then the whole string is returned as the first
 * token.
 *
 * As a special case, the result of splitting the empty string "" is an
 * empty vector, not a vector containing a single string. The reason for
 * this special case is that being able to represent an empty vector is
 * typically more useful than consistent handling of empty elements. If
 * you do need to represent empty elements, you'll need to check for the
 * empty string before calling this function.
 *
 * A pattern that can match empty strings splits @string into separate
 * characters wherever it matches the empty string between characters.
 * For example splitting "ab c" using as a separator "\s*", you will get
 * "a", "b" and "c".
 *
 * Setting @start_position differs from just passing over a shortened
 * string and setting %G_REGEX_MATCH_NOTBOL in the case of a pattern
 * that begins with any kind of lookbehind assertion, such as "\b".
 *
 * Returns: (transfer full): a %NULL-terminated gchar ** array. Free
 * it using g_strfreev()
 *
 * Since: 2.14
 **/
gchar **
g_regex_split_full (const GRegex      *regex,
                    const gchar       *string,
                    gssize             string_len,
                    gint               start_position,
                    GRegexMatchFlags   match_options,
                    gint               max_tokens,
                    GError           **error)
{
  GError *tmp_error = NULL;
  GMatchInfo *match_info;
  GList *list, *last;
  gint i;
  gint token_count;
  gboolean match_ok;
  /* position of the last separator. */
  gint last_separator_end;
  /* was the last match 0 bytes long? */
  gboolean last_match_is_empty;
  /* the returned array of char **s */
  gchar **string_list;

  g_return_val_if_fail (regex != NULL, NULL);
  g_return_val_if_fail (string != NULL, NULL);
  g_return_val_if_fail (start_position >= 0, NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
  g_return_val_if_fail ((match_options & ~G_REGEX_MATCH_MASK) == 0, NULL);

  if (max_tokens <= 0)
    max_tokens = G_MAXINT;

  if (string_len < 0)
    string_len = strlen (string);

  /* zero-length string */
  if (string_len - start_position == 0)
    return g_new0 (gchar *, 1);

  if (max_tokens == 1)
    {
      string_list = g_new0 (gchar *, 2);
      string_list[0] = g_strndup (&string[start_position],
                                  string_len - start_position);
      return string_list;
    }

  list = NULL;
  token_count = 0;
  last_separator_end = start_position;
  last_match_is_empty = FALSE;

  match_ok = g_regex_match_full (regex, string, string_len, start_position,
                                 match_options, &match_info, &tmp_error);

  while (tmp_error == NULL)
    {
      if (match_ok)
        {
          last_match_is_empty =
                    (match_info->offsets[0] == match_info->offsets[1]);

          /* we need to skip empty separators at the same position of the end
           * of another separator. e.g. the string is "a b" and the separator
           * is " *", so from 1 to 2 we have a match and at position 2 we have
           * an empty match. */
          if (last_separator_end != match_info->offsets[1])
            {
              gchar *token;
              gint match_count;

              token = g_strndup (string + last_separator_end,
                                 match_info->offsets[0] - last_separator_end);
              list = g_list_prepend (list, token);
              token_count++;

              /* if there were substrings, these need to be added to
               * the list. */
              match_count = g_match_info_get_match_count (match_info);
              if (match_count > 1)
                {
                  for (i = 1; i < match_count; i++)
                    list = g_list_prepend (list, g_match_info_fetch (match_info, i));
                }
            }
        }
      else
        {
          /* if there was no match, copy to end of string. */
          if (!last_match_is_empty)
            {
              gchar *token = g_strndup (string + last_separator_end,
                                        match_info->string_len - last_separator_end);
              list = g_list_prepend (list, token);
            }
          /* no more tokens, end the loop. */
          break;
        }

      /* -1 to leave room for the last part. */
      if (token_count >= max_tokens - 1)
        {
          /* we have reached the maximum number of tokens, so we copy
           * the remaining part of the string. */
          if (last_match_is_empty)
            {
              /* the last match was empty, so we have moved one char
               * after the real position to avoid empty matches at the
               * same position. */
              match_info->pos = PREV_CHAR (regex, &string[match_info->pos]) - string;
            }
          /* the if is needed in the case we have terminated the available
           * tokens, but we are at the end of the string, so there are no
           * characters left to copy. */
          if (string_len > match_info->pos)
            {
              gchar *token = g_strndup (string + match_info->pos,
                                        string_len - match_info->pos);
              list = g_list_prepend (list, token);
            }
          /* end the loop. */
          break;
        }

      last_separator_end = match_info->pos;
      if (last_match_is_empty)
        /* if the last match was empty, g_match_info_next() has moved
         * forward to avoid infinite loops, but we still need to copy that
         * character. */
        last_separator_end = PREV_CHAR (regex, &string[last_separator_end]) - string;

      match_ok = g_match_info_next (match_info, &tmp_error);
    }
  g_match_info_free (match_info);
  if (tmp_error != NULL)
    {
      g_propagate_error (error, tmp_error);
      g_list_free_full (list, g_free);
      return NULL;
    }

  string_list = g_new (gchar *, g_list_length (list) + 1);
  i = 0;
  for (last = g_list_last (list); last; last = g_list_previous (last))
    string_list[i++] = last->data;
  string_list[i] = NULL;
  g_list_free (list);

  return string_list;
}

enum
{
  REPL_TYPE_STRING,
  REPL_TYPE_CHARACTER,
  REPL_TYPE_SYMBOLIC_REFERENCE,
  REPL_TYPE_NUMERIC_REFERENCE,
  REPL_TYPE_CHANGE_CASE
};

typedef enum
{
  CHANGE_CASE_NONE         = 1 << 0,
  CHANGE_CASE_UPPER        = 1 << 1,
  CHANGE_CASE_LOWER        = 1 << 2,
  CHANGE_CASE_UPPER_SINGLE = 1 << 3,
  CHANGE_CASE_LOWER_SINGLE = 1 << 4,
  CHANGE_CASE_SINGLE_MASK  = CHANGE_CASE_UPPER_SINGLE | CHANGE_CASE_LOWER_SINGLE,
  CHANGE_CASE_LOWER_MASK   = CHANGE_CASE_LOWER | CHANGE_CASE_LOWER_SINGLE,
  CHANGE_CASE_UPPER_MASK   = CHANGE_CASE_UPPER | CHANGE_CASE_UPPER_SINGLE
} ChangeCase;

struct _InterpolationData
{
  gchar     *text;
  gint       type;
  gint       num;
  gchar      c;
  ChangeCase change_case;
};

static void
free_interpolation_data (InterpolationData *data)
{
  g_free (data->text);
  g_free (data);
}

static const gchar *
expand_escape (const gchar        *replacement,
               const gchar        *p,
               InterpolationData  *data,
               GError            **error)
{
  const gchar *q, *r;
  gint x, d, h, i;
  const gchar *error_detail;
  gint base = 0;
  GError *tmp_error = NULL;

  p++;
  switch (*p)
    {
    case 't':
      p++;
      data->c = '\t';
      data->type = REPL_TYPE_CHARACTER;
      break;
    case 'n':
      p++;
      data->c = '\n';
      data->type = REPL_TYPE_CHARACTER;
      break;
    case 'v':
      p++;
      data->c = '\v';
      data->type = REPL_TYPE_CHARACTER;
      break;
    case 'r':
      p++;
      data->c = '\r';
      data->type = REPL_TYPE_CHARACTER;
      break;
    case 'f':
      p++;
      data->c = '\f';
      data->type = REPL_TYPE_CHARACTER;
      break;
    case 'a':
      p++;
      data->c = '\a';
      data->type = REPL_TYPE_CHARACTER;
      break;
    case 'b':
      p++;
      data->c = '\b';
      data->type = REPL_TYPE_CHARACTER;
      break;
    case '\\':
      p++;
      data->c = '\\';
      data->type = REPL_TYPE_CHARACTER;
      break;
    case 'x':
      p++;
      x = 0;
      if (*p == '{')
        {
          p++;
          do
            {
              h = g_ascii_xdigit_value (*p);
              if (h < 0)
                {
                  error_detail = _("hexadecimal digit or “}” expected");
                  goto error;
                }
              x = x * 16 + h;
              p++;
            }
          while (*p != '}');
          p++;
        }
      else
        {
          for (i = 0; i < 2; i++)
            {
              h = g_ascii_xdigit_value (*p);
              if (h < 0)
                {
                  error_detail = _("hexadecimal digit expected");
                  goto error;
                }
              x = x * 16 + h;
              p++;
            }
        }
      data->type = REPL_TYPE_STRING;
      data->text = g_new0 (gchar, 8);
      g_unichar_to_utf8 (x, data->text);
      break;
    case 'l':
      p++;
      data->type = REPL_TYPE_CHANGE_CASE;
      data->change_case = CHANGE_CASE_LOWER_SINGLE;
      break;
    case 'u':
      p++;
      data->type = REPL_TYPE_CHANGE_CASE;
      data->change_case = CHANGE_CASE_UPPER_SINGLE;
      break;
    case 'L':
      p++;
      data->type = REPL_TYPE_CHANGE_CASE;
      data->change_case = CHANGE_CASE_LOWER;
      break;
    case 'U':
      p++;
      data->type = REPL_TYPE_CHANGE_CASE;
      data->change_case = CHANGE_CASE_UPPER;
      break;
    case 'E':
      p++;
      data->type = REPL_TYPE_CHANGE_CASE;
      data->change_case = CHANGE_CASE_NONE;
      break;
    case 'g':
      p++;
      if (*p != '<')
        {
          error_detail = _("missing “<” in symbolic reference");
          goto error;
        }
      q = p + 1;
      do
        {
          p++;
          if (!*p)
            {
              error_detail = _("unfinished symbolic reference");
              goto error;
            }
        }
      while (*p != '>');
      if (p - q == 0)
        {
          error_detail = _("zero-length symbolic reference");
          goto error;
        }
      if (g_ascii_isdigit (*q))
        {
          x = 0;
          do
            {
              h = g_ascii_digit_value (*q);
              if (h < 0)
                {
                  error_detail = _("digit expected");
                  p = q;
                  goto error;
                }
              x = x * 10 + h;
              q++;
            }
          while (q != p);
          data->num = x;
          data->type = REPL_TYPE_NUMERIC_REFERENCE;
        }
      else
        {
          r = q;
          do
            {
              if (!g_ascii_isalnum (*r))
                {
                  error_detail = _("illegal symbolic reference");
                  p = r;
                  goto error;
                }
              r++;
            }
          while (r != p);
          data->text = g_strndup (q, p - q);
          data->type = REPL_TYPE_SYMBOLIC_REFERENCE;
        }
      p++;
      break;
    case '0':
      /* if \0 is followed by a number is an octal number representing a
       * character, else it is a numeric reference. */
      if (g_ascii_digit_value (*g_utf8_next_char (p)) >= 0)
        {
          base = 8;
          p = g_utf8_next_char (p);
        }
      G_GNUC_FALLTHROUGH;
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
      x = 0;
      d = 0;
      for (i = 0; i < 3; i++)
        {
          h = g_ascii_digit_value (*p);
          if (h < 0)
            break;
          if (h > 7)
            {
              if (base == 8)
                break;
              else
                base = 10;
            }
          if (i == 2 && base == 10)
            break;
          x = x * 8 + h;
          d = d * 10 + h;
          p++;
        }
      if (base == 8 || i == 3)
        {
          data->type = REPL_TYPE_STRING;
          data->text = g_new0 (gchar, 8);
          g_unichar_to_utf8 (x, data->text);
        }
      else
        {
          data->type = REPL_TYPE_NUMERIC_REFERENCE;
          data->num = d;
        }
      break;
    case 0:
      error_detail = _("stray final “\\”");
      goto error;
      break;
    default:
      error_detail = _("unknown escape sequence");
      goto error;
    }

  return p;

 error:
  /* G_GSSIZE_FORMAT doesn't work with gettext, so we use %lu */
  tmp_error = g_error_new (G_REGEX_ERROR,
                           G_REGEX_ERROR_REPLACE,
                           _("Error while parsing replacement "
                             "text “%s” at char %lu: %s"),
                           replacement,
                           (gulong)(p - replacement),
                           error_detail);
  g_propagate_error (error, tmp_error);

  return NULL;
}

static GList *
split_replacement (const gchar  *replacement,
                   GError      **error)
{
  GList *list = NULL;
  InterpolationData *data;
  const gchar *p, *start;

  start = p = replacement;
  while (*p)
    {
      if (*p == '\\')
        {
          data = g_new0 (InterpolationData, 1);
          start = p = expand_escape (replacement, p, data, error);
          if (p == NULL)
            {
              g_list_free_full (list, (GDestroyNotify) free_interpolation_data);
              free_interpolation_data (data);

              return NULL;
            }
          list = g_list_prepend (list, data);
        }
      else
        {
          p++;
          if (*p == '\\' || *p == '\0')
            {
              if (p - start > 0)
                {
                  data = g_new0 (InterpolationData, 1);
                  data->text = g_strndup (start, p - start);
                  data->type = REPL_TYPE_STRING;
                  list = g_list_prepend (list, data);
                }
            }
        }
    }

  return g_list_reverse (list);
}

/* Change the case of c based on change_case. */
#define CHANGE_CASE(c, change_case) \
        (((change_case) & CHANGE_CASE_LOWER_MASK) ? \
                g_unichar_tolower (c) : \
                g_unichar_toupper (c))

static void
string_append (GString     *string,
               const gchar *text,
               ChangeCase  *change_case)
{
  gunichar c;

  if (text[0] == '\0')
    return;

  if (*change_case == CHANGE_CASE_NONE)
    {
      g_string_append (string, text);
    }
  else if (*change_case & CHANGE_CASE_SINGLE_MASK)
    {
      c = g_utf8_get_char (text);
      g_string_append_unichar (string, CHANGE_CASE (c, *change_case));
      g_string_append (string, g_utf8_next_char (text));
      *change_case = CHANGE_CASE_NONE;
    }
  else
    {
      while (*text != '\0')
        {
          c = g_utf8_get_char (text);
          g_string_append_unichar (string, CHANGE_CASE (c, *change_case));
          text = g_utf8_next_char (text);
        }
    }
}

static gboolean
interpolate_replacement (const GMatchInfo *match_info,
                         GString          *result,
                         gpointer          data)
{
  GList *list;
  InterpolationData *idata;
  gchar *match;
  ChangeCase change_case = CHANGE_CASE_NONE;

  for (list = data; list; list = list->next)
    {
      idata = list->data;
      switch (idata->type)
        {
        case REPL_TYPE_STRING:
          string_append (result, idata->text, &change_case);
          break;
        case REPL_TYPE_CHARACTER:
          g_string_append_c (result, CHANGE_CASE (idata->c, change_case));
          if (change_case & CHANGE_CASE_SINGLE_MASK)
            change_case = CHANGE_CASE_NONE;
          break;
        case REPL_TYPE_NUMERIC_REFERENCE:
          match = g_match_info_fetch (match_info, idata->num);
          if (match)
            {
              string_append (result, match, &change_case);
              g_free (match);
            }
          break;
        case REPL_TYPE_SYMBOLIC_REFERENCE:
          match = g_match_info_fetch_named (match_info, idata->text);
          if (match)
            {
              string_append (result, match, &change_case);
              g_free (match);
            }
          break;
        case REPL_TYPE_CHANGE_CASE:
          change_case = idata->change_case;
          break;
        }
    }

  return FALSE;
}

/* whether actual match_info is needed for replacement, i.e.
 * whether there are references
 */
static gboolean
interpolation_list_needs_match (GList *list)
{
  while (list != NULL)
    {
      InterpolationData *data = list->data;

      if (data->type == REPL_TYPE_SYMBOLIC_REFERENCE ||
          data->type == REPL_TYPE_NUMERIC_REFERENCE)
        {
          return TRUE;
        }

      list = list->next;
    }

  return FALSE;
}

/**
 * g_regex_replace:
 * @regex: a #GRegex structure
 * @string: (array length=string_len): the string to perform matches against
 * @string_len: the length of @string, in bytes, or -1 if @string is nul-terminated
 * @start_position: starting index of the string to match, in bytes
 * @replacement: text to replace each match with
 * @match_options: options for the match
 * @error: location to store the error occurring, or %NULL to ignore errors
 *
 * Replaces all occurrences of the pattern in @regex with the
 * replacement text. Backreferences of the form '\number' or
 * '\g<number>' in the replacement text are interpolated by the
 * number-th captured subexpression of the match, '\g<name>' refers
 * to the captured subexpression with the given name. '\0' refers
 * to the complete match, but '\0' followed by a number is the octal
 * representation of a character. To include a literal '\' in the
 * replacement, write '\\\\'.
 *
 * There are also escapes that changes the case of the following text:
 *
 * - \l: Convert to lower case the next character
 * - \u: Convert to upper case the next character
 * - \L: Convert to lower case till \E
 * - \U: Convert to upper case till \E
 * - \E: End case modification
 *
 * If you do not need to use backreferences use g_regex_replace_literal().
 *
 * The @replacement string must be UTF-8 encoded even if %G_REGEX_RAW was
 * passed to g_regex_new(). If you want to use not UTF-8 encoded strings
 * you can use g_regex_replace_literal().
 *
 * Setting @start_position differs from just passing over a shortened
 * string and setting %G_REGEX_MATCH_NOTBOL in the case of a pattern that
 * begins with any kind of lookbehind assertion, such as "\b".
 *
 * Returns: a newly allocated string containing the replacements
 *
 * Since: 2.14
 */
gchar *
g_regex_replace (const GRegex      *regex,
                 const gchar       *string,
                 gssize             string_len,
                 gint               start_position,
                 const gchar       *replacement,
                 GRegexMatchFlags   match_options,
                 GError           **error)
{
  gchar *result;
  GList *list;
  GError *tmp_error = NULL;

  g_return_val_if_fail (regex != NULL, NULL);
  g_return_val_if_fail (string != NULL, NULL);
  g_return_val_if_fail (start_position >= 0, NULL);
  g_return_val_if_fail (replacement != NULL, NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
  g_return_val_if_fail ((match_options & ~G_REGEX_MATCH_MASK) == 0, NULL);

  list = split_replacement (replacement, &tmp_error);
  if (tmp_error != NULL)
    {
      g_propagate_error (error, tmp_error);
      return NULL;
    }

  result = g_regex_replace_eval (regex,
                                 string, string_len, start_position,
                                 match_options,
                                 interpolate_replacement,
                                 (gpointer)list,
                                 &tmp_error);
  if (tmp_error != NULL)
    g_propagate_error (error, tmp_error);

  g_list_free_full (list, (GDestroyNotify) free_interpolation_data);

  return result;
}

static gboolean
literal_replacement (const GMatchInfo *match_info,
                     GString          *result,
                     gpointer          data)
{
  g_string_append (result, data);
  return FALSE;
}

/**
 * g_regex_replace_literal:
 * @regex: a #GRegex structure
 * @string: (array length=string_len): the string to perform matches against
 * @string_len: the length of @string, in bytes, or -1 if @string is nul-terminated
 * @start_position: starting index of the string to match, in bytes
 * @replacement: text to replace each match with
 * @match_options: options for the match
 * @error: location to store the error occurring, or %NULL to ignore errors
 *
 * Replaces all occurrences of the pattern in @regex with the
 * replacement text. @replacement is replaced literally, to
 * include backreferences use g_regex_replace().
 *
 * Setting @start_position differs from just passing over a
 * shortened string and setting %G_REGEX_MATCH_NOTBOL in the
 * case of a pattern that begins with any kind of lookbehind
 * assertion, such as "\b".
 *
 * Returns: a newly allocated string containing the replacements
 *
 * Since: 2.14
 */
gchar *
g_regex_replace_literal (const GRegex      *regex,
                         const gchar       *string,
                         gssize             string_len,
                         gint               start_position,
                         const gchar       *replacement,
                         GRegexMatchFlags   match_options,
                         GError           **error)
{
  g_return_val_if_fail (replacement != NULL, NULL);
  g_return_val_if_fail ((match_options & ~G_REGEX_MATCH_MASK) == 0, NULL);

  return g_regex_replace_eval (regex,
                               string, string_len, start_position,
                               match_options,
                               literal_replacement,
                               (gpointer)replacement,
                               error);
}

/**
 * g_regex_replace_eval:
 * @regex: a #GRegex structure from g_regex_new()
 * @string: (array length=string_len): string to perform matches against
 * @string_len: the length of @string, in bytes, or -1 if @string is nul-terminated
 * @start_position: starting index of the string to match, in bytes
 * @match_options: options for the match
 * @eval: (scope call): a function to call for each match
 * @user_data: user data to pass to the function
 * @error: location to store the error occurring, or %NULL to ignore errors
 *
 * Replaces occurrences of the pattern in regex with the output of
 * @eval for that occurrence.
 *
 * Setting @start_position differs from just passing over a shortened
 * string and setting %G_REGEX_MATCH_NOTBOL in the case of a pattern
 * that begins with any kind of lookbehind assertion, such as "\b".
 *
 * The following example uses g_regex_replace_eval() to replace multiple
 * strings at once:
 * |[<!-- language="C" --> 
 * static gboolean
 * eval_cb (const GMatchInfo *info,
 *          GString          *res,
 *          gpointer          data)
 * {
 *   gchar *match;
 *   gchar *r;
 *
 *    match = g_match_info_fetch (info, 0);
 *    r = g_hash_table_lookup ((GHashTable *)data, match);
 *    g_string_append (res, r);
 *    g_free (match);
 *
 *    return FALSE;
 * }
 *
 * ...
 *
 * GRegex *reg;
 * GHashTable *h;
 * gchar *res;
 *
 * h = g_hash_table_new (g_str_hash, g_str_equal);
 *
 * g_hash_table_insert (h, "1", "ONE");
 * g_hash_table_insert (h, "2", "TWO");
 * g_hash_table_insert (h, "3", "THREE");
 * g_hash_table_insert (h, "4", "FOUR");
 *
 * reg = g_regex_new ("1|2|3|4", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL);
 * res = g_regex_replace_eval (reg, text, -1, 0, 0, eval_cb, h, NULL);
 * g_hash_table_destroy (h);
 *
 * ...
 * ]|
 *
 * Returns: a newly allocated string containing the replacements
 *
 * Since: 2.14
 */
gchar *
g_regex_replace_eval (const GRegex        *regex,
                      const gchar         *string,
                      gssize               string_len,
                      gint                 start_position,
                      GRegexMatchFlags     match_options,
                      GRegexEvalCallback   eval,
                      gpointer             user_data,
                      GError             **error)
{
  GMatchInfo *match_info;
  GString *result;
  gint str_pos = 0;
  gboolean done = FALSE;
  GError *tmp_error = NULL;

  g_return_val_if_fail (regex != NULL, NULL);
  g_return_val_if_fail (string != NULL, NULL);
  g_return_val_if_fail (start_position >= 0, NULL);
  g_return_val_if_fail (eval != NULL, NULL);
  g_return_val_if_fail ((match_options & ~G_REGEX_MATCH_MASK) == 0, NULL);

  if (string_len < 0)
    string_len = strlen (string);

  result = g_string_sized_new (string_len);

  /* run down the string making matches. */
  g_regex_match_full (regex, string, string_len, start_position,
                      match_options, &match_info, &tmp_error);
  while (!done && g_match_info_matches (match_info))
    {
      g_string_append_len (result,
                           string + str_pos,
                           match_info->offsets[0] - str_pos);
      done = (*eval) (match_info, result, user_data);
      str_pos = match_info->offsets[1];
      g_match_info_next (match_info, &tmp_error);
    }
  g_match_info_free (match_info);
  if (tmp_error != NULL)
    {
      g_propagate_error (error, tmp_error);
      g_string_free (result, TRUE);
      return NULL;
    }

  g_string_append_len (result, string + str_pos, string_len - str_pos);
  return g_string_free (result, FALSE);
}

/**
 * g_regex_check_replacement:
 * @replacement: the replacement string
 * @has_references: (out) (optional): location to store information about
 *   references in @replacement or %NULL
 * @error: location to store error
 *
 * Checks whether @replacement is a valid replacement string
 * (see g_regex_replace()), i.e. that all escape sequences in
 * it are valid.
 *
 * If @has_references is not %NULL then @replacement is checked
 * for pattern references. For instance, replacement text 'foo\n'
 * does not contain references and may be evaluated without information
 * about actual match, but '\0\1' (whole match followed by first
 * subpattern) requires valid #GMatchInfo object.
 *
 * Returns: whether @replacement is a valid replacement string
 *
 * Since: 2.14
 */
gboolean
g_regex_check_replacement (const gchar  *replacement,
                           gboolean     *has_references,
                           GError      **error)
{
  GList *list;
  GError *tmp = NULL;

  list = split_replacement (replacement, &tmp);

  if (tmp)
  {
    g_propagate_error (error, tmp);
    return FALSE;
  }

  if (has_references)
    *has_references = interpolation_list_needs_match (list);

  g_list_free_full (list, (GDestroyNotify) free_interpolation_data);

  return TRUE;
}

/**
 * g_regex_escape_nul:
 * @string: the string to escape
 * @length: the length of @string
 *
 * Escapes the nul characters in @string to "\x00".  It can be used
 * to compile a regex with embedded nul characters.
 *
 * For completeness, @length can be -1 for a nul-terminated string.
 * In this case the output string will be of course equal to @string.
 *
 * Returns: a newly-allocated escaped string
 *
 * Since: 2.30
 */
gchar *
g_regex_escape_nul (const gchar *string,
                    gint         length)
{
  GString *escaped;
  const gchar *p, *piece_start, *end;
  gint backslashes;

  g_return_val_if_fail (string != NULL, NULL);

  if (length < 0)
    return g_strdup (string);

  end = string + length;
  p = piece_start = string;
  escaped = g_string_sized_new (length + 1);

  backslashes = 0;
  while (p < end)
    {
      switch (*p)
        {
        case '\0':
          if (p != piece_start)
            {
              /* copy the previous piece. */
              g_string_append_len (escaped, piece_start, p - piece_start);
            }
          if ((backslashes & 1) == 0)
            g_string_append_c (escaped, '\\');
          g_string_append_c (escaped, 'x');
          g_string_append_c (escaped, '0');
          g_string_append_c (escaped, '0');
          piece_start = ++p;
          backslashes = 0;
          break;
        case '\\':
          backslashes++;
          ++p;
          break;
        default:
          backslashes = 0;
          p = g_utf8_next_char (p);
          break;
        }
    }

  if (piece_start < end)
    g_string_append_len (escaped, piece_start, end - piece_start);

  return g_string_free (escaped, FALSE);
}

/**
 * g_regex_escape_string:
 * @string: the string to escape
 * @length: the length of @string, in bytes, or -1 if @string is nul-terminated
 *
 * Escapes the special characters used for regular expressions
 * in @string, for instance "a.b*c" becomes "a\.b\*c". This
 * function is useful to dynamically generate regular expressions.
 *
 * @string can contain nul characters that are replaced with "\0",
 * in this case remember to specify the correct length of @string
 * in @length.
 *
 * Returns: a newly-allocated escaped string
 *
 * Since: 2.14
 */
gchar *
g_regex_escape_string (const gchar *string,
                       gint         length)
{
  GString *escaped;
  const char *p, *piece_start, *end;

  g_return_val_if_fail (string != NULL, NULL);

  if (length < 0)
    length = strlen (string);

  end = string + length;
  p = piece_start = string;
  escaped = g_string_sized_new (length + 1);

  while (p < end)
    {
      switch (*p)
        {
        case '\0':
        case '\\':
        case '|':
        case '(':
        case ')':
        case '[':
        case ']':
        case '{':
        case '}':
        case '^':
        case '$':
        case '*':
        case '+':
        case '?':
        case '.':
          if (p != piece_start)
            /* copy the previous piece. */
            g_string_append_len (escaped, piece_start, p - piece_start);
          g_string_append_c (escaped, '\\');
          if (*p == '\0')
            g_string_append_c (escaped, '0');
          else
            g_string_append_c (escaped, *p);
          piece_start = ++p;
          break;
        default:
          p = g_utf8_next_char (p);
          break;
        }
  }

  if (piece_start < end)
    g_string_append_len (escaped, piece_start, end - piece_start);

  return g_string_free (escaped, FALSE);
}
