# HG changeset patch # User Bram Moolenaar # Date 1680210006 -7200 # Node ID 730eebd56f48f4e57617cf9799cdff2e47c526a0 # Parent dc4f9a9d07a1a1f641b98abe200e9b8079b714ea patch 9.0.1431: getscriptinfo() loops even when specific SID is given Commit: https://github.com/vim/vim/commit/2d68b722e3bca7532eb0d83ce773934618f12db5 Author: zeertzjq 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) diff --git a/src/scriptfile.c b/src/scriptfile.c --- 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; diff --git a/src/testdir/test_scriptnames.vim b/src/testdir/test_scriptnames.vim --- 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 diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -696,6 +696,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1431, +/**/ 1430, /**/ 1429,