mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-05-23 12:41:29 +02:00
52253: support pcre callouts with shell evaluation of the callout string
This commit is contained in:
parent
a9b0ccd661
commit
de635b4ee5
3 changed files with 40 additions and 2 deletions
|
@ -1,5 +1,8 @@
|
|||
2023-11-02 Oliver Kiddle <opk@zsh.org>
|
||||
|
||||
* 52253: Src/Modules/pcre.c: support pcre callouts with shell
|
||||
evaluation of the callout string
|
||||
|
||||
* 52260: Completion/Unix/Command/_sudo: handle variable assignments
|
||||
before the command in sudo completion
|
||||
|
||||
|
|
|
@ -69,6 +69,11 @@ print -l $accum)
|
|||
)
|
||||
enditem()
|
||||
|
||||
If the regular expression contains callouts, these are executed as shell code.
|
||||
During the execution of the callout, the string the regular expression is
|
||||
matching against is available in the parameter tt(.pcre.subject). If there is a
|
||||
non-zero return status from the shell code, the callout does not match.
|
||||
|
||||
The option tt(-d) uses the alternative breadth-first DFA search algorithm of
|
||||
pcre. This sets tt(match), or the array given with tt(-a), to all the matches
|
||||
found from the same start point in the subject.
|
||||
|
|
|
@ -128,6 +128,31 @@ bin_pcre_study(char *nam, UNUSED(char **args), UNUSED(Options ops), UNUSED(int f
|
|||
return 0;
|
||||
}
|
||||
|
||||
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,
|
||||
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue