47  pcre2_code *prcode = 
nullptr;
 
   52    pcre2_compile_context *
const ccontext = pcre2compilecontext();
 
   53    size_t erroroffset = -1;
 
   54    prcode = pcre2_compile ((
const uint8_t*) pattern.
c_str(), PCRE2_ZERO_TERMINATED, flags_to_pcre2_compile_options (flags), &errorcode, &erroroffset, ccontext);
 
   56      log (
"Re: failed to compile regex, error=%d: %s", errorcode, pattern);
 
   60    pcre2_code_free (prcode);
 
   65    pcre2_match_data *md = pcre2_match_data_create_from_pattern (prcode, 
nullptr);
 
   68    const int ret = pcre2_match (prcode, (
const uint8_t*) input.
c_str(), PCRE2_ZERO_TERMINATED, 0 , MATCH_OPTIONS, md, 
nullptr);
 
   71      const uint32_t ovecs = pcre2_get_ovector_count (md);
 
   73        const size_t *ovector = pcre2_get_ovector_pointer (md);
 
   77    pcre2_match_data_free (md); md = 
nullptr;
 
   81  grep (
const String &input, 
int group)
 
   83    pcre2_match_data *md = pcre2_match_data_create_from_pattern (prcode, 
nullptr);
 
   86    const int ret = pcre2_match (prcode, (
const uint8_t*) input.
c_str(), PCRE2_ZERO_TERMINATED, 0 , MATCH_OPTIONS, md, 
nullptr);
 
   89      const uint32_t ovecs = pcre2_get_ovector_count (md);
 
   91        group = 
uint (-group) < ovecs ? 
uint (-group) : 0;
 
   93        const size_t *ovector = pcre2_get_ovector_pointer (md);
 
   94        const size_t start = ovector[group*2], end = ovector[group*2+1];
 
   95        result.
assign (&input[0] + start, &input[0] + end);
 
   98    pcre2_match_data_free (md); md = 
nullptr;
 
  102  findall (
const String &input_string)
 
  105    pcre2_match_data *md = pcre2_match_data_create_from_pattern (prcode, 
nullptr);
 
  109    const size_t input_length = 
strlen (input_string.
c_str());
 
  110    int ret = pcre2_match (prcode, input, input_length, 0 , MATCH_OPTIONS, md, 
nullptr);
 
  111    size_t *ovector = ret <= 0 ? nullptr : pcre2_get_ovector_pointer (md);
 
  113    if (ret < 1 || ovector[0] > ovector[1]) {
 
  114      errorcode = ret < 0 ? ret : ret == 0 ? PCRE2_ERROR_NOMEMORY : PCRE2_ERROR_BACKSLASH_K_IN_LOOKAROUND;
 
  115      if (ret != PCRE2_ERROR_NOMATCH)
 
  116        log (
"Re: findall matching error, error=%d", errorcode);
 
  117      pcre2_match_data_free (md); md = 
nullptr;
 
  120    result.push_back (
std::string (input + ovector[0], input + ovector[1]));
 
  122    pcre2_pattern_info (prcode, PCRE2_INFO_ALLOPTIONS, &bits);
 
  123    const bool UTF8 = bits & PCRE2_UTF;
 
  124    pcre2_pattern_info (prcode, PCRE2_INFO_NEWLINE, &bits);
 
  125    const bool CRLF_IS_NEWLINE = bits == PCRE2_NEWLINE_ANY || bits == PCRE2_NEWLINE_CRLF || bits == PCRE2_NEWLINE_ANYCRLF;
 
  128        PCRE2_SIZE start_offset = ovector[1];           
 
  130        if (ovector[0] == ovector[1]) {                 
 
  131          if (ovector[0] == input_length)
 
  133          options = PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED;
 
  136          const auto startchar = pcre2_get_startchar (md);
 
  137          if (start_offset <= startchar) {
 
  138            if (startchar >= input_length)
 
  140            start_offset = startchar + 1;             
 
  141            for (; UTF8 && start_offset < input_length; start_offset++)
 
  142              if ((input[start_offset] & 0xc0) != 0x80)
 
  147        ret = pcre2_match (prcode, input, input_length, start_offset, options, md, 
nullptr);
 
  149        if (ret == PCRE2_ERROR_NOMATCH) {
 
  152          ovector[1] = start_offset + 1;                
 
  153          if (CRLF_IS_NEWLINE &&                        
 
  154              start_offset < input_length - 1 &&        
 
  155              input[start_offset] == 
'\r' &&
 
  156              input[start_offset + 1] == 
'\n')
 
  159            while (ovector[1] < input_length) {
 
  160              if ((input[ovector[1]] & 0xc0) != 0x80)
 
  168        if (ret < 1 || ovector[0] > ovector[1]) {
 
  170          errorcode = ret < 0 ? ret : ret == 0 ? PCRE2_ERROR_NOMEMORY : PCRE2_ERROR_BACKSLASH_K_IN_LOOKAROUND;
 
  171          log (
"Re: findall matching error, error=%d", errorcode);
 
  175        result.push_back (
std::string (input + ovector[0], input + ovector[1]));
 
  177    pcre2_match_data_free (md); md = 
nullptr;
 
  183    pcre2_match_data *md = pcre2_match_data_create_from_pattern (prcode, 
nullptr);
 
  184    pcre2_match_context *mc = pcre2_match_context_create (
nullptr);
 
  186      PCRE2_SUBSTITUTE_OVERFLOW_LENGTH |
 
  187      PCRE2_SUBSTITUTE_GLOBAL |
 
  192    callout_data.max_substitutions = maxsubst;
 
  193    auto callout_function = [] (pcre2_substitute_callout_block*, 
void *callout_data_ptr) -> 
int {
 
  194      CalloutData &callout_data = *(CalloutData*) callout_data_ptr;
 
  195      return callout_data.max_substitutions-- >= 1 ? 0 : -1;
 
  197    if (callout_data.max_substitutions < 
SSIZE_MAX)
 
  198      pcre2_set_substitute_callout (mc, callout_function, &callout_data);
 
  200    PCRE2_SIZE outlength = result.
size() - 1;
 
  201    int ret = pcre2_substitute (prcode, (
const uint8_t*) input.
c_str(), PCRE2_ZERO_TERMINATED, 0 , MATCH_OPTIONS, md, mc,
 
  203    if (ret == PCRE2_ERROR_NOMEMORY) {
 
  204      result.
resize (outlength + 128);
 
  205      ret = pcre2_substitute (prcode, (
const uint8_t*) input.
c_str(), PCRE2_ZERO_TERMINATED, 0 , MATCH_OPTIONS, md, mc,
 
  209    pcre2_match_data_free (md); md = 
nullptr;
 
  210    pcre2_match_context_free (mc); mc = 
nullptr;