summaryrefslogtreecommitdiff
path: root/pp_ctl.c
diff options
context:
space:
mode:
authorYves Orton <demerphq@gmail.com>2022-11-25 20:10:05 +0100
committerYves Orton <demerphq@gmail.com>2022-12-09 18:34:58 +0100
commit10ba1aff86e2ef2d5a2e1a26910c8cc1575bde86 (patch)
tree644aff28bff24e72a81e6bbad4d0c3094d6bf081 /pp_ctl.c
parent901d80aa640b7a4bacdba6355b48343f30148c0b (diff)
downloadperl-10ba1aff86e2ef2d5a2e1a26910c8cc1575bde86.tar.gz
pp_ctl.c - support $INC in require_file @INC hook
$INC is localized to be the C level index of the loop over the @INC array. At the end of the hook its value is assigned back to the C level loop iterator (inc_idx). This allows a hook to control where in the @INC array the loop should continue, for instance -1 represents "reprocess from the beginning" (and as a convenience so does undef). This can be useful if the @INC array is modified by a hook. Normally we would just "continue along", but this may or may not be the right thing to do, so we let the user decide.
Diffstat (limited to 'pp_ctl.c')
-rw-r--r--pp_ctl.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/pp_ctl.c b/pp_ctl.c
index 618349f9a5..6872b8c025 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -4307,6 +4307,9 @@ S_require_file(pTHX_ SV *sv)
SvSetSV_nosteal(nsv,sv);
}
+ SV * inc_idx_sv = save_scalar(PL_incgv);
+ sv_setiv(inc_idx_sv,inc_idx);
+
ENTER_with_name("call_INC_hook");
SAVETMPS;
EXTEND(SP, 2);
@@ -4412,6 +4415,21 @@ S_require_file(pTHX_ SV *sv)
/* FREETMPS may free our filter_cache */
SvREFCNT_inc_simple_void(filter_cache);
+ /*
+ Let the hook override which @INC entry we visit
+ next by setting $INC to a different value than it
+ was before we called the hook. If they have
+ completely rewritten the array they might want us
+ to start traversing from the beginning, which is
+ represented by -1. We use undef as an equivalent of
+ -1. This can't be used as a way to call a hook
+ twice, as we still dedupe.
+ We have to do this before we LEAVE, as we localized
+ $INC before we called the hook.
+ */
+ inc_idx_sv = GvSVn(PL_incgv);
+ inc_idx = SvOK(inc_idx_sv) ? SvIV(inc_idx_sv) : -1;
+
PUTBACK;
FREETMPS;
LEAVE_with_name("call_INC_hook");