1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
//! Port of `_cache_invalid` from
//! `Completion/Base/Utility/_cache_invalid`.
//!
//! Full upstream body (21 lines verbatim):
//! ```text
//! sh: 1 #autoload
//! sh: 5 local _cache_ident _cache_dir _cache_path _cache_policy
//! sh: 6 _cache_ident="$1"
//! sh: 8 # If the cache is disabled, we never want to rebuild it, so pretend
//! sh: 9 # it's valid.
//! sh:10 zstyle -t ":completion:${curcontext}:" use-cache || return 1
//! sh:12 zstyle -s ":completion:${curcontext}:" cache-path _cache_dir
//! sh:13 : ${_cache_dir:=${ZDOTDIR:-$HOME}/.zcompcache}
//! sh:14 _cache_path="$_cache_dir/$_cache_ident"
//! sh:18 zstyle -s ":completion:${curcontext}:" cache-policy _cache_policy
//! sh:19 [[ -n "$_cache_policy" ]] && "$_cache_policy" "$_cache_path" && return 0
//! sh:21 return 1
//! ```
//!
//! Returns 0 when the cache needs rebuilding (per the user-supplied
//! `cache-policy` hook); 1 otherwise (cache disabled or no policy).
use crate;
use crate;
use crategetsparam;
use cratequotestring;
use crateQT_SINGLE;
/// sh:19 — the policy hook is a COMMAND WORD (`"$_cache_policy" "$_cache_path"`),
/// so zsh resolves it function → builtin → `$PATH` and, when nothing matches,
/// prints `command not found` and yields status 127.
///
/// `dispatch_function_call` only covers the first of those three steps, so a
/// policy naming a builtin or an external program silently "failed" and an
/// undefined policy produced no diagnostic at all (reference zsh prints
/// `_cache_invalid:19: command not found: <policy>`).
///
/// Functions keep the direct dispatch — it is the same resolution zsh performs
/// first, and it avoids re-entering the parser on the completion hot path.
/// Everything else is handed to the canonical string-execution entry
/// (`execute_script_zsh_pipeline`, the same one `execstring` and `zstyle -e`'s
/// `evalstyle` use), which performs the remaining builtin/`$PATH` steps and
/// emits the diagnostic.
///
/// Both words are single-quoted, reproducing sh:19's `"…"` expansions: the
/// policy name and cache path are passed through verbatim, never split or
/// globbed.
/// Reach `_cache_invalid` the way every upstream caller writes it — as a BARE
/// COMMAND WORD (`_cache_invalid "$_cache_ident"`, `_retrieve_cache` sh:21;
/// `_cache_invalid $cache_id`, `_python_modules` sh:25) — so the normal
/// function lookup runs.
///
/// This is the DEFAULT entry point for the port, and the one a sibling port
/// should call. It goes through
/// [`crate::compsys::ported::shared::call_compfn`], which supplies both of
/// the things a bare Rust call to the body would skip: `$fpath` / shfunc
/// arbitration (a user's own `_cache_invalid` earlier on `$fpath` stays live
/// instead of being inert) and the `doshfunc` frame. Without that frame
/// `$funcstack` inside the `cache-policy` hook read `zpwrDailyCachingPolicy
/// _retrieve_cache __fasd_files_comp …` where zsh reads `… _cache_invalid
/// _retrieve_cache …`.
///
/// [`_cache_invalid_impl`] is the raw body, reserved for the two callers that
/// must not re-enter dispatch: this wrapper's own fallback (it runs only when
/// neither a shell function nor a registered port claims the name — i.e. unit
/// tests with no executor installed), and the `compsys::router` arm, which
/// has to target the body or dispatch would re-enter this wrapper forever.
/// `_cache_invalid` — query the cache-policy hook for tag `$1`.
/// Returns 0 (cache stale) or 1 (cache fresh / disabled / no policy).