Mercurial > vim
changeset 32200:730eebd56f48 v9.0.1431
patch 9.0.1431: getscriptinfo() loops even when specific SID is given
Commit: https://github.com/vim/vim/commit/2d68b722e3bca7532eb0d83ce773934618f12db5
Author: zeertzjq <zeertzjq@outlook.com>
Date: Thu Mar 30 21:50:37 2023 +0100
patch 9.0.1431: getscriptinfo() loops even when specific SID is given
Problem: getscriptinfo() loops even when specific SID is given.
Solution: Only loop when needed. Give a clearer error message.
(closes #12207)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Thu, 30 Mar 2023 23:00:06 +0200 |
parents | dc4f9a9d07a1 |
children | ac20568109be |
files | src/scriptfile.c src/testdir/test_scriptnames.vim src/version.c |
diffstat | 3 files changed, 34 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/src/scriptfile.c +++ b/src/scriptfile.c @@ -1299,7 +1299,7 @@ ex_options( * ":source" and associated commands. */ -#ifdef FEAT_EVAL +#if defined(FEAT_EVAL) || defined(PROTO) /* * Return the address holding the next breakpoint line for a source cookie. */ @@ -2096,7 +2096,6 @@ get_script_local_funcs(scid_T sid) void f_getscriptinfo(typval_T *argvars, typval_T *rettv) { - int i; list_T *l; char_u *pat = NULL; regmatch_T regmatch; @@ -2116,8 +2115,22 @@ f_getscriptinfo(typval_T *argvars, typva if (argvars[0].v_type == VAR_DICT) { - sid = dict_get_number_def(argvars[0].vval.v_dict, "sid", -1); - if (sid == -1) + dictitem_T *sid_di = dict_find(argvars[0].vval.v_dict, + (char_u *)"sid", 3); + if (sid_di != NULL) + { + int error = FALSE; + sid = tv_get_number_chk(&sid_di->di_tv, &error); + if (error) + return; + if (sid <= 0) + { + semsg(e_invalid_value_for_argument_str_str, "sid", + tv_get_string(&sid_di->di_tv)); + return; + } + } + else { pat = dict_get_string(argvars[0].vval.v_dict, "name", TRUE); if (pat != NULL) @@ -2127,7 +2140,8 @@ f_getscriptinfo(typval_T *argvars, typva } } - for (i = 1; i <= script_items.ga_len; ++i) + for (varnumber_T i = sid > 0 ? sid : 1; + (i == sid || sid <= 0) && i <= script_items.ga_len; ++i) { scriptitem_T *si = SCRIPT_ITEM(i); dict_T *d; @@ -2138,9 +2152,6 @@ f_getscriptinfo(typval_T *argvars, typva if (filterpat && !vim_regexec(®match, si->sn_name, (colnr_T)0)) continue; - if (sid != -1 && sid != i) - continue; - if ((d = dict_alloc()) == NULL || list_append_dict(l, d) == FAIL || dict_add_string(d, "name", si->sn_name) == FAIL @@ -2151,10 +2162,9 @@ f_getscriptinfo(typval_T *argvars, typva si->sn_state == SN_STATE_NOT_LOADED) == FAIL) return; - // When a filter pattern is specified to return information about only - // specific script(s), also add the script-local variables and - // functions. - if (sid != -1) + // When a script ID is specified, return information about only the + // specified script, and add the script-local variables and functions. + if (sid > 0) { dict_T *var_dict;
--- a/src/testdir/test_scriptnames.vim +++ b/src/testdir/test_scriptnames.vim @@ -91,6 +91,16 @@ func Test_getscriptinfo() call assert_fails("echo getscriptinfo('foobar')", 'E1206:') call assert_fails("echo getscriptinfo({'sid': []})", 'E745:') + call assert_fails("echo getscriptinfo({'sid': {}})", 'E728:') + call assert_fails("echo getscriptinfo({'sid': 0})", 'E475:') + call assert_fails("echo getscriptinfo({'sid': -1})", 'E475:') + call assert_fails("echo getscriptinfo({'sid': -999})", 'E475:') + + echo getscriptinfo({'sid': '1'}) + call assert_fails("vim9cmd echo getscriptinfo({'sid': '1'})", 'E1030:') + + let max_sid = max(map(getscriptinfo(), { k, v -> v.sid })) + call assert_equal([], getscriptinfo({'sid': max_sid + 1})) endfunc " vim: shiftwidth=2 sts=2 expandtab