diff options
author | Bram Moolenaar <Bram@vim.org> | 2022-01-11 15:24:05 +0000 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2022-01-11 15:24:05 +0000 |
commit | b8822442d716df0230c79531132e530e95cc17e3 (patch) | |
tree | b3ef7369be4f32805e8fcf04aee960d38d45e2e5 /src/userfunc.c | |
parent | 0bbca540f7377889e2154aa5731f6eeffcb5c0cc (diff) | |
download | vim-git-8.2.4063.tar.gz |
patch 8.2.4063: Vim9: exported function in autoload script not foundv8.2.4063
Problem: Vim9: exported function in autoload script not found. (Yegappan
Lakshmanan)
Solution: Use the autoload prefix to search for the function.
Diffstat (limited to 'src/userfunc.c')
-rw-r--r-- | src/userfunc.c | 52 |
1 files changed, 49 insertions, 3 deletions
diff --git a/src/userfunc.c b/src/userfunc.c index 48f5890e8..4516a48aa 100644 --- a/src/userfunc.c +++ b/src/userfunc.c @@ -1871,9 +1871,13 @@ fname_trans_sid(char_u *name, char_u *fname_buf, char_u **tofree, int *error) static ufunc_T * find_func_with_sid(char_u *name, int sid) { - hashitem_T *hi; - char_u buffer[200]; + hashitem_T *hi; + char_u buffer[200]; + + if (!SCRIPT_ID_VALID(sid)) + return NULL; // not in a script + // A script-local function is stored as "<SNR>99_name". buffer[0] = K_SPECIAL; buffer[1] = KS_EXTRA; buffer[2] = (int)KE_SNR; @@ -1882,6 +1886,46 @@ find_func_with_sid(char_u *name, int sid) hi = hash_find(&func_hashtab, buffer); if (!HASHITEM_EMPTY(hi)) return HI2UF(hi); + return NULL; +} + +/* + * Find a function "name" in script "sid" prefixing the autoload prefix. + */ + static ufunc_T * +find_func_with_prefix(char_u *name, int sid) +{ + hashitem_T *hi; + char_u buffer[200]; + scriptitem_T *si; + + if (vim_strchr(name, AUTOLOAD_CHAR) != 0) + return NULL; // already has the prefix + if (!SCRIPT_ID_VALID(sid)) + return NULL; // not in a script + si = SCRIPT_ITEM(sid); + if (si->sn_autoload_prefix != NULL) + { + size_t len = STRLEN(si->sn_autoload_prefix) + STRLEN(name) + 1; + char_u *auto_name; + + // An exported function in an autoload script is stored as + // "dir#path#name". + if (len < sizeof(buffer)) + auto_name = buffer; + else + auto_name = alloc(len); + if (auto_name != NULL) + { + vim_snprintf((char *)auto_name, len, "%s%s", + si->sn_autoload_prefix, name); + hi = hash_find(&func_hashtab, auto_name); + if (auto_name != buffer) + vim_free(auto_name); + if (!HASHITEM_EMPTY(hi)) + return HI2UF(hi); + } + } return NULL; } @@ -1917,7 +1961,9 @@ find_func_even_dead(char_u *name, int is_global, cctx_T *cctx UNUSED) if (!HASHITEM_EMPTY(hi)) return HI2UF(hi); - return NULL; + // Find autoload function if this is an autoload script. + return find_func_with_prefix(name[0] == 's' && name[1] == ':' + ? name + 2 : name, current_sctx.sc_sid); } /* |