diff options
author | Oliver Kiddle <opk@zsh.org> | 2023-10-31 01:04:19 +0100 |
---|---|---|
committer | Oliver Kiddle <opk@zsh.org> | 2023-11-02 14:54:59 +0100 |
commit | de635b4ee56c188ccbaf0009027f9d1c0d42af0f (patch) | |
tree | f45a398d019bb7aed4aa02093d5ae0af7ddbe5b9 /Src | |
parent | a9b0ccd661db7292a4ab52b3ffe6fbc8dc8ade4f (diff) | |
download | zsh-de635b4ee56c188ccbaf0009027f9d1c0d42af0f.tar.gz zsh-de635b4ee56c188ccbaf0009027f9d1c0d42af0f.tar.xz zsh-de635b4ee56c188ccbaf0009027f9d1c0d42af0f.zip |
52253: support pcre callouts with shell evaluation of the callout string
Diffstat (limited to 'Src')
-rw-r--r-- | Src/Modules/pcre.c | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/Src/Modules/pcre.c b/Src/Modules/pcre.c index f5cda6d38..e6b59831f 100644 --- a/Src/Modules/pcre.c +++ b/Src/Modules/pcre.c @@ -129,6 +129,31 @@ bin_pcre_study(char *nam, UNUSED(char **args), UNUSED(Options ops), UNUSED(int f } static int +pcre_callout(pcre2_callout_block_8 *block, void *) +{ + Eprog prog; + int ret=0; + + if (!block->callout_number && + ((prog = parse_string((char *) block->callout_string, 0)))) + { + int ef = errflag, lv = lastval; + + setsparam(".pcre.subject", + metafy((char *) block->subject, block->subject_length, META_DUP)); + setiparam(".pcre.pos", block->current_position + 1); + execode(prog, 1, 0, "pcre"); + ret = lastval | errflag; + + /* Restore any user interrupt error status */ + errflag = ef | (errflag & ERRFLAG_INT); + lastval = lv; + } + + return ret; +} + +static int zpcre_get_substrings(pcre2_code *pat, char *arg, pcre2_match_data *mdata, int captured_count, char *matchvar, char *substravar, char *namedassoc, int want_offset_pair, int matchedinarr, int want_begin_end) @@ -339,6 +364,9 @@ bin_pcre_match(char *nam, char **args, Options ops, UNUSED(int func)) plaintext = ztrdup(*args); unmetafy(plaintext, &subject_len); + pcre2_match_context_8 *mcontext = pcre2_match_context_create(NULL); + pcre2_set_callout(mcontext, &pcre_callout, 0); + if (offset_start > 0 && offset_start >= subject_len) ret = PCRE2_ERROR_NOMATCH; else if (use_dfa) { @@ -347,7 +375,7 @@ bin_pcre_match(char *nam, char **args, Options ops, UNUSED(int func)) pcre_mdata = pcre2_match_data_create(capcount, NULL); do { ret = pcre2_dfa_match(pcre_pattern, (PCRE2_SPTR) plaintext, subject_len, - offset_start, 0, pcre_mdata, NULL, (int *) workspace, wscount); + offset_start, 0, pcre_mdata, mcontext, (int *) workspace, wscount); if (ret == PCRE2_ERROR_DFA_WSSIZE) { old = wscount; wscount += wscount / 2; @@ -362,7 +390,7 @@ bin_pcre_match(char *nam, char **args, Options ops, UNUSED(int func)) } else { pcre_mdata = pcre2_match_data_create_from_pattern(pcre_pattern, NULL); ret = pcre2_match(pcre_pattern, (PCRE2_SPTR) plaintext, subject_len, - offset_start, 0, pcre_mdata, NULL); + offset_start, 0, pcre_mdata, mcontext); } if (ret==0) return_value = 0; @@ -380,6 +408,8 @@ bin_pcre_match(char *nam, char **args, Options ops, UNUSED(int func)) if (pcre_mdata) pcre2_match_data_free(pcre_mdata); + if (mcontext) + pcre2_match_context_free(mcontext); zsfree(plaintext); return return_value; |