/* 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>
 *
 * 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 <string.h>

#include <pcre.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"

/**
 * SECTION:gregex
 * @title: Perl-compatible regular expressions
 * @short_description: matches strings against regular expressions
 * @see_also: [Regular expression syntax][glib-regex-syntax]
 *
 * The g_regex_*() functions implement regular
 * expression pattern matching using syntax and semantics similar to
 * Perl regular expression.
 *
 * 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.
 *
 * When setting the %G_REGEX_JAVASCRIPT_COMPAT flag, pattern syntax and pattern
 * matching is changed to be compatible with the way that regular expressions
 * work in JavaScript. More precisely, a lonely ']' character in the pattern
 * is a syntax error; the '\x' escape only allows 0 to 2 hexadecimal digits, and
 * you must use the '\u' escape sequence with 4 hex digits to specify a unicode
 * codepoint instead of '\x' or 'x{....}'. If '\x' or '\u' are not followed by
 * the specified number of hex digits, they match 'x' and 'u' literally; also
 * '\U' always matches 'U' instead of being an error in the pattern. Finally,
 * pattern matching is modified so that back references to an unset subpattern
 * group produces a match with the empty string instead of an error. See
 * pcreapi(3) for more information.
 *
 * 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.
 */

/* Mask of all the possible values for GRegexCompileFlags. */
#define G_REGEX_COMPILE_MASK (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       | \
                              G_REGEX_JAVASCRIPT_COMPAT)

/* Mask of all GRegexCompileFlags values that are (not) passed trough to PCRE */
#define G_REGEX_COMPILE_PCRE_MASK (G_REGEX_COMPILE_MASK & ~G_REGEX_COMPILE_NONPCRE_MASK)
#define G_REGEX_COMPILE_NONPCRE_MASK (G_REGEX_RAW              | \
                                      G_REGEX_OPTIMIZE)

/* Mask of all the possible values for GRegexMatchFlags. */
#define G_REGEX_MATCH_MASK (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)

/* we rely on these flags having the same values */
G_STATIC_ASSERT (G_REGEX_CASELESS          == PCRE_CASELESS);
G_STATIC_ASSERT (G_REGEX_MULTILINE         == PCRE_MULTILINE);
G_STATIC_ASSERT (G_REGEX_DOTALL            == PCRE_DOTALL);
G_STATIC_ASSERT (G_REGEX_EXTENDED          == PCRE_EXTENDED);
G_STATIC_ASSERT (G_REGEX_ANCHORED          == PCRE_ANCHORED);
G_STATIC_ASSERT (G_REGEX_DOLLAR_ENDONLY    == PCRE_DOLLAR_ENDONLY);
G_STATIC_ASSERT (G_REGEX_UNGREEDY          == PCRE_UNGREEDY);
G_STATIC_ASSERT (G_REGEX_NO_AUTO_CAPTURE   == PCRE_NO_AUTO_CAPTURE);
G_STATIC_ASSERT (G_REGEX_FIRSTLINE         == PCRE_FIRSTLINE);
G_STATIC_ASSERT (G_REGEX_DUPNAMES          == PCRE_DUPNAMES);
G_STATIC_ASSERT (G_REGEX_NEWLINE_CR        == PCRE_NEWLINE_CR);
G_STATIC_ASSERT (G_REGEX_NEWLINE_LF        == PCRE_NEWLINE_LF);
G_STATIC_ASSERT (G_REGEX_NEWLINE_CRLF      == PCRE_NEWLINE_CRLF);
G_STATIC_ASSERT (G_REGEX_NEWLINE_ANYCRLF   == PCRE_NEWLINE_ANYCRLF);
G_STATIC_ASSERT (G_REGEX_BSR_ANYCRLF       == PCRE_BSR_ANYCRLF);
G_STATIC_ASSERT (G_REGEX_JAVASCRIPT_COMPAT == PCRE_JAVASCRIPT_COMPAT);

G_STATIC_ASSERT (G_REGEX_MATCH_ANCHORED         == PCRE_ANCHORED);
G_STATIC_ASSERT (G_REGEX_MATCH_NOTBOL           == PCRE_NOTBOL);
G_STATIC_ASSERT (G_REGEX_MATCH_NOTEOL           == PCRE_NOTEOL);
G_STATIC_ASSERT (G_REGEX_MATCH_NOTEMPTY         == PCRE_NOTEMPTY);
G_STATIC_ASSERT (G_REGEX_MATCH_PARTIAL          == PCRE_PARTIAL);
G_STATIC_ASSERT (G_REGEX_MATCH_NEWLINE_CR       == PCRE_NEWLINE_CR);
G_STATIC_ASSERT (G_REGEX_MATCH_NEWLINE_LF       == PCRE_NEWLINE_LF);
G_STATIC_ASSERT (G_REGEX_MATCH_NEWLINE_CRLF     == PCRE_NEWLINE_CRLF);
G_STATIC_ASSERT (G_REGEX_MATCH_NEWLINE_ANY      == PCRE_NEWLINE_ANY);
G_STATIC_ASSERT (G_REGEX_MATCH_NEWLINE_ANYCRLF  == PCRE_NEWLINE_ANYCRLF);
G_STATIC_ASSERT (G_REGEX_MATCH_BSR_ANYCRLF      == PCRE_BSR_ANYCRLF);
G_STATIC_ASSERT (G_REGEX_MATCH_BSR_ANY          == PCRE_BSR_UNICODE);
G_STATIC_ASSERT (G_REGEX_MATCH_PARTIAL_SOFT     == PCRE_PARTIAL_SOFT);
G_STATIC_ASSERT (G_REGEX_MATCH_PARTIAL_HARD     == PCRE_PARTIAL_HARD);
G_STATIC_ASSERT (G_REGEX_MATCH_NOTEMPTY_ATSTART == PCRE_NOTEMPTY_ATSTART);

/* These PCRE flags are unused or not exposed publicly in GRegexFlags, so
 * it should be ok to reuse them for different things.
 */
G_STATIC_ASSERT (G_REGEX_OPTIMIZE          == PCRE_NO_UTF8_CHECK);
G_STATIC_ASSERT (G_REGEX_RAW               == PCRE_UTF8);

/* 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 */
  GRegexMatchFlags match_opts;  /* 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) */
  gint n_subpatterns;           /* total number of sub patterns in the regex */
  gint pos;                     /* position in the string where last match left off */
  gint  n_offsets;              /* number of offsets */
  gint *offsets;                /* array of offsets paired 0,1 ; 2,3 ; 3,4 etc */
  gint *workspace;              /* workspace for pcre_dfa_exec() */
  gint n_workspace;             /* number of workspace elements */
  const gchar *string;          /* string passed to the match function */
  gssize string_len;            /* length of string, in bytes */
};

struct _GRegex
{
  gint ref_count;               /* the ref count for the immutable part (atomic) */
  gchar *pattern;               /* the pattern */
  pcre *pcre_re;                /* compiled form of the pattern */
  GRegexCompileFlags compile_opts;      /* options used at compile time on the pattern */
  GRegexMatchFlags match_opts;  /* options used at match time on the regex */
  pcre_extra *extra;            /* data stored when G_REGEX_OPTIMIZE is used */
};

/* TRUE if ret is an error code, FALSE otherwise. */
#define IS_PCRE_ERROR(ret) ((ret) < PCRE_ERROR_NOMATCH && (ret) != PCRE_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 const gchar *
match_error (gint errcode)
{
  switch (errcode)
    {
    case PCRE_ERROR_NOMATCH:
      /* not an error */
      break;
    case PCRE_ERROR_NULL:
      /* NULL argument, this should not happen in GRegex */
      g_warning ("A NULL argument was passed to PCRE");
      break;
    case PCRE_ERROR_BADOPTION:
      return "bad options";
    case PCRE_ERROR_BADMAGIC:
      return _("corrupted object");
    case PCRE_ERROR_UNKNOWN_OPCODE:
      return N_("internal error or corrupted object");
    case PCRE_ERROR_NOMEMORY:
      return _("out of memory");
    case PCRE_ERROR_NOSUBSTRING:
      /* not used by pcre_exec() */
      break;
    case PCRE_ERROR_MATCHLIMIT:
      return _("backtracking limit reached");
    case PCRE_ERROR_CALLOUT:
      /* callouts are not implemented */
      break;
    case PCRE_ERROR_BADUTF8:
    case PCRE_ERROR_BADUTF8_OFFSET:
      /* we do not check if strings are valid */
      break;
    case PCRE_ERROR_PARTIAL:
      /* not an error */
      break;
    case PCRE_ERROR_BADPARTIAL:
      return _("the pattern contains items not supported for partial matching");
    case PCRE_ERROR_INTERNAL:
      return _("internal error");
    case PCRE_ERROR_BADCOUNT:
      /* negative ovecsize, this should not happen in GRegex */
      g_warning ("A negative ovecsize was passed to PCRE");
      break;
    case PCRE_ERROR_DFA_UITEM:
      return _("the pattern contains items not supported for partial matching");
    case PCRE_ERROR_DFA_UCOND:
      return _("back references as conditions are not supported for partial matching");
    case PCRE_ERROR_DFA_UMLIMIT:
      /* the match_field field is not used in GRegex */
      break;
    case PCRE_ERROR_DFA_WSSIZE:
      /* handled expanding the workspace */
      break;
    case PCRE_ERROR_DFA_RECURSE:
    case PCRE_ERROR_RECURSIONLIMIT:
      return _("recursion limit reached");
    case PCRE_ERROR_BADNEWLINE:
      return _("invalid combination of newline flags");
    case PCRE_ERROR_BADOFFSET:
      return _("bad offset");
    case PCRE_ERROR_SHORTUTF8:
      return _("short utf8");
    case PCRE_ERROR_RECURSELOOP:
      return _("recursion loop");
    default:
      break;
    }
  return _("unknown error");
}

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

  switch (*errcode)
    {
    case G_REGEX_ERROR_STRAY_BACKSLASH:
      *errmsg = _("\\ at end of pattern");
      break;
    case G_REGEX_ERROR_MISSING_CONTROL_CHAR:
      *errmsg = _("\\c at end of pattern");
      break;
    case G_REGEX_ERROR_UNRECOGNIZED_ESCAPE:
      *errmsg = _("unrecognized character following \\");
      break;
    case G_REGEX_ERROR_QUANTIFIERS_OUT_OF_ORDER:
      *errmsg = _("numbers out of order in {} quantifier");
      break;
    case G_REGEX_ERROR_QUANTIFIER_TOO_BIG:
      *errmsg = _("number too big in {} quantifier");
      break;
    case G_REGEX_ERROR_UNTERMINATED_CHARACTER_CLASS:
      *errmsg = _("missing terminating ] for character class");
      break;
    case G_REGEX_ERROR_INVALID_ESCAPE_IN_CHARACTER_CLASS:
      *errmsg = _("invalid escape sequence in character class");
      break;
    case G_REGEX_ERROR_RANGE_OUT_OF_ORDER:
      *errmsg = _("range out of order in character class");
      break;
    case G_REGEX_ERROR_NOTHING_TO_REPEAT:
      *errmsg = _("nothing to repeat");
      break;
    case 111: /* internal error: unexpected repeat */
      *errcode = G_REGEX_ERROR_INTERNAL;
      *errmsg = _("unexpected repeat");
      break;
    case G_REGEX_ERROR_UNRECOGNIZED_CHARACTER:
      *errmsg = _("unrecognized character after (? or (?-");
      break;
    case G_REGEX_ERROR_POSIX_NAMED_CLASS_OUTSIDE_CLASS:
      *errmsg = _("POSIX named classes are supported only within a class");
      break;
    case G_REGEX_ERROR_UNMATCHED_PARENTHESIS:
      *errmsg = _("missing terminating )");
      break;
    case G_REGEX_ERROR_INEXISTENT_SUBPATTERN_REFERENCE:
      *errmsg = _("reference to non-existent subpattern");
      break;
    case G_REGEX_ERROR_UNTERMINATED_COMMENT:
      *errmsg = _("missing ) after comment");
      break;
    case G_REGEX_ERROR_EXPRESSION_TOO_LARGE:
      *errmsg = _("regular expression is too large");
      break;
    case G_REGEX_ERROR_MEMORY_ERROR:
      *errmsg = _("failed to get memory");
      break;
    case 122: /* unmatched parentheses */
      *errcode = G_REGEX_ERROR_UNMATCHED_PARENTHESIS;
      *errmsg = _(") without opening (");
      break;
    case 123: /* internal error: code overflow */
      *errcode = G_REGEX_ERROR_INTERNAL;
      *errmsg = _("code overflow");
      break;
    case 124: /* "unrecognized character after (?<\0 */
      *errcode = G_REGEX_ERROR_UNRECOGNIZED_CHARACTER;
      *errmsg = _("unrecognized character after (?<");
      break;
    case G_REGEX_ERROR_VARIABLE_LENGTH_LOOKBEHIND:
      *errmsg = _("lookbehind assertion is not fixed length");
      break;
    case G_REGEX_ERROR_MALFORMED_CONDITION:
      *errmsg = _("malformed number or name after (?(");
      break;
    case G_REGEX_ERROR_TOO_MANY_CONDITIONAL_BRANCHES:
      *errmsg = _("conditional group contains more than two branches");
      break;
    case G_REGEX_ERROR_ASSERTION_EXPECTED:
      *errmsg = _("assertion expected after (?(");
      break;
    case 129:
      *errcode = G_REGEX_ERROR_UNMATCHED_PARENTHESIS;
      /* translators: '(?R' and '(?[+-]digits' are both meant as (groups of)
       * sequences here, '(?-54' would be an example for the second group.
       */
      *errmsg = _("(?R or (?[+-]digits must be followed by )");
      break;
    case G_REGEX_ERROR_UNKNOWN_POSIX_CLASS_NAME:
      *errmsg = _("unknown POSIX class name");
      break;
    case G_REGEX_ERROR_POSIX_COLLATING_ELEMENTS_NOT_SUPPORTED:
      *errmsg = _("POSIX collating elements are not supported");
      break;
    case G_REGEX_ERROR_HEX_CODE_TOO_LARGE:
      *errmsg = _("character value in \\x{...} sequence is too large");
      break;
    case G_REGEX_ERROR_INVALID_CONDITION:
      *errmsg = _("invalid condition (?(0)");
      break;
    case G_REGEX_ERROR_SINGLE_BYTE_MATCH_IN_LOOKBEHIND:
      *errmsg = _("\\C not allowed in lookbehind assertion");
      break;
    case 137: /* PCRE does not support \\L, \\l, \\N{name}, \\U, or \\u\0 */
      /* A number of Perl escapes are not handled by PCRE.
       * Therefore it explicitly raises ERR37.
       */
      *errcode = G_REGEX_ERROR_UNRECOGNIZED_ESCAPE;
      *errmsg = _("escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported");
      break;
    case G_REGEX_ERROR_INFINITE_LOOP:
      *errmsg = _("recursive call could loop indefinitely");
      break;
    case 141: /* unrecognized character after (?P\0 */
      *errcode = G_REGEX_ERROR_UNRECOGNIZED_CHARACTER;
      *errmsg = _("unrecognized character after (?P");
      break;
    case G_REGEX_ERROR_MISSING_SUBPATTERN_NAME_TERMINATOR:
      *errmsg = _("missing terminator in subpattern name");
      break;
    case G_REGEX_ERROR_DUPLICATE_SUBPATTERN_NAME:
      *errmsg = _("two named subpatterns have the same name");
      break;
    case G_REGEX_ERROR_MALFORMED_PROPERTY:
      *errmsg = _("malformed \\P or \\p sequence");
      break;
    case G_REGEX_ERROR_UNKNOWN_PROPERTY:
      *errmsg = _("unknown property name after \\P or \\p");
      break;
    case G_REGEX_ERROR_SUBPATTERN_NAME_TOO_LONG:
      *errmsg = _("subpattern name is too long (maximum 32 characters)");
      break;
    case G_REGEX_ERROR_TOO_MANY_SUBPATTERNS:
      *errmsg = _("too many named subpatterns (maximum 10,000)");
      break;
    case G_REGEX_ERROR_INVALID_OCTAL_VALUE:
      *errmsg = _("octal value is greater than \\377");
      break;
    case 152: /* internal error: overran compiling workspace */
      *errcode = G_REGEX_ERROR_INTERNAL;
      *errmsg = _("overran compiling workspace");
      break;
    case 153: /* internal error: previously-checked referenced subpattern not found */
      *errcode = G_REGEX_ERROR_INTERNAL;
      *errmsg = _("previously-checked referenced subpattern not found");
      break;
    case G_REGEX_ERROR_TOO_MANY_BRANCHES_IN_DEFINE:
      *errmsg = _("DEFINE group contains more than one branch");
      break;
    case G_REGEX_ERROR_INCONSISTENT_NEWLINE_OPTIONS:
      *errmsg = _("inconsistent NEWLINE options");
      break;
    case 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 G_REGEX_ERROR_INVALID_RELATIVE_REFERENCE:
      *errmsg = _("a numbered reference must not be zero");
      break;
    case G_REGEX_ERROR_BACKTRACKING_CONTROL_VERB_ARGUMENT_FORBIDDEN:
      *errmsg = _("an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)");
      break;
    case G_REGEX_ERROR_UNKNOWN_BACKTRACKING_CONTROL_VERB:
      *errmsg = _("(*VERB) not recognized");
      break;
    case G_REGEX_ERROR_NUMBER_TOO_BIG:
      *errmsg = _("number is too big");
      break;
    case G_REGEX_ERROR_MISSING_SUBPATTERN_NAME:
      *errmsg = _("missing subpattern name after (?&");
      break;
    case G_REGEX_ERROR_MISSING_DIGIT:
      *errmsg = _("digit expected after (?+");
      break;
    case G_REGEX_ERROR_INVALID_DATA_CHARACTER:
      *errmsg = _("] is an invalid data character in JavaScript compatibility mode");
      break;
    case G_REGEX_ERROR_EXTRA_SUBPATTERN_NAME:
      *errmsg = _("different names for subpatterns of the same number are not allowed");
      break;
    case G_REGEX_ERROR_BACKTRACKING_CONTROL_VERB_ARGUMENT_REQUIRED:
      *errmsg = _("(*MARK) must have an argument");
      break;
    case G_REGEX_ERROR_INVALID_CONTROL_CHAR:
      *errmsg = _( "\\c must be followed by an ASCII character");
      break;
    case G_REGEX_ERROR_MISSING_NAME:
      *errmsg = _("\\k is not followed by a braced, angle-bracketed, or quoted name");
      break;
    case G_REGEX_ERROR_NOT_SUPPORTED_IN_CLASS:
      *errmsg = _("\\N is not supported in a class");
      break;
    case G_REGEX_ERROR_TOO_MANY_FORWARD_REFERENCES:
      *errmsg = _("too many forward references");
      break;
    case G_REGEX_ERROR_NAME_TOO_LONG:
      *errmsg = _("name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)");
      break;
    case G_REGEX_ERROR_CHARACTER_VALUE_TOO_LARGE:
      *errmsg = _("character value in \\u.... sequence is too large");
      break;

    case 116: /* erroffset passed as NULL */
      /* This should not happen as we never pass a NULL erroffset */
      g_warning ("erroffset passed as NULL");
      *errcode = G_REGEX_ERROR_COMPILE;
      break;
    case 117: /* unknown option bit(s) set */
      /* This should not happen as we check options before passing them
       * to pcre_compile2() */
      g_warning ("unknown option bit(s) set");
      *errcode = G_REGEX_ERROR_COMPILE;
      break;
    case 132: /* this version of PCRE is compiled without UTF support */
    case 144: /* invalid UTF-8 string */
    case 145: /* support for \\P, \\p, and \\X has not been compiled */
    case 167: /* this version of PCRE is not compiled with Unicode property support */
    case 173: /* disallowed Unicode code point (>= 0xd800 && <= 0xdfff) */
    case 174: /* invalid UTF-16 string */
      /* These errors should not happen as we are using an UTF-8 and UCP-enabled PCRE
       * and we do not check if strings are valid */
    case 170: /* internal error: unknown opcode in find_fixedlength() */
      *errcode = G_REGEX_ERROR_INTERNAL;
      break;

    default:
      *errcode = G_REGEX_ERROR_COMPILE;
    }
}

/* GMatchInfo */

static GMatchInfo *
match_info_new (const GRegex *regex,
                const gchar  *string,
                gint          string_len,
                gint          start_position,
                gint          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 = PCRE_ERROR_NOMATCH;
  match_info->pos = start_position;
  match_info->match_opts = match_options;

  pcre_fullinfo (regex->pcre_re, regex->extra,
                 PCRE_INFO_CAPTURECOUNT, &match_info->n_subpatterns);

  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_offsets = 24;
      match_info->n_workspace = 100;
      match_info->workspace = g_new (gint, match_info->n_workspace);
    }
  else
    {
      match_info->n_offsets = (match_info->n_subpatterns + 1) * 3;
    }

  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;

  return match_info;
}

/**
 * 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: #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);
      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)
{
  gint prev_match_start;
  gint prev_match_end;

  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 = PCRE_ERROR_NOMATCH;
      return FALSE;
    }

  match_info->matches = pcre_exec (match_info->regex->pcre_re,
                                   match_info->regex->extra,
                                   match_info->string,
                                   match_info->string_len,
                                   match_info->pos,
                                   match_info->regex->match_opts | match_info->match_opts,
                                   match_info->offsets,
                                   match_info->n_offsets);
  if (IS_PCRE_ERROR (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, match_error (match_info->matches));
      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 = PCRE_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 <= 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 == PCRE_ERROR_NOMATCH)
    /* no match */
    return 0;
  else if (match_info->matches < PCRE_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 == PCRE_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)
{
  /* we cannot use pcre_get_substring() because it allocates the
   * string using pcre_malloc(). */
  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 (match_num >= MAX (match_info->n_subpatterns + 1, 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;
 * pcre_get_stringnumber() does not work in that case.
 */
static gint
get_matched_substring_number (const GMatchInfo *match_info,
                              const gchar      *name)
{
  gint entrysize;
  gchar *first, *last;
  guchar *entry;

  if (!(match_info->regex->compile_opts & G_REGEX_DUPNAMES))
    return pcre_get_stringnumber (match_info->regex->pcre_re, name);

  /* This code is copied from pcre_get.c: get_first_set() */
  entrysize = pcre_get_stringtable_entries (match_info->regex->pcre_re,
                                            name,
                                            &first,
                                            &last);

  if (entrysize <= 0)
    return entrysize;

  for (entry = (guchar*) first; entry <= (guchar*) last; entry += entrysize)
    {
      gint n = (entry[0] << 8) + entry[1];
      if (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)
{
  /* we cannot use pcre_get_named_substring() because it allocates the
   * string using pcre_malloc(). */
  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)
{
  /* we cannot use pcre_get_substring_list() because the returned value
   * isn't suitable for g_strfreev(). */
  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)
        pcre_free (regex->pcre_re);
      if (regex->extra != NULL)
        pcre_free (regex->extra);
      g_free (regex);
    }
}

/*
 * @match_options: (inout) (optional):
 */
static pcre *regex_compile (const gchar         *pattern,
                            GRegexCompileFlags   compile_options,
                            GRegexCompileFlags  *compile_options_out,
                            GRegexMatchFlags    *match_options,
                            GError             **error);

/**
 * 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;
  pcre *re;
  const gchar *errmsg;
  gboolean optimize = FALSE;
  static gsize initialised = 0;

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

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

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

      pcre_config (PCRE_CONFIG_UNICODE_PROPERTIES, &supports_ucp);
      if (!supports_ucp)
        g_critical (_("PCRE library is compiled without UTF8 properties support"));

      g_once_init_leave (&initialised, supports_utf8 && supports_ucp ? 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;
    }

  /* G_REGEX_OPTIMIZE has the same numeric value of PCRE_NO_UTF8_CHECK,
   * as we do not need to wrap PCRE_NO_UTF8_CHECK. */
  if (compile_options & G_REGEX_OPTIMIZE)
    optimize = TRUE;

  re = regex_compile (pattern, compile_options, &compile_options,
                      &match_options, error);

  if (re == NULL)
    return NULL;

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

  if (optimize)
    {
      regex->extra = pcre_study (regex->pcre_re, 0, &errmsg);
      if (errmsg != NULL)
        {
          GError *tmp_error = g_error_new (G_REGEX_ERROR,
                                           G_REGEX_ERROR_OPTIMIZE,
                                           _("Error while optimizing "
                                             "regular expression %s: %s"),
                                           regex->pattern,
                                           errmsg);
          g_propagate_error (error, tmp_error);

          g_regex_unref (regex);
          return NULL;
        }
    }

  return regex;
}

static pcre *
regex_compile (const gchar         *pattern,
               GRegexCompileFlags   compile_options,
               GRegexCompileFlags  *compile_options_out,
               GRegexMatchFlags    *match_options,
               GError             **error)
{
  pcre *re;
  const gchar *errmsg;
  gint erroffset;
  gint errcode;
  GRegexCompileFlags nonpcre_compile_options;
  unsigned long int pcre_compile_options;

  nonpcre_compile_options = compile_options & G_REGEX_COMPILE_NONPCRE_MASK;

  /* In GRegex the string are, by default, UTF-8 encoded. PCRE
   * instead uses UTF-8 only if required with PCRE_UTF8. */
  if (compile_options & G_REGEX_RAW)
    {
      /* disable utf-8 */
      compile_options &= ~G_REGEX_RAW;
    }
  else
    {
      /* enable utf-8 */
      compile_options |= PCRE_UTF8 | PCRE_NO_UTF8_CHECK;

      if (match_options != NULL)
        *match_options |= PCRE_NO_UTF8_CHECK;
    }

  /* PCRE_NEWLINE_ANY is the default for the internal PCRE but
   * not for the system one. */
  if (!(compile_options & G_REGEX_NEWLINE_CR) &&
      !(compile_options & G_REGEX_NEWLINE_LF))
    {
      compile_options |= PCRE_NEWLINE_ANY;
    }

  compile_options |= PCRE_UCP;

  /* PCRE_BSR_UNICODE is the default for the internal PCRE but
   * possibly not for the system one.
   */
  if (~compile_options & G_REGEX_BSR_ANYCRLF)
    compile_options |= PCRE_BSR_UNICODE;

  /* compile the pattern */
  re = pcre_compile2 (pattern, compile_options, &errcode,
                      &errmsg, &erroffset, NULL);

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

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

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

      tmp_error = g_error_new (G_REGEX_ERROR, errcode,
                               _("Error while compiling regular "
                                 "expression %s at char %d: %s"),
                               pattern, erroffset, errmsg);
      g_propagate_error (error, tmp_error);

      return NULL;
    }

  /* 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
   * PCRE_CASELESS even though it wasn't explicitly given for compilation. */
  pcre_fullinfo (re, NULL, PCRE_INFO_OPTIONS, &pcre_compile_options);
  compile_options = pcre_compile_options & G_REGEX_COMPILE_PCRE_MASK;

  /* Don't leak PCRE_NEWLINE_ANY, which is part of PCRE_NEWLINE_ANYCRLF */
  if ((pcre_compile_options & PCRE_NEWLINE_ANYCRLF) != PCRE_NEWLINE_ANYCRLF)
    compile_options &= ~PCRE_NEWLINE_ANY;

  compile_options |= nonpcre_compile_options;

  if (!(compile_options & G_REGEX_DUPNAMES))
    {
      gboolean jchanged = FALSE;
      pcre_fullinfo (re, NULL, PCRE_INFO_JCHANGED, &jchanged);
      if (jchanged)
        compile_options |= G_REGEX_DUPNAMES;
    }

  if (compile_options_out != 0)
    *compile_options_out = compile_options;

  return re;
}

/**
 * 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)
{
  gint value;

  pcre_fullinfo (regex->pcre_re, regex->extra,
                 PCRE_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)
{
  gint value;

  pcre_fullinfo (regex->pcre_re, regex->extra,
                 PCRE_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)
{
  gint value;

  pcre_fullinfo (regex->pcre_re, regex->extra,
                 PCRE_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)
{
  gint max_lookbehind;

  pcre_fullinfo (regex->pcre_re, regex->extra,
                 PCRE_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)
{
  g_return_val_if_fail (regex != NULL, 0);

  return regex->compile_opts;
}

/**
 * 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)
{
  g_return_val_if_fail (regex != NULL, 0);

  return regex->match_opts & G_REGEX_MATCH_MASK;
}

/**
 * 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, 0, 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]+", 0, 0, 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]+", 0, 0, 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;
  pcre *pcre_re;
  pcre_extra *extra;
  gboolean retval;

  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);

#ifdef PCRE_NO_AUTO_POSSESS
  /* For PCRE >= 8.34 we need to turn off PCRE_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 | PCRE_NO_AUTO_POSSESS,
                           NULL, NULL, error);

  if (pcre_re == NULL)
    return FALSE;

  /* Not bothering to cache the optimization data either, with similar
   * reasoning */
  extra = NULL;
#else
  /* For PCRE < 8.33 the precompiled regex is fine. */
  pcre_re = regex->pcre_re;
  extra = regex->extra;
#endif

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

  done = FALSE;
  while (!done)
    {
      done = TRUE;
      info->matches = pcre_dfa_exec (pcre_re, extra,
                                     info->string, info->string_len,
                                     info->pos,
                                     regex->match_opts | match_options,
                                     info->offsets, info->n_offsets,
                                     info->workspace, info->n_workspace);
      if (info->matches == PCRE_ERROR_DFA_WSSIZE)
        {
          /* info->workspace is too small. */
          info->n_workspace *= 2;
          info->workspace = g_realloc (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 (info->offsets,
                                     info->n_offsets * sizeof (gint));
          done = FALSE;
        }
      else if (IS_PCRE_ERROR (info->matches))
        {
          g_set_error (error, G_REGEX_ERROR, G_REGEX_ERROR_MATCH,
                       _("Error while matching regular expression %s: %s"),
                       regex->pattern, match_error (info->matches));
        }
    }

#ifdef PCRE_NO_AUTO_POSSESS
  pcre_free (pcre_re);
#endif

  /* 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 = pcre_get_stringnumber (regex->pcre_re, name);
  if (num == PCRE_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: 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", 0, 0, 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: (array length=length): 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);
}
