Esempio n. 1
0
/// A return value of true means all is well (even if no replacements were performed), false
/// indicates an unrecoverable error.
bool regex_replacer_t::replace_matches(const wchar_t *arg) {
    if (regex.code == 0) {
        // pcre2_compile() failed
        return false;
    }

    uint32_t options = PCRE2_SUBSTITUTE_OVERFLOW_LENGTH | PCRE2_SUBSTITUTE_EXTENDED |
                       (opts.all ? PCRE2_SUBSTITUTE_GLOBAL : 0);
    size_t arglen = wcslen(arg);
    PCRE2_SIZE bufsize = (arglen == 0) ? 16 : 2 * arglen;
    wchar_t *output = (wchar_t *)malloc(sizeof(wchar_t) * bufsize);
    int pcre2_rc;

    bool done = false;
    while (!done) {
        if (output == NULL) {
            DIE_MEM();
        }
        PCRE2_SIZE outlen = bufsize;
        pcre2_rc = pcre2_substitute(regex.code, PCRE2_SPTR(arg), arglen,
                                    0,  // start offset
                                    options, regex.match,
                                    0,  // match context
                                    PCRE2_SPTR(replacement.c_str()), PCRE2_ZERO_TERMINATED,
                                    (PCRE2_UCHAR *)output, &outlen);

        if (pcre2_rc != PCRE2_ERROR_NOMEMORY || bufsize >= outlen) {
            done = true;
        } else {
            bufsize = outlen;
            // cppcheck-suppress memleakOnRealloc
            output = (wchar_t *)realloc(output, sizeof(wchar_t) * bufsize);
        }
    }

    bool rc = true;
    if (pcre2_rc < 0) {
        string_error(streams, _(L"%ls: Regular expression substitute error: %ls\n"), argv0,
                     pcre2_strerror(pcre2_rc).c_str());
        rc = false;
    } else {
        if (!opts.quiet) {
            streams.out.append(output);
            streams.out.append(L'\n');
        }
        total_replaced += pcre2_rc;
    }

    free(output);
    return rc;
}
Esempio n. 2
0
char *preg_replace(char *re, char *replacement, char *subject) {
  int rc;

  pcre2_code *compiled_re = get_compiled_re(re);

  PCRE2_SPTR pcre2_subject = (PCRE2_SPTR)subject;
  size_t subject_length = strlen((char *)subject);

  PCRE2_SPTR pcre2_replacement = (PCRE2_SPTR)replacement;
  size_t replacement_length = strlen((char *)replacement);

  PCRE2_UCHAR output[256];
  size_t output_length = 256;

  rc = pcre2_substitute(
    compiled_re,
    pcre2_subject,
    subject_length,
    0,
    PCRE2_SUBSTITUTE_GLOBAL,
    NULL,
    NULL,
    pcre2_replacement,
    replacement_length,
    output,
    &output_length
    );


  if (rc < 0) {

    switch(rc) {
      case PCRE2_ERROR_NOMEMORY:
        printf("Output buffer not large enough\n"); break;
      case PCRE2_ERROR_BADREPLACEMENT:
        printf("Invalid replacement string %s\n", replacement); break;
      default:
       printf("Unknown error %d \n", rc); break;
    }

    exit(1);
  }

  return strndup((char *)output, output_length);
}
Esempio n. 3
0
File: pcre2.c Progetto: waruqi/tbox
tb_char_t const* tb_regex_replace(tb_regex_ref_t self, tb_char_t const* cstr, tb_size_t size, tb_size_t start, tb_char_t const* replace_cstr, tb_size_t replace_size, tb_size_t* plength)
{
    // check
    tb_regex_t* regex = (tb_regex_t*)self;
    tb_assert_and_check_return_val(regex && regex->code && cstr && replace_cstr, tb_null);

    // done
    tb_char_t const* result = tb_null;
    do
    {
        // clear length first
        if (plength) *plength = 0;

        // end?
        tb_check_break(start < size);

        // init options
#ifdef __tb_debug__
        tb_uint32_t options = 0;
#else
        tb_uint32_t options = PCRE2_NO_UTF_CHECK;
#endif
        if (regex->mode & TB_REGEX_MODE_GLOBAL) options |= PCRE2_SUBSTITUTE_GLOBAL;

        // init buffer
        if (!regex->buffer_data)
        {
            regex->buffer_maxn = tb_max(size + replace_size + 64, 256);
            regex->buffer_data = (PCRE2_UCHAR*)tb_malloc_bytes(regex->buffer_maxn);
        }
        tb_assert_and_check_break(regex->buffer_data);

        // done
        tb_long_t   ok = -1;
        PCRE2_SIZE  length = 0;
        while (1)
        {
            // replace it
            length = (PCRE2_SIZE)regex->buffer_maxn;
            ok = pcre2_substitute(regex->code, (PCRE2_SPTR)cstr, (PCRE2_SIZE)size, (PCRE2_SIZE)start, options, tb_null, tb_null, (PCRE2_SPTR)replace_cstr, (PCRE2_SIZE)replace_size, regex->buffer_data, &length);

            // no space?
            if (ok == PCRE2_ERROR_NOMEMORY)
            {
                // grow buffer
                regex->buffer_maxn <<= 1;
                regex->buffer_data = (PCRE2_UCHAR*)tb_ralloc_bytes(regex->buffer_data, regex->buffer_maxn);
                tb_assert_and_check_break(regex->buffer_data);
            }
            // failed
            else if (ok < 0)
            {
#if defined(__tb_debug__) && !defined(TB_CONFIG_OS_WINDOWS)
                // get error info
                PCRE2_UCHAR info[256];
                pcre2_get_error_message(ok, info, sizeof(info));

                // trace
                tb_trace_d("replace failed at offset %lu: error: %ld, %s\n", start, ok, info);
#endif

                // end
                break;
            }
            else break;
        }

        // check
        tb_check_break(ok > 0);
        tb_assert_and_check_break(length < regex->buffer_maxn);

        // end
        regex->buffer_data[length] = '\0';

        // trace
        tb_trace_d("    replace: [%lu]: %s", length, regex->buffer_data);

        // save length 
        if (plength) *plength = (tb_size_t)length;

        // ok
        result = (tb_char_t const*)regex->buffer_data;

    } while (0);

    // ok?
    return result;
}
Esempio n. 4
0
    bool replace_matches(const wchar_t *arg)
    {
        // A return value of true means all is well (even if no replacements
        // were performed), false indicates an unrecoverable error.
        if (regex.code == 0)
        {
            // pcre2_compile() failed
            return false;
        }

        uint32_t options = opts.all ? PCRE2_SUBSTITUTE_GLOBAL : 0;
        size_t arglen = wcslen(arg);
        PCRE2_SIZE bufsize = (arglen == 0) ? 16 : 2 * arglen;
        wchar_t *output = (wchar_t *)malloc(sizeof(wchar_t) * bufsize);
        if (output == 0)
        {
            DIE_MEM();
        }
        int pcre2_rc = 0;
        for (;;)
        {
            PCRE2_SIZE outlen = bufsize;
            pcre2_rc = pcre2_substitute(
                            regex.code,
                            PCRE2_SPTR(arg),
                            arglen,
                            0,  // start offset
                            options,
                            regex.match,
                            0,  // match context
                            PCRE2_SPTR(replacement.c_str()),
                            PCRE2_ZERO_TERMINATED,
                            (PCRE2_UCHAR *)output,
                            &outlen);

            if (pcre2_rc == PCRE2_ERROR_NOMEMORY)
            {
                if (bufsize < MAX_REPLACE_SIZE)
                {
                    bufsize = std::min(2 * bufsize, MAX_REPLACE_SIZE);
                    output = (wchar_t *)realloc(output, sizeof(wchar_t) * bufsize);
                    if (output == 0)
                    {
                        DIE_MEM();
                    }
                    continue;
                }
                string_error(streams, _(L"%ls: Replacement string too large\n"), argv0);
                free(output);
                return false;
            }
            break;
        }

        bool rc = true;
        if (pcre2_rc < 0)
        {
            string_error(streams, _(L"%ls: Regular expression substitute error: %ls\n"),
                    argv0, pcre2_strerror(pcre2_rc).c_str());
            rc = false;
        }
        else
        {
            if (!opts.quiet)
            {
                streams.out.append(output);
                streams.out.append(L'\n');
            }
            total_replaced += pcre2_rc;
        }

        free(output);
        return rc;
    }