160
160
static char *e_emptykey = N_("E713: Cannot use empty key for Dictionary");
161
161
static char *e_listreq = N_("E714: List required");
162
162
static char *e_dictreq = N_("E715: Dictionary required");
163
static char *e_strreq = N_("E114: String required");
163
164
static char *e_toomanyarg = N_("E118: Too many arguments for function: %s");
164
165
static char *e_dictkey = N_("E716: Key not present in Dictionary: %s");
165
166
static char *e_funcexts = N_(
378
379
{ VV_NAME("option_type", VAR_STRING), VV_RO },
379
380
{ VV_NAME("errors", VAR_LIST), 0 },
380
381
{ VV_NAME("msgpack_types", VAR_DICT), VV_RO },
382
{ VV_NAME("event", VAR_DICT), VV_RO },
546
548
set_vim_var_dict(VV_MSGPACK_TYPES, msgpack_types_dict);
547
549
set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc());
551
dict_T *v_event = dict_alloc();
552
v_event->dv_lock = VAR_FIXED;
553
set_vim_var_dict(VV_EVENT, v_event);
548
554
set_vim_var_list(VV_ERRORS, list_alloc());
549
555
set_vim_var_nr(VV_SEARCHFORWARD, 1L);
550
556
set_vim_var_nr(VV_HLSEARCH, 1L);
1709
if (tofree != NULL) {
1705
if (get_var_tv(name, len, &tv, TRUE, FALSE) == FAIL)
1708
/* handle d.key, l[idx], f(expr) */
1712
if (get_var_tv(name, len, &tv, NULL, true, false) == FAIL) {
1715
// handle d.key, l[idx], f(expr)
1709
1716
arg_subsc = arg;
1710
1717
if (handle_subscript(&arg, &tv, TRUE, TRUE) == FAIL)
2274
2281
if (op != NULL && *op != '=') {
2277
/* handle +=, -= and .= */
2284
// handle +=, -= and .=
2278
2286
if (get_var_tv(lp->ll_name, (int)STRLEN(lp->ll_name),
2279
&tv, TRUE, FALSE) == OK) {
2280
if (tv_op(&tv, rettv, op) == OK)
2281
set_var(lp->ll_name, &tv, FALSE);
2287
&tv, &di, true, false) == OK) {
2289
|| (!var_check_ro(di->di_flags, lp->ll_name, false) &&
2290
!tv_check_lock(di->di_tv.v_lock, lp->ll_name, false)))
2291
&& tv_op(&tv, rettv, op) == OK) {
2292
set_var(lp->ll_name, &tv, false);
2288
2300
} else if (tv_check_lock(lp->ll_newkey == NULL
2290
: lp->ll_tv->vval.v_dict->dv_lock, lp->ll_name))
2292
else if (lp->ll_range) {
2302
: lp->ll_tv->vval.v_dict->dv_lock,
2303
lp->ll_name, false)) {
2304
} else if (lp->ll_range) {
2293
2305
listitem_T *ll_li = lp->ll_li;
2294
2306
int ll_n1 = lp->ll_n1;
2296
2308
// Check whether any of the list items is locked
2297
for (listitem_T *ri = rettv->vval.v_list->lv_first; ri != NULL && ll_li != NULL; ) {
2298
if (tv_check_lock(ll_li->li_tv.v_lock, lp->ll_name)) {
2309
for (listitem_T *ri = rettv->vval.v_list->lv_first;
2310
ri != NULL && ll_li != NULL; ) {
2311
if (tv_check_lock(ll_li->li_tv.v_lock, lp->ll_name, false)) {
2301
2314
ri = ri->li_next;
2892
2905
*name_end = cc;
2893
2906
} else if ((lp->ll_list != NULL
2894
&& tv_check_lock(lp->ll_list->lv_lock, lp->ll_name))
2907
&& tv_check_lock(lp->ll_list->lv_lock, lp->ll_name, false))
2895
2908
|| (lp->ll_dict != NULL
2896
&& tv_check_lock(lp->ll_dict->dv_lock, lp->ll_name))) {
2909
&& tv_check_lock(lp->ll_dict->dv_lock, lp->ll_name, false))) {
2898
2911
} else if (lp->ll_range) {
2899
2912
listitem_T *li;
2975
2988
hi = hash_find(ht, varname);
2976
2989
if (!HASHITEM_EMPTY(hi)) {
2977
2990
di = HI2DI(hi);
2978
if (var_check_fixed(di->di_flags, name)
2979
|| var_check_ro(di->di_flags, name)
2980
|| tv_check_lock(d->dv_lock, name)) {
2991
if (var_check_fixed(di->di_flags, name, false)
2992
|| var_check_ro(di->di_flags, name, false)
2993
|| tv_check_lock(d->dv_lock, name, false)) {
2983
2996
typval_T oldtv;
3045
3058
li = li->li_next;
3048
} else if (lp->ll_list != NULL)
3049
/* (un)lock a List item. */
3061
} else if (lp->ll_list != NULL) {
3062
// (un)lock a List item.
3050
3063
item_lock(&lp->ll_li->li_tv, deep, lock);
3052
/* un(lock) a Dictionary item. */
3065
// (un)lock a Dictionary item.
3053
3066
item_lock(&lp->ll_di->di_tv, deep, lock);
5998
6023
++d->dv_refcount;
6026
/// Clear all the keys of a Dictionary. "d" remains a valid empty Dictionary.
6028
/// @param d The Dictionary to clear
6029
void dict_clear(dict_T *d)
6030
FUNC_ATTR_NONNULL_ALL
6032
hash_lock(&d->dv_hashtab);
6033
assert(d->dv_hashtab.ht_locked > 0);
6035
size_t todo = d->dv_hashtab.ht_used;
6036
for (hashitem_T *hi = d->dv_hashtab.ht_array; todo > 0; hi++) {
6037
if (!HASHITEM_EMPTY(hi)) {
6038
dictitem_free(HI2DI(hi));
6039
hash_remove(&d->dv_hashtab, hi);
6044
hash_unlock(&d->dv_hashtab);
6003
6049
* Unreference a Dictionary: decrement the reference count and free it when it
6288
/// Set all existing keys in "dict" as read-only.
6290
/// This does not protect against adding new keys to the Dictionary.
6292
/// @param dict The dict whose keys should be frozen
6293
void dict_set_keys_readonly(dict_T *dict)
6294
FUNC_ATTR_NONNULL_ALL
6296
size_t todo = dict->dv_hashtab.ht_used;
6297
for (hashitem_T *hi = dict->dv_hashtab.ht_array; todo > 0 ; hi++) {
6298
if (HASHITEM_EMPTY(hi)) {
6302
HI2DI(hi)->di_flags |= DI_FLAGS_RO | DI_FLAGS_FIX;
6243
6307
* Get the number of items in a Dictionary.
6840
6904
#define CONV_FLOAT(flt) \
6842
char numbuf[NUMBUFLEN]; \
6843
vim_snprintf(numbuf, NUMBUFLEN - 1, "%g", (flt)); \
6844
ga_concat(gap, (char_u *) numbuf); \
6906
const float_T flt_ = (flt); \
6907
switch (fpclassify(flt_)) { \
6909
ga_concat(gap, (char_u *) "str2float('nan')"); \
6912
case FP_INFINITE: { \
6914
ga_append(gap, '-'); \
6916
ga_concat(gap, (char_u *) "str2float('inf')"); \
6920
char numbuf[NUMBUFLEN]; \
6921
vim_snprintf(numbuf, NUMBUFLEN - 1, "%g", flt_); \
6922
ga_concat(gap, (char_u *) numbuf); \
6847
6927
#define CONV_FUNC(fun) \
7262
7342
{ "maparg", 1, 4, f_maparg },
7263
7343
{ "mapcheck", 1, 3, f_mapcheck },
7264
7344
{ "match", 2, 4, f_match },
7265
{ "matchadd", 2, 4, f_matchadd },
7266
{ "matchaddpos", 2, 4, f_matchaddpos },
7345
{ "matchadd", 2, 5, f_matchadd },
7346
{ "matchaddpos", 2, 5, f_matchaddpos },
7267
7347
{ "matcharg", 1, 1, f_matcharg },
7268
7348
{ "matchdelete", 1, 1, f_matchdelete },
7269
7349
{ "matchend", 2, 4, f_matchend },
7281
7361
{ "pathshorten", 1, 1, f_pathshorten },
7282
7362
{ "pow", 2, 2, f_pow },
7283
7363
{ "prevnonblank", 1, 1, f_prevnonblank },
7284
{ "printf", 2, 19, f_printf },
7364
{ "printf", 2, MAX_FUNC_ARGS, f_printf },
7285
7365
{ "pumvisible", 0, 0, f_pumvisible },
7286
7366
{ "py3eval", 1, 1, f_py3eval },
7287
7367
{ "pyeval", 1, 1, f_pyeval },
7295
7375
{ "resolve", 1, 1, f_resolve },
7296
7376
{ "reverse", 1, 1, f_reverse },
7297
7377
{ "round", 1, 1, f_round },
7298
{ "rpcnotify", 2, 64, f_rpcnotify },
7299
{ "rpcrequest", 2, 64, f_rpcrequest },
7378
{ "rpcnotify", 2, MAX_FUNC_ARGS, f_rpcnotify },
7379
{ "rpcrequest", 2, MAX_FUNC_ARGS, f_rpcrequest },
7300
7380
{ "rpcstart", 1, 2, f_rpcstart },
7301
7381
{ "rpcstop", 1, 1, f_rpcstop },
7302
7382
{ "screenattr", 2, 2, f_screenattr },
7315
7395
{ "setcharsearch", 1, 1, f_setcharsearch },
7316
7396
{ "setcmdpos", 1, 1, f_setcmdpos },
7317
7397
{ "setline", 2, 2, f_setline },
7318
{ "setloclist", 2, 3, f_setloclist },
7398
{ "setloclist", 2, 4, f_setloclist },
7319
7399
{ "setmatches", 1, 1, f_setmatches },
7320
7400
{ "setpos", 2, 2, f_setpos },
7321
{ "setqflist", 1, 2, f_setqflist },
7401
{ "setqflist", 1, 3, f_setqflist },
7322
7402
{ "setreg", 2, 3, f_setreg },
7323
7403
{ "settabvar", 3, 3, f_settabvar },
7324
7404
{ "settabwinvar", 4, 4, f_settabwinvar },
7337
7417
{ "sqrt", 1, 1, f_sqrt },
7338
7418
{ "str2float", 1, 1, f_str2float },
7339
7419
{ "str2nr", 1, 2, f_str2nr },
7340
{ "strchars", 1, 1, f_strchars },
7420
{ "strchars", 1, 2, f_strchars },
7341
7421
{ "strdisplaywidth", 1, 2, f_strdisplaywidth },
7342
7422
{ "strftime", 1, 2, f_strftime },
7343
7423
{ "stridx", 2, 3, f_stridx },
7855
7935
rettv->vval.v_number = 1; /* Default: Failed */
7856
7936
if (argvars[0].v_type == VAR_LIST) {
7857
7937
if ((l = argvars[0].vval.v_list) != NULL
7858
&& !tv_check_lock(l->lv_lock, (char_u *)_("add() argument"))) {
7938
&& !tv_check_lock(l->lv_lock,
7939
(char_u *)N_("add() argument"), true)) {
7859
7940
list_append_tv(l, &argvars[1]);
7860
7941
copy_tv(&argvars[0], rettv);
9131
9212
len = get_name_len(&p, &tofree, TRUE, FALSE);
9214
if (tofree != NULL) {
9135
n = (get_var_tv(name, len, &tv, FALSE, TRUE) == OK);
9217
n = (get_var_tv(name, len, &tv, NULL, false, true) == OK);
9137
9219
/* handle d.key, l[idx], f(expr) */
9138
9220
n = (handle_subscript(&p, &tv, TRUE, FALSE) == OK);
9264
9346
} else if (*action == 'f' && HI2DI(hi2) != di1) {
9265
9347
typval_T oldtv;
9267
if (tv_check_lock(di1->di_tv.v_lock, (char_u *)_(arg_errmsg))
9268
|| var_check_ro(di1->di_flags, (char_u *)_(arg_errmsg))) {
9349
if (tv_check_lock(di1->di_tv.v_lock, arg_errmsg, true)
9350
|| var_check_ro(di1->di_flags, arg_errmsg, true)) {
9302
9384
l1 = argvars[0].vval.v_list;
9303
9385
l2 = argvars[1].vval.v_list;
9304
if (l1 != NULL && !tv_check_lock(l1->lv_lock, (char_u *)_(arg_errmsg))
9386
if (l1 != NULL && !tv_check_lock(l1->lv_lock, arg_errmsg, true)
9305
9387
&& l2 != NULL) {
9306
9388
if (argvars[2].v_type != VAR_UNKNOWN) {
9307
9389
before = get_tv_number_chk(&argvars[2], &error);
9332
9414
d1 = argvars[0].vval.v_dict;
9333
9415
d2 = argvars[1].vval.v_dict;
9334
if (d1 != NULL && !tv_check_lock(d1->dv_lock, (char_u *)_(arg_errmsg))
9416
if (d1 != NULL && !tv_check_lock(d1->dv_lock, arg_errmsg, true)
9335
9417
&& d2 != NULL) {
9336
9418
/* Check the third argument. */
9337
9419
if (argvars[2].v_type != VAR_UNKNOWN) {
9479
9561
char_u *ermsg = (char_u *)(map ? "map()" : "filter()");
9480
char *arg_errmsg = (map ? N_("map() argument")
9481
: N_("filter() argument"));
9562
char_u *arg_errmsg = (char_u *)(map ? N_("map() argument")
9563
: N_("filter() argument"));
9482
9564
int save_did_emsg;
9485
9567
if (argvars[0].v_type == VAR_LIST) {
9486
9568
if ((l = argvars[0].vval.v_list) == NULL
9487
|| (!map && tv_check_lock(l->lv_lock, (char_u *)_(arg_errmsg)))) {
9569
|| (!map && tv_check_lock(l->lv_lock, arg_errmsg, true))) {
9490
9572
} else if (argvars[0].v_type == VAR_DICT) {
9491
9573
if ((d = argvars[0].vval.v_dict) == NULL
9492
|| (!map && tv_check_lock(d->dv_lock, (char_u *)_(arg_errmsg)))) {
9574
|| (!map && tv_check_lock(d->dv_lock, arg_errmsg, true))) {
9534
9616
if (r == FAIL || did_emsg)
9536
9618
if (!map && rem) {
9537
if (var_check_fixed(di->di_flags, (char_u *)_(arg_errmsg))
9538
|| var_check_ro(di->di_flags, (char_u *)_(arg_errmsg))) {
9619
if (var_check_fixed(di->di_flags, arg_errmsg, true)
9620
|| var_check_ro(di->di_flags, arg_errmsg, true)) {
9541
9623
dictitem_remove(d, di);
10412
10494
dict_add_nr_str(dict, "group", 0L, syn_id2name(cur->hlg_id));
10413
10495
dict_add_nr_str(dict, "priority", (long)cur->priority, NULL);
10414
10496
dict_add_nr_str(dict, "id", (long)cur->id, NULL);
10498
if (cur->conceal_char) {
10499
char_u buf[MB_MAXBYTES + 1];
10501
buf[(*mb_char2bytes)((int)cur->conceal_char, buf)] = NUL;
10502
dict_add_nr_str(dict, "conceal", 0L, (char_u *)&buf);
10415
10505
list_append_dict(rettv->vval.v_list, dict);
10416
10506
cur = cur->next;
10552
10640
if (regname == 0)
10553
10641
regname = '"';
10557
switch (get_reg_type(regname, ®len)) {
10558
case MLINE: buf[0] = 'V'; break;
10559
case MCHAR: buf[0] = 'v'; break;
10562
sprintf((char *)buf + 1, "%" PRId64, (int64_t)(reglen + 1));
10643
colnr_T reglen = 0;
10644
char buf[NUMBUFLEN + 2];
10645
char_u reg_type = get_reg_type(regname, ®len);
10646
format_reg_type(reg_type, reglen, buf, ARRAY_SIZE(buf));
10565
10648
rettv->v_type = VAR_STRING;
10566
rettv->vval.v_string = vim_strsave(buf);
10649
rettv->vval.v_string = (char_u *)xstrdup(buf);
10583
10666
varname = get_tv_string_chk(&argvars[1]);
10584
10667
tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL));
10585
10668
if (tp != NULL && varname != NULL) {
10586
/* Set tp to be our tabpage, temporarily. Also set the window to the
10587
* first window in the tabpage, otherwise the window is not valid. */
10588
if (switch_win(&oldcurwin, &oldtabpage, tp->tp_firstwin, tp, TRUE) == OK) {
10669
// Set tp to be our tabpage, temporarily. Also set the window to the
10670
// first window in the tabpage, otherwise the window is not valid.
10671
win_T *window = tp->tp_firstwin == NULL ? firstwin : tp->tp_firstwin;
10672
if (switch_win(&oldcurwin, &oldtabpage, window, tp, true) == OK) {
10589
10673
// look up the variable
10590
10674
// Let gettabvar({nr}, "") return the "t:" dictionary.
10591
10675
v = find_var_in_ht(&tp->tp_vars->dv_hashtab, 't', varname, FALSE);
10697
10781
rettv->vval.v_string = NULL;
10699
10783
if (win != NULL && varname != NULL) {
10700
/* Set curwin to be our win, temporarily. Also set the tabpage,
10701
* otherwise the window is not valid. */
10702
if (switch_win(&oldcurwin, &oldtabpage, win, tp, TRUE) == OK) {
10703
if (*varname == '&') { /* window-local-option */
10704
if (get_option_tv(&varname, rettv, 1) == OK)
10784
// Set curwin to be our win, temporarily. Also set the tabpage,
10785
// otherwise the window is not valid. Only do this when needed,
10786
// autocommands get blocked.
10787
bool need_switch_win = tp != curtab || win != curwin;
10788
if (!need_switch_win
10789
|| switch_win(&oldcurwin, &oldtabpage, win, tp, true) == OK) {
10790
if (*varname == '&') { // window-local-option
10791
if (get_option_tv(&varname, rettv, 1) == OK) {
10707
10795
// Look up the variable.
10708
10796
// Let getwinvar({nr}, "") return the "w:" dictionary.
11443
11533
int error = FALSE;
11445
if (argvars[0].v_type != VAR_LIST)
11535
if (argvars[0].v_type != VAR_LIST) {
11446
11536
EMSG2(_(e_listarg), "insert()");
11447
else if ((l = argvars[0].vval.v_list) != NULL
11448
&& !tv_check_lock(l->lv_lock, (char_u *)_("insert() argument"))) {
11449
if (argvars[2].v_type != VAR_UNKNOWN)
11537
} else if ((l = argvars[0].vval.v_list) != NULL
11538
&& !tv_check_lock(l->lv_lock,
11539
(char_u *)N_("insert() argument"), true)) {
11540
if (argvars[2].v_type != VAR_UNKNOWN) {
11450
11541
before = get_tv_number_chk(&argvars[2], &error);
11452
return; /* type error; errmsg already given */
11544
// type error; errmsg already given
11454
11548
if (before == l->lv_len)
12481
12576
if (argvars[2].v_type != VAR_UNKNOWN) {
12482
12577
prio = get_tv_number_chk(&argvars[2], &error);
12483
if (argvars[3].v_type != VAR_UNKNOWN)
12578
if (argvars[3].v_type != VAR_UNKNOWN) {
12484
12579
id = get_tv_number_chk(&argvars[3], &error);
12580
if (argvars[4].v_type != VAR_UNKNOWN) {
12581
if (argvars[4].v_type != VAR_DICT) {
12582
EMSG(_(e_dictreq));
12585
if (dict_find(argvars[4].vval.v_dict,
12586
(char_u *)"conceal", -1) != NULL) {
12587
conceal_char = get_dict_string(argvars[4].vval.v_dict,
12588
(char_u *)"conceal", false);
12593
if (error == true) {
12488
12596
if (id >= 1 && id <= 3) {
12489
12597
EMSGN("E798: ID is reserved for \":match\": %" PRId64, id);
12493
rettv->vval.v_number = match_add(curwin, grp, pat, prio, id, NULL);
12601
rettv->vval.v_number = match_add(curwin, grp, pat, prio, id, NULL,
12496
12605
static void f_matchaddpos(typval_T *argvars, typval_T *rettv) FUNC_ATTR_NONNULL_ALL
12518
12627
int error = false;
12519
12628
int prio = 10;
12630
char_u *conceal_char = NULL;
12522
12632
if (argvars[2].v_type != VAR_UNKNOWN) {
12523
prio = get_tv_number_chk(&argvars[2], &error);
12524
if (argvars[3].v_type != VAR_UNKNOWN) {
12525
id = get_tv_number_chk(&argvars[3], &error);
12633
prio = get_tv_number_chk(&argvars[2], &error);
12634
if (argvars[3].v_type != VAR_UNKNOWN) {
12635
id = get_tv_number_chk(&argvars[3], &error);
12636
if (argvars[4].v_type != VAR_UNKNOWN) {
12637
if (argvars[4].v_type != VAR_DICT) {
12638
EMSG(_(e_dictreq));
12641
if (dict_find(argvars[4].vval.v_dict,
12642
(char_u *)"conceal", -1) != NULL) {
12643
conceal_char = get_dict_string(argvars[4].vval.v_dict,
12644
(char_u *)"conceal", false);
12528
12649
if (error == true) {
13905
14027
dictitem_T *di;
13906
char *arg_errmsg = N_("remove() argument");
14028
char_u *arg_errmsg = (char_u *)N_("remove() argument");
13908
14030
if (argvars[0].v_type == VAR_DICT) {
13909
if (argvars[2].v_type != VAR_UNKNOWN)
14031
if (argvars[2].v_type != VAR_UNKNOWN) {
13910
14032
EMSG2(_(e_toomanyarg), "remove()");
13911
else if ((d = argvars[0].vval.v_dict) != NULL
13912
&& !tv_check_lock(d->dv_lock, (char_u *)_(arg_errmsg))) {
14033
} else if ((d = argvars[0].vval.v_dict) != NULL
14034
&& !tv_check_lock(d->dv_lock, arg_errmsg, true)) {
13913
14035
key = get_tv_string_chk(&argvars[1]);
13914
14036
if (key != NULL) {
13915
14037
di = dict_find(d, key, -1);
13916
14038
if (di == NULL) {
13917
14039
EMSG2(_(e_dictkey), key);
13918
} else if (!var_check_fixed(di->di_flags, (char_u *)_(arg_errmsg))
13919
&& !var_check_ro(di->di_flags, (char_u *)_(arg_errmsg))) {
14040
} else if (!var_check_fixed(di->di_flags, arg_errmsg, true)
14041
&& !var_check_ro(di->di_flags, arg_errmsg, true)) {
13920
14042
*rettv = di->di_tv;
13921
14043
init_tv(&di->di_tv);
13922
14044
dictitem_remove(d, di);
13929
} else if (argvars[0].v_type != VAR_LIST)
14051
} else if (argvars[0].v_type != VAR_LIST) {
13930
14052
EMSG2(_(e_listdictarg), "remove()");
13931
else if ((l = argvars[0].vval.v_list) != NULL
13932
&& !tv_check_lock(l->lv_lock, (char_u *)_(arg_errmsg))) {
14053
} else if ((l = argvars[0].vval.v_list) != NULL
14054
&& !tv_check_lock(l->lv_lock, arg_errmsg, true)) {
14055
int error = (int)false;
13935
14057
idx = get_tv_number_chk(&argvars[1], &error);
14205
14327
listitem_T *li, *ni;
14207
if (argvars[0].v_type != VAR_LIST)
14329
if (argvars[0].v_type != VAR_LIST) {
14208
14330
EMSG2(_(e_listarg), "reverse()");
14209
else if ((l = argvars[0].vval.v_list) != NULL
14210
&& !tv_check_lock(l->lv_lock, (char_u *)_("reverse() argument"))) {
14331
} else if ((l = argvars[0].vval.v_list) != NULL
14332
&& !tv_check_lock(l->lv_lock,
14333
(char_u *)N_("reverse() argument"), true)) {
14211
14334
li = l->lv_last;
14212
14335
l->lv_first = l->lv_last = NULL;
14213
14336
l->lv_len = 0;
15156
15279
appended_lines_mark(lcount, added);
15161
* Used by "setqflist()" and "setloclist()" functions
15163
static void set_qf_ll_list(win_T *wp, typval_T *list_arg, typval_T *action_arg, typval_T *rettv)
15282
/// Create quickfix/location list from VimL values
15284
/// Used by `setqflist()` and `setloclist()` functions. Accepts invalid
15285
/// list_arg, action_arg and title_arg arguments in which case errors out,
15286
/// including VAR_UNKNOWN parameters.
15288
/// @param[in,out] wp Window to create location list for. May be NULL in
15289
/// which case quickfix list will be created.
15290
/// @param[in] list_arg Quickfix list contents.
15291
/// @param[in] action_arg Action to perform: append to an existing list,
15292
/// replace its content or create a new one.
15293
/// @param[in] title_arg New list title. Defaults to caller function name.
15294
/// @param[out] rettv Return value: 0 in case of success, -1 otherwise.
15295
static void set_qf_ll_list(win_T *wp, typval_T *args, typval_T *rettv)
15296
FUNC_ATTR_NONNULL_ARG(2, 3)
15298
char_u *title = NULL;
15166
15299
int action = ' ';
15168
15300
rettv->vval.v_number = -1;
15170
if (list_arg->v_type != VAR_LIST)
15302
typval_T *list_arg = &args[0];
15303
if (list_arg->v_type != VAR_LIST) {
15171
15304
EMSG(_(e_listreq));
15173
list_T *l = list_arg->vval.v_list;
15175
if (action_arg->v_type == VAR_STRING) {
15176
act = get_tv_string_chk(action_arg);
15178
return; /* type error; errmsg already given */
15179
if (*act == 'a' || *act == 'r')
15183
if (l != NULL && set_errorlist(wp, l, action,
15184
(char_u *)(wp == NULL ? "setqflist()" : "setloclist()")) == OK)
15185
rettv->vval.v_number = 0;
15308
typval_T *action_arg = &args[1];
15309
if (action_arg->v_type == VAR_UNKNOWN) {
15310
// Option argument was not given.
15312
} else if (action_arg->v_type != VAR_STRING) {
15316
char_u *act = get_tv_string_chk(action_arg);
15317
if (*act == 'a' || *act == 'r') {
15321
typval_T *title_arg = &args[2];
15322
if (title_arg->v_type == VAR_UNKNOWN) {
15323
// Option argument was not given.
15326
title = get_tv_string_chk(title_arg);
15328
// Type error. Error already printed by get_tv_string_chk().
15334
title = (char_u*)(wp ? "setloclist()" : "setqflist()");
15337
list_T *l = list_arg->vval.v_list;
15338
if (l && set_errorlist(wp, l, action, title) == OK) {
15339
rettv->vval.v_number = 0;
15427
char_u *group = get_dict_string(d, (char_u *)"group", false);
15428
int priority = get_dict_number(d, (char_u *)"priority");
15429
int id = get_dict_number(d, (char_u *)"id");
15430
char_u *conceal = dict_find(d, (char_u *)"conceal", -1) != NULL
15431
? get_dict_string(d, (char_u *)"conceal",
15272
15434
if (i == 0) {
15273
match_add(curwin, get_dict_string(d, (char_u *)"group", false),
15435
match_add(curwin, group,
15274
15436
get_dict_string(d, (char_u *)"pattern", false),
15275
(int)get_dict_number(d, (char_u *)"priority"),
15276
(int)get_dict_number(d, (char_u *)"id"), NULL);
15437
priority, id, NULL, conceal);
15278
match_add(curwin, get_dict_string(d, (char_u *)"group", false),
15279
NULL, (int)get_dict_number(d, (char_u *)"priority"),
15280
(int)get_dict_number(d, (char_u *)"id"), s);
15439
match_add(curwin, group, NULL, priority, id, s, conceal);
15281
15440
list_unref(s);
15503
15662
varname = get_tv_string_chk(&argvars[off + 1]);
15504
15663
varp = &argvars[off + 2];
15506
if (win != NULL && varname != NULL && varp != NULL
15507
&& switch_win(&save_curwin, &save_curtab, win, tp, TRUE) == OK) {
15508
if (*varname == '&') {
15665
if (win != NULL && varname != NULL && varp != NULL) {
15666
bool need_switch_win = tp != curtab || win != curwin;
15667
if (!need_switch_win
15668
|| switch_win(&save_curwin, &save_curtab, win, tp, true) == OK) {
15669
if (*varname == '&') {
15514
numval = get_tv_number_chk(varp, &error);
15515
strval = get_tv_string_buf_chk(varp, nbuf);
15516
if (!error && strval != NULL)
15517
set_option_value(varname, numval, strval, OPT_LOCAL);
15519
winvarname = xmalloc(STRLEN(varname) + 3);
15520
STRCPY(winvarname, "w:");
15521
STRCPY(winvarname + 2, varname);
15522
set_var(winvarname, varp, TRUE);
15525
restore_win(save_curwin, save_curtab, TRUE);
15675
numval = get_tv_number_chk(varp, &error);
15676
strval = get_tv_string_buf_chk(varp, nbuf);
15677
if (!error && strval != NULL) {
15678
set_option_value(varname, numval, strval, OPT_LOCAL);
15681
winvarname = xmalloc(STRLEN(varname) + 3);
15682
STRCPY(winvarname, "w:");
15683
STRCPY(winvarname + 2, varname);
15684
set_var(winvarname, varp, true);
15688
if (need_switch_win) {
15689
restore_win(save_curwin, save_curtab, true);
15741
15906
EMSG2(_(e_listarg), sort ? "sort()" : "uniq()");
15743
15908
l = argvars[0].vval.v_list;
15744
if (l == NULL || tv_check_lock(l->lv_lock,
15745
(char_u *)(sort ? _("sort() argument") : _("uniq() argument")))) {
15910
tv_check_lock(l->lv_lock,
15912
? N_("sort() argument")
15913
: N_("uniq() argument")),
15748
15917
rettv->vval.v_list = l;
16213
16382
static void f_strchars(typval_T *argvars, typval_T *rettv)
16215
16384
char_u *s = get_tv_string(&argvars[0]);
16216
16386
varnumber_T len = 0;
16387
int (*func_mb_ptr2char_adv)(char_u **pp);
16218
while (*s != NUL) {
16219
mb_cptr2char_adv(&s);
16222
rettv->vval.v_number = len;
16389
if (argvars[1].v_type != VAR_UNKNOWN) {
16390
skipcc = get_tv_number_chk(&argvars[1], NULL);
16392
if (skipcc < 0 || skipcc > 1) {
16395
func_mb_ptr2char_adv = skipcc ? mb_ptr2char_adv : mb_cptr2char_adv;
16396
while (*s != NUL) {
16397
func_mb_ptr2char_adv(&s);
16400
rettv->vval.v_number = len;
18023
18202
/// Set Dictionary v: variable to "val".
18024
void set_vim_var_dict(int idx, dict_T *val) FUNC_ATTR_NONNULL_ALL
18203
void set_vim_var_dict(int idx, dict_T *val)
18026
18205
dict_unref(vimvars[idx].vv_dict);
18029
int todo = (int)val->dv_hashtab.ht_used;
18030
for (hashitem_T *hi = val->dv_hashtab.ht_array; todo > 0 ; ++hi) {
18031
if (HASHITEM_EMPTY(hi)) {
18036
HI2DI(hi)->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
18039
18206
vimvars[idx].vv_dict = val;
18040
++val->dv_refcount;
18209
++val->dv_refcount;
18211
dict_set_keys_readonly(val);
18157
18329
char_u *name,
18158
int len, /* length of "name" */
18159
typval_T *rettv, /* NULL when only checking existence */
18160
int verbose, /* may give error message */
18161
int no_autoload /* do not use script autoloading */
18330
int len, // length of "name"
18331
typval_T *rettv, // NULL when only checking existence
18332
dictitem_T **dip, // non-NULL when typval's dict item is needed
18333
int verbose, // may give error message
18334
int no_autoload // do not use script autoloading
18164
18337
int ret = OK;
18850
19031
if (v != NULL) {
18851
/* existing variable, need to clear the value */
18852
if (var_check_ro(v->di_flags, name)
18853
|| tv_check_lock(v->di_tv.v_lock, name))
19032
// existing variable, need to clear the value
19033
if (var_check_ro(v->di_flags, name, false)
19034
|| tv_check_lock(v->di_tv.v_lock, name, false)) {
18855
19037
if (v->di_tv.v_type != tv->v_type
18856
19038
&& !((v->di_tv.v_type == VAR_STRING
18857
19039
|| v->di_tv.v_type == VAR_NUMBER)
18880
19060
v->di_tv.vval.v_string = tv->vval.v_string;
18881
19061
tv->vval.v_string = NULL;
18883
} else if (v->di_tv.v_type != VAR_NUMBER)
18884
EMSG2(_(e_intern2), "set_var()");
19064
} else if (v->di_tv.v_type == VAR_NUMBER) {
18886
19065
v->di_tv.vval.v_number = get_tv_number(tv);
18887
19066
if (STRCMP(varname, "searchforward") == 0)
18888
19067
set_search_direction(v->di_tv.vval.v_number ? '/' : '?');
18940
* Return TRUE if di_flags "flags" indicates variable "name" is read-only.
18941
* Also give an error message.
18943
static int var_check_ro(int flags, char_u *name)
19120
// Return true if di_flags "flags" indicates variable "name" is read-only.
19121
// Also give an error message.
19122
static bool var_check_ro(int flags, char_u *name, bool use_gettext)
18945
19124
if (flags & DI_FLAGS_RO) {
18946
EMSG2(_(e_readonlyvar), name);
19125
EMSG2(_(e_readonlyvar), use_gettext ? (char_u *)_(name) : name);
18949
19128
if ((flags & DI_FLAGS_RO_SBX) && sandbox) {
18950
EMSG2(_(e_readonlysbx), name);
19129
EMSG2(_(e_readonlysbx), use_gettext ? (char_u *)_(name) : name);
18957
* Return TRUE if di_flags "flags" indicates variable "name" is fixed.
18958
* Also give an error message.
18960
static int var_check_fixed(int flags, char_u *name)
19135
// Return true if di_flags "flags" indicates variable "name" is fixed.
19136
// Also give an error message.
19137
static bool var_check_fixed(int flags, char_u *name, bool use_gettext)
18962
19139
if (flags & DI_FLAGS_FIX) {
18963
EMSG2(_("E795: Cannot delete variable %s"), name);
19140
EMSG2(_("E795: Cannot delete variable %s"),
19141
use_gettext ? (char_u *)_(name) : name);
19015
* Return TRUE if typeval "tv" is set to be locked (immutable).
19016
* Also give an error message, using "name".
19018
static int tv_check_lock(int lock, char_u *name)
19192
// Return true if typeval "tv" is set to be locked (immutable).
19193
// Also give an error message, using "name" or _("name") when use_gettext is
19195
static bool tv_check_lock(int lock, char_u *name, bool use_gettext)
19020
19197
if (lock & VAR_LOCKED) {
19021
19198
EMSG2(_("E741: Value is locked: %s"),
19022
name == NULL ? (char_u *)_("Unknown") : name);
19200
? (char_u *)_("Unknown")
19201
: use_gettext ? (char_u *)_(name)
19025
19205
if (lock & VAR_FIXED) {
19026
19206
EMSG2(_("E742: Cannot change value of %s"),
19027
name == NULL ? (char_u *)_("Unknown") : name);
19208
? (char_u *)_("Unknown")
19209
: use_gettext ? (char_u *)_(name)
19846
20032
if (fudi.fd_di == NULL) {
19847
/* Can't add a function to a locked dictionary */
19848
if (tv_check_lock(fudi.fd_dict->dv_lock, eap->arg))
20033
if (tv_check_lock(fudi.fd_dict->dv_lock, eap->arg, false)) {
20034
// Can't add a function to a locked dictionary
20037
} else if (tv_check_lock(fudi.fd_di->di_tv.v_lock, eap->arg, false)) {
20038
// Can't change an existing function if it is locked
19851
/* Can't change an existing function if it is locked */
19852
else if (tv_check_lock(fudi.fd_di->di_tv.v_lock, eap->arg))
19855
20042
/* Give the function a sequential number. Can only be used with a
19856
20043
* Funcref! */
20828
21015
save_sourcing_name = sourcing_name;
20829
21016
save_sourcing_lnum = sourcing_lnum;
20830
21017
sourcing_lnum = 1;
20831
sourcing_name = xmalloc((save_sourcing_name == NULL ? 0 : STRLEN(save_sourcing_name))
20832
+ STRLEN(fp->uf_name) + 13);
21018
// need space for function name + ("function " + 3) or "[number]"
21019
size_t len = (save_sourcing_name == NULL ? 0 : STRLEN(save_sourcing_name))
21020
+ STRLEN(fp->uf_name) + 20;
21021
sourcing_name = xmalloc(len);
20834
21023
if (save_sourcing_name != NULL
20835
&& STRNCMP(save_sourcing_name, "function ", 9) == 0)
20836
sprintf((char *)sourcing_name, "%s..", save_sourcing_name);
21024
&& STRNCMP(save_sourcing_name, "function ", 9) == 0) {
21025
vim_snprintf((char *)sourcing_name, len, "%s[%zu]..",
21026
save_sourcing_name, save_sourcing_lnum);
20838
21028
STRCPY(sourcing_name, "function ");
20839
21030
cat_func_name(sourcing_name + STRLEN(sourcing_name), fp);
20841
21032
if (p_verbose >= 12) {