Mercurial > vim
comparison src/eval.c @ 9556:afaff1d283d3 v7.4.2055
commit https://github.com/vim/vim/commit/cd52459c387785796713826c63174cdeed295dd4
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Jul 17 14:57:05 2016 +0200
patch 7.4.2055
Problem: eval.c is too big.
Solution: Move Dictionary functions to dict.c.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Sun, 17 Jul 2016 15:15:05 +0200 |
parents | e8b3db8e2d30 |
children | 1e68dfd7931b |
comparison
equal
deleted
inserted
replaced
9555:9560a5b782ee | 9556:afaff1d283d3 |
---|---|
30 | 30 |
31 #define DICT_MAXNEST 100 /* maximum nesting of lists and dicts */ | 31 #define DICT_MAXNEST 100 /* maximum nesting of lists and dicts */ |
32 | 32 |
33 #define DO_NOT_FREE_CNT 99999 /* refcount for dict or list that should not | 33 #define DO_NOT_FREE_CNT 99999 /* refcount for dict or list that should not |
34 be freed. */ | 34 be freed. */ |
35 | |
36 /* | |
37 * In a hashtab item "hi_key" points to "di_key" in a dictitem. | |
38 * This avoids adding a pointer to the hashtab item. | |
39 * DI2HIKEY() converts a dictitem pointer to a hashitem key pointer. | |
40 * HIKEY2DI() converts a hashitem key pointer to a dictitem pointer. | |
41 * HI2DI() converts a hashitem pointer to a dictitem pointer. | |
42 */ | |
43 static dictitem_T dumdi; | |
44 #define DI2HIKEY(di) ((di)->di_key) | |
45 #define HIKEY2DI(p) ((dictitem_T *)(p - (dumdi.di_key - (char_u *)&dumdi))) | |
46 #define HI2DI(hi) HIKEY2DI((hi)->hi_key) | |
47 | 35 |
48 /* | 36 /* |
49 * Structure returned by get_lval() and used by set_var_lval(). | 37 * Structure returned by get_lval() and used by set_var_lval(). |
50 * For a plain name: | 38 * For a plain name: |
51 * "name" points to the variable name. | 39 * "name" points to the variable name. |
95 static char *e_undefvar = N_("E121: Undefined variable: %s"); | 83 static char *e_undefvar = N_("E121: Undefined variable: %s"); |
96 static char *e_missbrac = N_("E111: Missing ']'"); | 84 static char *e_missbrac = N_("E111: Missing ']'"); |
97 static char *e_listarg = N_("E686: Argument of %s must be a List"); | 85 static char *e_listarg = N_("E686: Argument of %s must be a List"); |
98 static char *e_listdictarg = N_("E712: Argument of %s must be a List or Dictionary"); | 86 static char *e_listdictarg = N_("E712: Argument of %s must be a List or Dictionary"); |
99 static char *e_listreq = N_("E714: List required"); | 87 static char *e_listreq = N_("E714: List required"); |
100 static char *e_dictreq = N_("E715: Dictionary required"); | |
101 #ifdef FEAT_QUICKFIX | 88 #ifdef FEAT_QUICKFIX |
102 static char *e_stringreq = N_("E928: String required"); | 89 static char *e_stringreq = N_("E928: String required"); |
103 #endif | 90 #endif |
104 static char *e_toomanyarg = N_("E118: Too many arguments for function: %s"); | 91 static char *e_toomanyarg = N_("E118: Too many arguments for function: %s"); |
105 static char *e_dictkey = N_("E716: Key not present in Dictionary: %s"); | 92 static char *e_dictkey = N_("E716: Key not present in Dictionary: %s"); |
129 * When recursively copying lists and dicts we need to remember which ones we | 116 * When recursively copying lists and dicts we need to remember which ones we |
130 * have done to avoid endless recursiveness. This unique ID is used for that. | 117 * have done to avoid endless recursiveness. This unique ID is used for that. |
131 * The last bit is used for previous_funccal, ignored when comparing. | 118 * The last bit is used for previous_funccal, ignored when comparing. |
132 */ | 119 */ |
133 static int current_copyID = 0; | 120 static int current_copyID = 0; |
134 #define COPYID_INC 2 | |
135 #define COPYID_MASK (~0x1) | |
136 | |
137 /* Abort conversion to string after a recursion error. */ | |
138 static int did_echo_string_emsg = FALSE; | |
139 | 121 |
140 /* | 122 /* |
141 * Array to hold the hashtab with variables local to each sourced script. | 123 * Array to hold the hashtab with variables local to each sourced script. |
142 * Each item holds a variable (nameless) that points to the dict_T. | 124 * Each item holds a variable (nameless) that points to the dict_T. |
143 */ | 125 */ |
213 static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL}; | 195 static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL}; |
214 | 196 |
215 /* List heads for garbage collection. Although there can be a reference loop | 197 /* List heads for garbage collection. Although there can be a reference loop |
216 * from partial to dict to partial, we don't need to keep track of the partial, | 198 * from partial to dict to partial, we don't need to keep track of the partial, |
217 * since it will get freed when the dict is unused and gets freed. */ | 199 * since it will get freed when the dict is unused and gets freed. */ |
218 static dict_T *first_dict = NULL; /* list of all dicts */ | |
219 static list_T *first_list = NULL; /* list of all lists */ | 200 static list_T *first_list = NULL; /* list of all lists */ |
220 | 201 |
221 /* From user function to hashitem and back. */ | 202 /* From user function to hashitem and back. */ |
222 static ufunc_T dumuf; | 203 static ufunc_T dumuf; |
223 #define UF2HIKEY(fp) ((fp)->uf_name) | 204 #define UF2HIKEY(fp) ((fp)->uf_name) |
421 static int do_lock_var(lval_T *lp, char_u *name_end, int deep, int lock); | 402 static int do_lock_var(lval_T *lp, char_u *name_end, int deep, int lock); |
422 static void item_lock(typval_T *tv, int deep, int lock); | 403 static void item_lock(typval_T *tv, int deep, int lock); |
423 static int tv_islocked(typval_T *tv); | 404 static int tv_islocked(typval_T *tv); |
424 | 405 |
425 static int eval0(char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate); | 406 static int eval0(char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate); |
426 static int eval1(char_u **arg, typval_T *rettv, int evaluate); | |
427 static int eval2(char_u **arg, typval_T *rettv, int evaluate); | 407 static int eval2(char_u **arg, typval_T *rettv, int evaluate); |
428 static int eval3(char_u **arg, typval_T *rettv, int evaluate); | 408 static int eval3(char_u **arg, typval_T *rettv, int evaluate); |
429 static int eval4(char_u **arg, typval_T *rettv, int evaluate); | 409 static int eval4(char_u **arg, typval_T *rettv, int evaluate); |
430 static int eval5(char_u **arg, typval_T *rettv, int evaluate); | 410 static int eval5(char_u **arg, typval_T *rettv, int evaluate); |
431 static int eval6(char_u **arg, typval_T *rettv, int evaluate, int want_string); | 411 static int eval6(char_u **arg, typval_T *rettv, int evaluate, int want_string); |
438 static int get_list_tv(char_u **arg, typval_T *rettv, int evaluate); | 418 static int get_list_tv(char_u **arg, typval_T *rettv, int evaluate); |
439 static void list_free_contents(list_T *l); | 419 static void list_free_contents(list_T *l); |
440 static void list_free_list(list_T *l); | 420 static void list_free_list(list_T *l); |
441 static long list_len(list_T *l); | 421 static long list_len(list_T *l); |
442 static int list_equal(list_T *l1, list_T *l2, int ic, int recursive); | 422 static int list_equal(list_T *l1, list_T *l2, int ic, int recursive); |
443 static int dict_equal(dict_T *d1, dict_T *d2, int ic, int recursive); | |
444 static int tv_equal(typval_T *tv1, typval_T *tv2, int ic, int recursive); | |
445 static long list_find_nr(list_T *l, long idx, int *errorp); | 423 static long list_find_nr(list_T *l, long idx, int *errorp); |
446 static long list_idx_of_item(list_T *l, listitem_T *item); | 424 static long list_idx_of_item(list_T *l, listitem_T *item); |
447 static int list_extend(list_T *l1, list_T *l2, listitem_T *bef); | 425 static int list_extend(list_T *l1, list_T *l2, listitem_T *bef); |
448 static int list_concat(list_T *l1, list_T *l2, typval_T *tv); | 426 static int list_concat(list_T *l1, list_T *l2, typval_T *tv); |
449 static list_T *list_copy(list_T *orig, int deep, int copyID); | 427 static list_T *list_copy(list_T *orig, int deep, int copyID); |
450 static char_u *list2string(typval_T *tv, int copyID, int restore_copyID); | 428 static char_u *list2string(typval_T *tv, int copyID, int restore_copyID); |
451 static int list_join_inner(garray_T *gap, list_T *l, char_u *sep, int echo_style, int restore_copyID, int copyID, garray_T *join_gap); | 429 static int list_join_inner(garray_T *gap, list_T *l, char_u *sep, int echo_style, int restore_copyID, int copyID, garray_T *join_gap); |
452 static int list_join(garray_T *gap, list_T *l, char_u *sep, int echo_style, int restore_copyID, int copyID); | 430 static int list_join(garray_T *gap, list_T *l, char_u *sep, int echo_style, int restore_copyID, int copyID); |
453 static int free_unref_items(int copyID); | 431 static int free_unref_items(int copyID); |
454 static dictitem_T *dictitem_copy(dictitem_T *org); | |
455 static void dictitem_remove(dict_T *dict, dictitem_T *item); | |
456 static dict_T *dict_copy(dict_T *orig, int deep, int copyID); | |
457 static long dict_len(dict_T *d); | |
458 static char_u *dict2string(typval_T *tv, int copyID, int restore_copyID); | |
459 static int get_dict_tv(char_u **arg, typval_T *rettv, int evaluate); | |
460 static int get_function_args(char_u **argp, char_u endchar, garray_T *newargs, int *varargs, int skip); | 432 static int get_function_args(char_u **argp, char_u endchar, garray_T *newargs, int *varargs, int skip); |
461 static int get_lambda_tv(char_u **arg, typval_T *rettv, int evaluate); | 433 static int get_lambda_tv(char_u **arg, typval_T *rettv, int evaluate); |
462 static char_u *echo_string_core(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID, int echo_style, int restore_copyID, int dict_val); | |
463 static char_u *echo_string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID); | 434 static char_u *echo_string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID); |
464 static char_u *string_quote(char_u *str, int function); | |
465 static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate); | 435 static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate); |
466 static int find_internal_func(char_u *name); | 436 static int find_internal_func(char_u *name); |
467 static char_u *deref_func_name(char_u *name, int *lenp, partial_T **partial, int no_autoload); | 437 static char_u *deref_func_name(char_u *name, int *lenp, partial_T **partial, int no_autoload); |
468 static int get_func_tv(char_u *name, int len, typval_T *rettv, char_u **arg, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, partial_T *partial, dict_T *selfdict); | 438 static int get_func_tv(char_u *name, int len, typval_T *rettv, char_u **arg, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, partial_T *partial, dict_T *selfdict); |
469 static void emsg_funcname(char *ermsg, char_u *name); | 439 static void emsg_funcname(char *ermsg, char_u *name); |
470 static int non_zero_arg(typval_T *argvars); | 440 static int non_zero_arg(typval_T *argvars); |
471 | |
472 static void dict_free_contents(dict_T *d); | |
473 static void dict_free_dict(dict_T *d); | |
474 | 441 |
475 #ifdef FEAT_FLOAT | 442 #ifdef FEAT_FLOAT |
476 static void f_abs(typval_T *argvars, typval_T *rettv); | 443 static void f_abs(typval_T *argvars, typval_T *rettv); |
477 static void f_acos(typval_T *argvars, typval_T *rettv); | 444 static void f_acos(typval_T *argvars, typval_T *rettv); |
478 #endif | 445 #endif |
896 static void vars_clear_ext(hashtab_T *ht, int free_val); | 863 static void vars_clear_ext(hashtab_T *ht, int free_val); |
897 static void delete_var(hashtab_T *ht, hashitem_T *hi); | 864 static void delete_var(hashtab_T *ht, hashitem_T *hi); |
898 static void list_one_var(dictitem_T *v, char_u *prefix, int *first); | 865 static void list_one_var(dictitem_T *v, char_u *prefix, int *first); |
899 static void list_one_var_a(char_u *prefix, char_u *name, int type, char_u *string, int *first); | 866 static void list_one_var_a(char_u *prefix, char_u *name, int type, char_u *string, int *first); |
900 static void set_var(char_u *name, typval_T *varp, int copy); | 867 static void set_var(char_u *name, typval_T *varp, int copy); |
901 static int var_check_ro(int flags, char_u *name, int use_gettext); | |
902 static int var_check_fixed(int flags, char_u *name, int use_gettext); | 868 static int var_check_fixed(int flags, char_u *name, int use_gettext); |
903 static int var_check_func_name(char_u *name, int new_var); | |
904 static int valid_varname(char_u *varname); | |
905 static int tv_check_lock(int lock, char_u *name, int use_gettext); | |
906 static int item_copy(typval_T *from, typval_T *to, int deep, int copyID); | |
907 static char_u *find_option_end(char_u **arg, int *opt_flags); | 869 static char_u *find_option_end(char_u **arg, int *opt_flags); |
908 static char_u *trans_function_name(char_u **pp, int skip, int flags, funcdict_T *fd, partial_T **partial); | 870 static char_u *trans_function_name(char_u **pp, int skip, int flags, funcdict_T *fd, partial_T **partial); |
909 static int eval_fname_script(char_u *p); | 871 static int eval_fname_script(char_u *p); |
910 static int eval_fname_sid(char_u *p); | 872 static int eval_fname_sid(char_u *p); |
911 static void list_func_head(ufunc_T *fp, int indent); | 873 static void list_func_head(ufunc_T *fp, int indent); |
4258 * | 4220 * |
4259 * Note: "rettv.v_lock" is not set. | 4221 * Note: "rettv.v_lock" is not set. |
4260 * | 4222 * |
4261 * Return OK or FAIL. | 4223 * Return OK or FAIL. |
4262 */ | 4224 */ |
4263 static int | 4225 int |
4264 eval1(char_u **arg, typval_T *rettv, int evaluate) | 4226 eval1(char_u **arg, typval_T *rettv, int evaluate) |
4265 { | 4227 { |
4266 int result; | 4228 int result; |
4267 typval_T var2; | 4229 typval_T var2; |
4268 | 4230 |
6257 if (!tv_equal(&item1->li_tv, &item2->li_tv, ic, recursive)) | 6219 if (!tv_equal(&item1->li_tv, &item2->li_tv, ic, recursive)) |
6258 return FALSE; | 6220 return FALSE; |
6259 return item1 == NULL && item2 == NULL; | 6221 return item1 == NULL && item2 == NULL; |
6260 } | 6222 } |
6261 | 6223 |
6262 /* | |
6263 * Return the dictitem that an entry in a hashtable points to. | |
6264 */ | |
6265 dictitem_T * | |
6266 dict_lookup(hashitem_T *hi) | |
6267 { | |
6268 return HI2DI(hi); | |
6269 } | |
6270 | |
6271 /* | |
6272 * Return TRUE when two dictionaries have exactly the same key/values. | |
6273 */ | |
6274 static int | |
6275 dict_equal( | |
6276 dict_T *d1, | |
6277 dict_T *d2, | |
6278 int ic, /* ignore case for strings */ | |
6279 int recursive) /* TRUE when used recursively */ | |
6280 { | |
6281 hashitem_T *hi; | |
6282 dictitem_T *item2; | |
6283 int todo; | |
6284 | |
6285 if (d1 == NULL && d2 == NULL) | |
6286 return TRUE; | |
6287 if (d1 == NULL || d2 == NULL) | |
6288 return FALSE; | |
6289 if (d1 == d2) | |
6290 return TRUE; | |
6291 if (dict_len(d1) != dict_len(d2)) | |
6292 return FALSE; | |
6293 | |
6294 todo = (int)d1->dv_hashtab.ht_used; | |
6295 for (hi = d1->dv_hashtab.ht_array; todo > 0; ++hi) | |
6296 { | |
6297 if (!HASHITEM_EMPTY(hi)) | |
6298 { | |
6299 item2 = dict_find(d2, hi->hi_key, -1); | |
6300 if (item2 == NULL) | |
6301 return FALSE; | |
6302 if (!tv_equal(&HI2DI(hi)->di_tv, &item2->di_tv, ic, recursive)) | |
6303 return FALSE; | |
6304 --todo; | |
6305 } | |
6306 } | |
6307 return TRUE; | |
6308 } | |
6309 | |
6310 static int tv_equal_recurse_limit; | 6224 static int tv_equal_recurse_limit; |
6311 | 6225 |
6312 static int | 6226 static int |
6313 func_equal( | 6227 func_equal( |
6314 typval_T *tv1, | 6228 typval_T *tv1, |
6364 /* | 6278 /* |
6365 * Return TRUE if "tv1" and "tv2" have the same value. | 6279 * Return TRUE if "tv1" and "tv2" have the same value. |
6366 * Compares the items just like "==" would compare them, but strings and | 6280 * Compares the items just like "==" would compare them, but strings and |
6367 * numbers are different. Floats and numbers are also different. | 6281 * numbers are different. Floats and numbers are also different. |
6368 */ | 6282 */ |
6369 static int | 6283 int |
6370 tv_equal( | 6284 tv_equal( |
6371 typval_T *tv1, | 6285 typval_T *tv1, |
6372 typval_T *tv2, | 6286 typval_T *tv2, |
6373 int ic, /* ignore case */ | 6287 int ic, /* ignore case */ |
6374 int recursive) /* TRUE when used recursively */ | 6288 int recursive) /* TRUE when used recursively */ |
7196 * Free lists, dictionaries, channels and jobs that are no longer referenced. | 7110 * Free lists, dictionaries, channels and jobs that are no longer referenced. |
7197 */ | 7111 */ |
7198 static int | 7112 static int |
7199 free_unref_items(int copyID) | 7113 free_unref_items(int copyID) |
7200 { | 7114 { |
7201 dict_T *dd, *dd_next; | |
7202 list_T *ll, *ll_next; | 7115 list_T *ll, *ll_next; |
7203 int did_free = FALSE; | 7116 int did_free = FALSE; |
7204 | 7117 |
7205 /* Let all "free" functions know that we are here. This means no | 7118 /* Let all "free" functions know that we are here. This means no |
7206 * dictionaries, lists, channels or jobs are to be freed, because we will | 7119 * dictionaries, lists, channels or jobs are to be freed, because we will |
7210 /* | 7123 /* |
7211 * PASS 1: free the contents of the items. We don't free the items | 7124 * PASS 1: free the contents of the items. We don't free the items |
7212 * themselves yet, so that it is possible to decrement refcount counters | 7125 * themselves yet, so that it is possible to decrement refcount counters |
7213 */ | 7126 */ |
7214 | 7127 |
7215 /* | 7128 /* Go through the list of dicts and free items without the copyID. */ |
7216 * Go through the list of dicts and free items without the copyID. | 7129 did_free |= dict_free_nonref(copyID); |
7217 */ | |
7218 for (dd = first_dict; dd != NULL; dd = dd->dv_used_next) | |
7219 if ((dd->dv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)) | |
7220 { | |
7221 /* Free the Dictionary and ordinary items it contains, but don't | |
7222 * recurse into Lists and Dictionaries, they will be in the list | |
7223 * of dicts or list of lists. */ | |
7224 dict_free_contents(dd); | |
7225 did_free = TRUE; | |
7226 } | |
7227 | 7130 |
7228 /* | 7131 /* |
7229 * Go through the list of lists and free items without the copyID. | 7132 * Go through the list of lists and free items without the copyID. |
7230 * But don't free a list that has a watcher (used in a for loop), these | 7133 * But don't free a list that has a watcher (used in a for loop), these |
7231 * are not referenced anywhere. | 7134 * are not referenced anywhere. |
7252 #endif | 7155 #endif |
7253 | 7156 |
7254 /* | 7157 /* |
7255 * PASS 2: free the items themselves. | 7158 * PASS 2: free the items themselves. |
7256 */ | 7159 */ |
7257 for (dd = first_dict; dd != NULL; dd = dd_next) | 7160 dict_free_items(copyID); |
7258 { | |
7259 dd_next = dd->dv_used_next; | |
7260 if ((dd->dv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)) | |
7261 dict_free_dict(dd); | |
7262 } | |
7263 | 7161 |
7264 for (ll = first_list; ll != NULL; ll = ll_next) | 7162 for (ll = first_list; ll != NULL; ll = ll_next) |
7265 { | 7163 { |
7266 ll_next = ll->lv_used_next; | 7164 ll_next = ll->lv_used_next; |
7267 if ((ll->lv_copyID & COPYID_MASK) != (copyID & COPYID_MASK) | 7165 if ((ll->lv_copyID & COPYID_MASK) != (copyID & COPYID_MASK) |
7536 } | 7434 } |
7537 #endif | 7435 #endif |
7538 return abort; | 7436 return abort; |
7539 } | 7437 } |
7540 | 7438 |
7541 /* | |
7542 * Allocate an empty header for a dictionary. | |
7543 */ | |
7544 dict_T * | |
7545 dict_alloc(void) | |
7546 { | |
7547 dict_T *d; | |
7548 | |
7549 d = (dict_T *)alloc(sizeof(dict_T)); | |
7550 if (d != NULL) | |
7551 { | |
7552 /* Add the dict to the list of dicts for garbage collection. */ | |
7553 if (first_dict != NULL) | |
7554 first_dict->dv_used_prev = d; | |
7555 d->dv_used_next = first_dict; | |
7556 d->dv_used_prev = NULL; | |
7557 first_dict = d; | |
7558 | |
7559 hash_init(&d->dv_hashtab); | |
7560 d->dv_lock = 0; | |
7561 d->dv_scope = 0; | |
7562 d->dv_refcount = 0; | |
7563 d->dv_copyID = 0; | |
7564 } | |
7565 return d; | |
7566 } | |
7567 | |
7568 /* | |
7569 * Allocate an empty dict for a return value. | |
7570 * Returns OK or FAIL. | |
7571 */ | |
7572 int | |
7573 rettv_dict_alloc(typval_T *rettv) | |
7574 { | |
7575 dict_T *d = dict_alloc(); | |
7576 | |
7577 if (d == NULL) | |
7578 return FAIL; | |
7579 | |
7580 rettv->vval.v_dict = d; | |
7581 rettv->v_type = VAR_DICT; | |
7582 rettv->v_lock = 0; | |
7583 ++d->dv_refcount; | |
7584 return OK; | |
7585 } | |
7586 | |
7587 | |
7588 /* | |
7589 * Unreference a Dictionary: decrement the reference count and free it when it | |
7590 * becomes zero. | |
7591 */ | |
7592 void | |
7593 dict_unref(dict_T *d) | |
7594 { | |
7595 if (d != NULL && --d->dv_refcount <= 0) | |
7596 dict_free(d); | |
7597 } | |
7598 | |
7599 /* | |
7600 * Free a Dictionary, including all non-container items it contains. | |
7601 * Ignores the reference count. | |
7602 */ | |
7603 static void | |
7604 dict_free_contents(dict_T *d) | |
7605 { | |
7606 int todo; | |
7607 hashitem_T *hi; | |
7608 dictitem_T *di; | |
7609 | |
7610 /* Lock the hashtab, we don't want it to resize while freeing items. */ | |
7611 hash_lock(&d->dv_hashtab); | |
7612 todo = (int)d->dv_hashtab.ht_used; | |
7613 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) | |
7614 { | |
7615 if (!HASHITEM_EMPTY(hi)) | |
7616 { | |
7617 /* Remove the item before deleting it, just in case there is | |
7618 * something recursive causing trouble. */ | |
7619 di = HI2DI(hi); | |
7620 hash_remove(&d->dv_hashtab, hi); | |
7621 clear_tv(&di->di_tv); | |
7622 vim_free(di); | |
7623 --todo; | |
7624 } | |
7625 } | |
7626 hash_clear(&d->dv_hashtab); | |
7627 } | |
7628 | |
7629 static void | |
7630 dict_free_dict(dict_T *d) | |
7631 { | |
7632 /* Remove the dict from the list of dicts for garbage collection. */ | |
7633 if (d->dv_used_prev == NULL) | |
7634 first_dict = d->dv_used_next; | |
7635 else | |
7636 d->dv_used_prev->dv_used_next = d->dv_used_next; | |
7637 if (d->dv_used_next != NULL) | |
7638 d->dv_used_next->dv_used_prev = d->dv_used_prev; | |
7639 vim_free(d); | |
7640 } | |
7641 | |
7642 void | |
7643 dict_free(dict_T *d) | |
7644 { | |
7645 if (!in_free_unref_items) | |
7646 { | |
7647 dict_free_contents(d); | |
7648 dict_free_dict(d); | |
7649 } | |
7650 } | |
7651 | |
7652 /* | |
7653 * Allocate a Dictionary item. | |
7654 * The "key" is copied to the new item. | |
7655 * Note that the value of the item "di_tv" still needs to be initialized! | |
7656 * Returns NULL when out of memory. | |
7657 */ | |
7658 dictitem_T * | |
7659 dictitem_alloc(char_u *key) | |
7660 { | |
7661 dictitem_T *di; | |
7662 | |
7663 di = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) + STRLEN(key))); | |
7664 if (di != NULL) | |
7665 { | |
7666 STRCPY(di->di_key, key); | |
7667 di->di_flags = DI_FLAGS_ALLOC; | |
7668 } | |
7669 return di; | |
7670 } | |
7671 | |
7672 /* | |
7673 * Make a copy of a Dictionary item. | |
7674 */ | |
7675 static dictitem_T * | |
7676 dictitem_copy(dictitem_T *org) | |
7677 { | |
7678 dictitem_T *di; | |
7679 | |
7680 di = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) | |
7681 + STRLEN(org->di_key))); | |
7682 if (di != NULL) | |
7683 { | |
7684 STRCPY(di->di_key, org->di_key); | |
7685 di->di_flags = DI_FLAGS_ALLOC; | |
7686 copy_tv(&org->di_tv, &di->di_tv); | |
7687 } | |
7688 return di; | |
7689 } | |
7690 | |
7691 /* | |
7692 * Remove item "item" from Dictionary "dict" and free it. | |
7693 */ | |
7694 static void | |
7695 dictitem_remove(dict_T *dict, dictitem_T *item) | |
7696 { | |
7697 hashitem_T *hi; | |
7698 | |
7699 hi = hash_find(&dict->dv_hashtab, item->di_key); | |
7700 if (HASHITEM_EMPTY(hi)) | |
7701 EMSG2(_(e_intern2), "dictitem_remove()"); | |
7702 else | |
7703 hash_remove(&dict->dv_hashtab, hi); | |
7704 dictitem_free(item); | |
7705 } | |
7706 | |
7707 /* | |
7708 * Free a dict item. Also clears the value. | |
7709 */ | |
7710 void | |
7711 dictitem_free(dictitem_T *item) | |
7712 { | |
7713 clear_tv(&item->di_tv); | |
7714 if (item->di_flags & DI_FLAGS_ALLOC) | |
7715 vim_free(item); | |
7716 } | |
7717 | |
7718 /* | |
7719 * Make a copy of dict "d". Shallow if "deep" is FALSE. | |
7720 * The refcount of the new dict is set to 1. | |
7721 * See item_copy() for "copyID". | |
7722 * Returns NULL when out of memory. | |
7723 */ | |
7724 static dict_T * | |
7725 dict_copy(dict_T *orig, int deep, int copyID) | |
7726 { | |
7727 dict_T *copy; | |
7728 dictitem_T *di; | |
7729 int todo; | |
7730 hashitem_T *hi; | |
7731 | |
7732 if (orig == NULL) | |
7733 return NULL; | |
7734 | |
7735 copy = dict_alloc(); | |
7736 if (copy != NULL) | |
7737 { | |
7738 if (copyID != 0) | |
7739 { | |
7740 orig->dv_copyID = copyID; | |
7741 orig->dv_copydict = copy; | |
7742 } | |
7743 todo = (int)orig->dv_hashtab.ht_used; | |
7744 for (hi = orig->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) | |
7745 { | |
7746 if (!HASHITEM_EMPTY(hi)) | |
7747 { | |
7748 --todo; | |
7749 | |
7750 di = dictitem_alloc(hi->hi_key); | |
7751 if (di == NULL) | |
7752 break; | |
7753 if (deep) | |
7754 { | |
7755 if (item_copy(&HI2DI(hi)->di_tv, &di->di_tv, deep, | |
7756 copyID) == FAIL) | |
7757 { | |
7758 vim_free(di); | |
7759 break; | |
7760 } | |
7761 } | |
7762 else | |
7763 copy_tv(&HI2DI(hi)->di_tv, &di->di_tv); | |
7764 if (dict_add(copy, di) == FAIL) | |
7765 { | |
7766 dictitem_free(di); | |
7767 break; | |
7768 } | |
7769 } | |
7770 } | |
7771 | |
7772 ++copy->dv_refcount; | |
7773 if (todo > 0) | |
7774 { | |
7775 dict_unref(copy); | |
7776 copy = NULL; | |
7777 } | |
7778 } | |
7779 | |
7780 return copy; | |
7781 } | |
7782 | |
7783 /* | |
7784 * Add item "item" to Dictionary "d". | |
7785 * Returns FAIL when out of memory and when key already exists. | |
7786 */ | |
7787 int | |
7788 dict_add(dict_T *d, dictitem_T *item) | |
7789 { | |
7790 return hash_add(&d->dv_hashtab, item->di_key); | |
7791 } | |
7792 | |
7793 /* | |
7794 * Add a number or string entry to dictionary "d". | |
7795 * When "str" is NULL use number "nr", otherwise use "str". | |
7796 * Returns FAIL when out of memory and when key already exists. | |
7797 */ | |
7798 int | |
7799 dict_add_nr_str( | |
7800 dict_T *d, | |
7801 char *key, | |
7802 varnumber_T nr, | |
7803 char_u *str) | |
7804 { | |
7805 dictitem_T *item; | |
7806 | |
7807 item = dictitem_alloc((char_u *)key); | |
7808 if (item == NULL) | |
7809 return FAIL; | |
7810 item->di_tv.v_lock = 0; | |
7811 if (str == NULL) | |
7812 { | |
7813 item->di_tv.v_type = VAR_NUMBER; | |
7814 item->di_tv.vval.v_number = nr; | |
7815 } | |
7816 else | |
7817 { | |
7818 item->di_tv.v_type = VAR_STRING; | |
7819 item->di_tv.vval.v_string = vim_strsave(str); | |
7820 } | |
7821 if (dict_add(d, item) == FAIL) | |
7822 { | |
7823 dictitem_free(item); | |
7824 return FAIL; | |
7825 } | |
7826 return OK; | |
7827 } | |
7828 | |
7829 /* | |
7830 * Add a list entry to dictionary "d". | |
7831 * Returns FAIL when out of memory and when key already exists. | |
7832 */ | |
7833 int | |
7834 dict_add_list(dict_T *d, char *key, list_T *list) | |
7835 { | |
7836 dictitem_T *item; | |
7837 | |
7838 item = dictitem_alloc((char_u *)key); | |
7839 if (item == NULL) | |
7840 return FAIL; | |
7841 item->di_tv.v_lock = 0; | |
7842 item->di_tv.v_type = VAR_LIST; | |
7843 item->di_tv.vval.v_list = list; | |
7844 if (dict_add(d, item) == FAIL) | |
7845 { | |
7846 dictitem_free(item); | |
7847 return FAIL; | |
7848 } | |
7849 ++list->lv_refcount; | |
7850 return OK; | |
7851 } | |
7852 | |
7853 /* | |
7854 * Get the number of items in a Dictionary. | |
7855 */ | |
7856 static long | |
7857 dict_len(dict_T *d) | |
7858 { | |
7859 if (d == NULL) | |
7860 return 0L; | |
7861 return (long)d->dv_hashtab.ht_used; | |
7862 } | |
7863 | |
7864 /* | |
7865 * Find item "key[len]" in Dictionary "d". | |
7866 * If "len" is negative use strlen(key). | |
7867 * Returns NULL when not found. | |
7868 */ | |
7869 dictitem_T * | |
7870 dict_find(dict_T *d, char_u *key, int len) | |
7871 { | |
7872 #define AKEYLEN 200 | |
7873 char_u buf[AKEYLEN]; | |
7874 char_u *akey; | |
7875 char_u *tofree = NULL; | |
7876 hashitem_T *hi; | |
7877 | |
7878 if (d == NULL) | |
7879 return NULL; | |
7880 if (len < 0) | |
7881 akey = key; | |
7882 else if (len >= AKEYLEN) | |
7883 { | |
7884 tofree = akey = vim_strnsave(key, len); | |
7885 if (akey == NULL) | |
7886 return NULL; | |
7887 } | |
7888 else | |
7889 { | |
7890 /* Avoid a malloc/free by using buf[]. */ | |
7891 vim_strncpy(buf, key, len); | |
7892 akey = buf; | |
7893 } | |
7894 | |
7895 hi = hash_find(&d->dv_hashtab, akey); | |
7896 vim_free(tofree); | |
7897 if (HASHITEM_EMPTY(hi)) | |
7898 return NULL; | |
7899 return HI2DI(hi); | |
7900 } | |
7901 | |
7902 /* | |
7903 * Get a string item from a dictionary. | |
7904 * When "save" is TRUE allocate memory for it. | |
7905 * Returns NULL if the entry doesn't exist or out of memory. | |
7906 */ | |
7907 char_u * | |
7908 get_dict_string(dict_T *d, char_u *key, int save) | |
7909 { | |
7910 dictitem_T *di; | |
7911 char_u *s; | |
7912 | |
7913 di = dict_find(d, key, -1); | |
7914 if (di == NULL) | |
7915 return NULL; | |
7916 s = get_tv_string(&di->di_tv); | |
7917 if (save && s != NULL) | |
7918 s = vim_strsave(s); | |
7919 return s; | |
7920 } | |
7921 | |
7922 /* | |
7923 * Get a number item from a dictionary. | |
7924 * Returns 0 if the entry doesn't exist. | |
7925 */ | |
7926 varnumber_T | |
7927 get_dict_number(dict_T *d, char_u *key) | |
7928 { | |
7929 dictitem_T *di; | |
7930 | |
7931 di = dict_find(d, key, -1); | |
7932 if (di == NULL) | |
7933 return 0; | |
7934 return get_tv_number(&di->di_tv); | |
7935 } | |
7936 | |
7937 /* | |
7938 * Return an allocated string with the string representation of a Dictionary. | |
7939 * May return NULL. | |
7940 */ | |
7941 static char_u * | |
7942 dict2string(typval_T *tv, int copyID, int restore_copyID) | |
7943 { | |
7944 garray_T ga; | |
7945 int first = TRUE; | |
7946 char_u *tofree; | |
7947 char_u numbuf[NUMBUFLEN]; | |
7948 hashitem_T *hi; | |
7949 char_u *s; | |
7950 dict_T *d; | |
7951 int todo; | |
7952 | |
7953 if ((d = tv->vval.v_dict) == NULL) | |
7954 return NULL; | |
7955 ga_init2(&ga, (int)sizeof(char), 80); | |
7956 ga_append(&ga, '{'); | |
7957 | |
7958 todo = (int)d->dv_hashtab.ht_used; | |
7959 for (hi = d->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) | |
7960 { | |
7961 if (!HASHITEM_EMPTY(hi)) | |
7962 { | |
7963 --todo; | |
7964 | |
7965 if (first) | |
7966 first = FALSE; | |
7967 else | |
7968 ga_concat(&ga, (char_u *)", "); | |
7969 | |
7970 tofree = string_quote(hi->hi_key, FALSE); | |
7971 if (tofree != NULL) | |
7972 { | |
7973 ga_concat(&ga, tofree); | |
7974 vim_free(tofree); | |
7975 } | |
7976 ga_concat(&ga, (char_u *)": "); | |
7977 s = echo_string_core(&HI2DI(hi)->di_tv, &tofree, numbuf, copyID, | |
7978 FALSE, restore_copyID, TRUE); | |
7979 if (s != NULL) | |
7980 ga_concat(&ga, s); | |
7981 vim_free(tofree); | |
7982 if (s == NULL || did_echo_string_emsg) | |
7983 break; | |
7984 line_breakcheck(); | |
7985 | |
7986 } | |
7987 } | |
7988 if (todo > 0) | |
7989 { | |
7990 vim_free(ga.ga_data); | |
7991 return NULL; | |
7992 } | |
7993 | |
7994 ga_append(&ga, '}'); | |
7995 ga_append(&ga, NUL); | |
7996 return (char_u *)ga.ga_data; | |
7997 } | |
7998 | |
7999 /* | |
8000 * Allocate a variable for a Dictionary and fill it from "*arg". | |
8001 * Return OK or FAIL. Returns NOTDONE for {expr}. | |
8002 */ | |
8003 static int | |
8004 get_dict_tv(char_u **arg, typval_T *rettv, int evaluate) | |
8005 { | |
8006 dict_T *d = NULL; | |
8007 typval_T tvkey; | |
8008 typval_T tv; | |
8009 char_u *key = NULL; | |
8010 dictitem_T *item; | |
8011 char_u *start = skipwhite(*arg + 1); | |
8012 char_u buf[NUMBUFLEN]; | |
8013 | |
8014 /* | |
8015 * First check if it's not a curly-braces thing: {expr}. | |
8016 * Must do this without evaluating, otherwise a function may be called | |
8017 * twice. Unfortunately this means we need to call eval1() twice for the | |
8018 * first item. | |
8019 * But {} is an empty Dictionary. | |
8020 */ | |
8021 if (*start != '}') | |
8022 { | |
8023 if (eval1(&start, &tv, FALSE) == FAIL) /* recursive! */ | |
8024 return FAIL; | |
8025 if (*start == '}') | |
8026 return NOTDONE; | |
8027 } | |
8028 | |
8029 if (evaluate) | |
8030 { | |
8031 d = dict_alloc(); | |
8032 if (d == NULL) | |
8033 return FAIL; | |
8034 } | |
8035 tvkey.v_type = VAR_UNKNOWN; | |
8036 tv.v_type = VAR_UNKNOWN; | |
8037 | |
8038 *arg = skipwhite(*arg + 1); | |
8039 while (**arg != '}' && **arg != NUL) | |
8040 { | |
8041 if (eval1(arg, &tvkey, evaluate) == FAIL) /* recursive! */ | |
8042 goto failret; | |
8043 if (**arg != ':') | |
8044 { | |
8045 EMSG2(_("E720: Missing colon in Dictionary: %s"), *arg); | |
8046 clear_tv(&tvkey); | |
8047 goto failret; | |
8048 } | |
8049 if (evaluate) | |
8050 { | |
8051 key = get_tv_string_buf_chk(&tvkey, buf); | |
8052 if (key == NULL) | |
8053 { | |
8054 /* "key" is NULL when get_tv_string_buf_chk() gave an errmsg */ | |
8055 clear_tv(&tvkey); | |
8056 goto failret; | |
8057 } | |
8058 } | |
8059 | |
8060 *arg = skipwhite(*arg + 1); | |
8061 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ | |
8062 { | |
8063 if (evaluate) | |
8064 clear_tv(&tvkey); | |
8065 goto failret; | |
8066 } | |
8067 if (evaluate) | |
8068 { | |
8069 item = dict_find(d, key, -1); | |
8070 if (item != NULL) | |
8071 { | |
8072 EMSG2(_("E721: Duplicate key in Dictionary: \"%s\""), key); | |
8073 clear_tv(&tvkey); | |
8074 clear_tv(&tv); | |
8075 goto failret; | |
8076 } | |
8077 item = dictitem_alloc(key); | |
8078 clear_tv(&tvkey); | |
8079 if (item != NULL) | |
8080 { | |
8081 item->di_tv = tv; | |
8082 item->di_tv.v_lock = 0; | |
8083 if (dict_add(d, item) == FAIL) | |
8084 dictitem_free(item); | |
8085 } | |
8086 } | |
8087 | |
8088 if (**arg == '}') | |
8089 break; | |
8090 if (**arg != ',') | |
8091 { | |
8092 EMSG2(_("E722: Missing comma in Dictionary: %s"), *arg); | |
8093 goto failret; | |
8094 } | |
8095 *arg = skipwhite(*arg + 1); | |
8096 } | |
8097 | |
8098 if (**arg != '}') | |
8099 { | |
8100 EMSG2(_("E723: Missing end of Dictionary '}': %s"), *arg); | |
8101 failret: | |
8102 if (evaluate) | |
8103 dict_free(d); | |
8104 return FAIL; | |
8105 } | |
8106 | |
8107 *arg = skipwhite(*arg + 1); | |
8108 if (evaluate) | |
8109 { | |
8110 rettv->v_type = VAR_DICT; | |
8111 rettv->vval.v_dict = d; | |
8112 ++d->dv_refcount; | |
8113 } | |
8114 | |
8115 return OK; | |
8116 } | |
8117 | |
8118 /* Get function arguments. */ | 7439 /* Get function arguments. */ |
8119 static int | 7440 static int |
8120 get_function_args( | 7441 get_function_args( |
8121 char_u **argp, | 7442 char_u **argp, |
8122 char_u endchar, | 7443 char_u endchar, |
8226 static int lambda_no = 0; | 7547 static int lambda_no = 0; |
8227 | 7548 |
8228 ga_init(&newargs); | 7549 ga_init(&newargs); |
8229 ga_init(&newlines); | 7550 ga_init(&newlines); |
8230 | 7551 |
8231 /* First, check if this is a lambda expression. "->" must exists. */ | 7552 /* First, check if this is a lambda expression. "->" must exist. */ |
8232 ret = get_function_args(&start, '-', NULL, NULL, TRUE); | 7553 ret = get_function_args(&start, '-', NULL, NULL, TRUE); |
8233 if (ret == FAIL || *start != '>') | 7554 if (ret == FAIL || *start != '>') |
8234 return NOTDONE; | 7555 return NOTDONE; |
8235 | 7556 |
8236 /* Parse the arguments again. */ | 7557 /* Parse the arguments again. */ |
8335 * displays values. | 7656 * displays values. |
8336 * When "restore_copyID" is FALSE, repeated items in dictionaries and lists | 7657 * When "restore_copyID" is FALSE, repeated items in dictionaries and lists |
8337 * are replaced with "...". | 7658 * are replaced with "...". |
8338 * May return NULL. | 7659 * May return NULL. |
8339 */ | 7660 */ |
8340 static char_u * | 7661 char_u * |
8341 echo_string_core( | 7662 echo_string_core( |
8342 typval_T *tv, | 7663 typval_T *tv, |
8343 char_u **tofree, | 7664 char_u **tofree, |
8344 char_u *numbuf, | 7665 char_u *numbuf, |
8345 int copyID, | 7666 int copyID, |
8551 /* | 7872 /* |
8552 * Return string "str" in ' quotes, doubling ' characters. | 7873 * Return string "str" in ' quotes, doubling ' characters. |
8553 * If "str" is NULL an empty string is assumed. | 7874 * If "str" is NULL an empty string is assumed. |
8554 * If "function" is TRUE make it function('string'). | 7875 * If "function" is TRUE make it function('string'). |
8555 */ | 7876 */ |
8556 static char_u * | 7877 char_u * |
8557 string_quote(char_u *str, int function) | 7878 string_quote(char_u *str, int function) |
8558 { | 7879 { |
8559 unsigned len; | 7880 unsigned len; |
8560 char_u *p, *r, *s; | 7881 char_u *p, *r, *s; |
8561 | 7882 |
11883 rettv->vval.v_string = NULL; | 11204 rettv->vval.v_string = NULL; |
11884 } | 11205 } |
11885 } | 11206 } |
11886 | 11207 |
11887 /* | 11208 /* |
11888 * Go over all entries in "d2" and add them to "d1". | |
11889 * When "action" is "error" then a duplicate key is an error. | |
11890 * When "action" is "force" then a duplicate key is overwritten. | |
11891 * Otherwise duplicate keys are ignored ("action" is "keep"). | |
11892 */ | |
11893 void | |
11894 dict_extend(dict_T *d1, dict_T *d2, char_u *action) | |
11895 { | |
11896 dictitem_T *di1; | |
11897 hashitem_T *hi2; | |
11898 int todo; | |
11899 char_u *arg_errmsg = (char_u *)N_("extend() argument"); | |
11900 | |
11901 todo = (int)d2->dv_hashtab.ht_used; | |
11902 for (hi2 = d2->dv_hashtab.ht_array; todo > 0; ++hi2) | |
11903 { | |
11904 if (!HASHITEM_EMPTY(hi2)) | |
11905 { | |
11906 --todo; | |
11907 di1 = dict_find(d1, hi2->hi_key, -1); | |
11908 if (d1->dv_scope != 0) | |
11909 { | |
11910 /* Disallow replacing a builtin function in l: and g:. | |
11911 * Check the key to be valid when adding to any | |
11912 * scope. */ | |
11913 if (d1->dv_scope == VAR_DEF_SCOPE | |
11914 && HI2DI(hi2)->di_tv.v_type == VAR_FUNC | |
11915 && var_check_func_name(hi2->hi_key, | |
11916 di1 == NULL)) | |
11917 break; | |
11918 if (!valid_varname(hi2->hi_key)) | |
11919 break; | |
11920 } | |
11921 if (di1 == NULL) | |
11922 { | |
11923 di1 = dictitem_copy(HI2DI(hi2)); | |
11924 if (di1 != NULL && dict_add(d1, di1) == FAIL) | |
11925 dictitem_free(di1); | |
11926 } | |
11927 else if (*action == 'e') | |
11928 { | |
11929 EMSG2(_("E737: Key already exists: %s"), hi2->hi_key); | |
11930 break; | |
11931 } | |
11932 else if (*action == 'f' && HI2DI(hi2) != di1) | |
11933 { | |
11934 if (tv_check_lock(di1->di_tv.v_lock, arg_errmsg, TRUE) | |
11935 || var_check_ro(di1->di_flags, arg_errmsg, TRUE)) | |
11936 break; | |
11937 clear_tv(&di1->di_tv); | |
11938 copy_tv(&HI2DI(hi2)->di_tv, &di1->di_tv); | |
11939 } | |
11940 } | |
11941 } | |
11942 } | |
11943 | |
11944 /* | |
11945 * "extend(list, list [, idx])" function | 11209 * "extend(list, list [, idx])" function |
11946 * "extend(dict, dict [, action])" function | 11210 * "extend(dict, dict [, action])" function |
11947 */ | 11211 */ |
11948 static void | 11212 static void |
11949 f_extend(typval_T *argvars, typval_T *rettv) | 11213 f_extend(typval_T *argvars, typval_T *rettv) |
15535 { | 14799 { |
15536 rettv->vval.v_number = argvars[0].v_type == VAR_FLOAT | 14800 rettv->vval.v_number = argvars[0].v_type == VAR_FLOAT |
15537 && isnan(argvars[0].vval.v_float); | 14801 && isnan(argvars[0].vval.v_float); |
15538 } | 14802 } |
15539 #endif | 14803 #endif |
15540 | |
15541 static void dict_list(typval_T *argvars, typval_T *rettv, int what); | |
15542 | |
15543 /* | |
15544 * Turn a dict into a list: | |
15545 * "what" == 0: list of keys | |
15546 * "what" == 1: list of values | |
15547 * "what" == 2: list of items | |
15548 */ | |
15549 static void | |
15550 dict_list(typval_T *argvars, typval_T *rettv, int what) | |
15551 { | |
15552 list_T *l2; | |
15553 dictitem_T *di; | |
15554 hashitem_T *hi; | |
15555 listitem_T *li; | |
15556 listitem_T *li2; | |
15557 dict_T *d; | |
15558 int todo; | |
15559 | |
15560 if (argvars[0].v_type != VAR_DICT) | |
15561 { | |
15562 EMSG(_(e_dictreq)); | |
15563 return; | |
15564 } | |
15565 if ((d = argvars[0].vval.v_dict) == NULL) | |
15566 return; | |
15567 | |
15568 if (rettv_list_alloc(rettv) == FAIL) | |
15569 return; | |
15570 | |
15571 todo = (int)d->dv_hashtab.ht_used; | |
15572 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) | |
15573 { | |
15574 if (!HASHITEM_EMPTY(hi)) | |
15575 { | |
15576 --todo; | |
15577 di = HI2DI(hi); | |
15578 | |
15579 li = listitem_alloc(); | |
15580 if (li == NULL) | |
15581 break; | |
15582 list_append(rettv->vval.v_list, li); | |
15583 | |
15584 if (what == 0) | |
15585 { | |
15586 /* keys() */ | |
15587 li->li_tv.v_type = VAR_STRING; | |
15588 li->li_tv.v_lock = 0; | |
15589 li->li_tv.vval.v_string = vim_strsave(di->di_key); | |
15590 } | |
15591 else if (what == 1) | |
15592 { | |
15593 /* values() */ | |
15594 copy_tv(&di->di_tv, &li->li_tv); | |
15595 } | |
15596 else | |
15597 { | |
15598 /* items() */ | |
15599 l2 = list_alloc(); | |
15600 li->li_tv.v_type = VAR_LIST; | |
15601 li->li_tv.v_lock = 0; | |
15602 li->li_tv.vval.v_list = l2; | |
15603 if (l2 == NULL) | |
15604 break; | |
15605 ++l2->lv_refcount; | |
15606 | |
15607 li2 = listitem_alloc(); | |
15608 if (li2 == NULL) | |
15609 break; | |
15610 list_append(l2, li2); | |
15611 li2->li_tv.v_type = VAR_STRING; | |
15612 li2->li_tv.v_lock = 0; | |
15613 li2->li_tv.vval.v_string = vim_strsave(di->di_key); | |
15614 | |
15615 li2 = listitem_alloc(); | |
15616 if (li2 == NULL) | |
15617 break; | |
15618 list_append(l2, li2); | |
15619 copy_tv(&di->di_tv, &li2->li_tv); | |
15620 } | |
15621 } | |
15622 } | |
15623 } | |
15624 | 14804 |
15625 /* | 14805 /* |
15626 * "items(dict)" function | 14806 * "items(dict)" function |
15627 */ | 14807 */ |
15628 static void | 14808 static void |
23960 | 23140 |
23961 /* | 23141 /* |
23962 * Return TRUE if di_flags "flags" indicates variable "name" is read-only. | 23142 * Return TRUE if di_flags "flags" indicates variable "name" is read-only. |
23963 * Also give an error message. | 23143 * Also give an error message. |
23964 */ | 23144 */ |
23965 static int | 23145 int |
23966 var_check_ro(int flags, char_u *name, int use_gettext) | 23146 var_check_ro(int flags, char_u *name, int use_gettext) |
23967 { | 23147 { |
23968 if (flags & DI_FLAGS_RO) | 23148 if (flags & DI_FLAGS_RO) |
23969 { | 23149 { |
23970 EMSG2(_(e_readonlyvar), use_gettext ? (char_u *)_(name) : name); | 23150 EMSG2(_(e_readonlyvar), use_gettext ? (char_u *)_(name) : name); |
23996 | 23176 |
23997 /* | 23177 /* |
23998 * Check if a funcref is assigned to a valid variable name. | 23178 * Check if a funcref is assigned to a valid variable name. |
23999 * Return TRUE and give an error if not. | 23179 * Return TRUE and give an error if not. |
24000 */ | 23180 */ |
24001 static int | 23181 int |
24002 var_check_func_name( | 23182 var_check_func_name( |
24003 char_u *name, /* points to start of variable name */ | 23183 char_u *name, /* points to start of variable name */ |
24004 int new_var) /* TRUE when creating the variable */ | 23184 int new_var) /* TRUE when creating the variable */ |
24005 { | 23185 { |
24006 /* Allow for w: b: s: and t:. */ | 23186 /* Allow for w: b: s: and t:. */ |
24026 | 23206 |
24027 /* | 23207 /* |
24028 * Check if a variable name is valid. | 23208 * Check if a variable name is valid. |
24029 * Return FALSE and give an error if not. | 23209 * Return FALSE and give an error if not. |
24030 */ | 23210 */ |
24031 static int | 23211 int |
24032 valid_varname(char_u *varname) | 23212 valid_varname(char_u *varname) |
24033 { | 23213 { |
24034 char_u *p; | 23214 char_u *p; |
24035 | 23215 |
24036 for (p = varname; *p != NUL; ++p) | 23216 for (p = varname; *p != NUL; ++p) |
24046 /* | 23226 /* |
24047 * Return TRUE if typeval "tv" is set to be locked (immutable). | 23227 * Return TRUE if typeval "tv" is set to be locked (immutable). |
24048 * Also give an error message, using "name" or _("name") when use_gettext is | 23228 * Also give an error message, using "name" or _("name") when use_gettext is |
24049 * TRUE. | 23229 * TRUE. |
24050 */ | 23230 */ |
24051 static int | 23231 int |
24052 tv_check_lock(int lock, char_u *name, int use_gettext) | 23232 tv_check_lock(int lock, char_u *name, int use_gettext) |
24053 { | 23233 { |
24054 if (lock & VAR_LOCKED) | 23234 if (lock & VAR_LOCKED) |
24055 { | 23235 { |
24056 EMSG2(_("E741: Value is locked: %s"), | 23236 EMSG2(_("E741: Value is locked: %s"), |
24156 * Lists and Dictionaries are also copied. A deep copy if "deep" is set. | 23336 * Lists and Dictionaries are also copied. A deep copy if "deep" is set. |
24157 * For deepcopy() "copyID" is zero for a full copy or the ID for when a | 23337 * For deepcopy() "copyID" is zero for a full copy or the ID for when a |
24158 * reference to an already copied list/dict can be used. | 23338 * reference to an already copied list/dict can be used. |
24159 * Returns FAIL or OK. | 23339 * Returns FAIL or OK. |
24160 */ | 23340 */ |
24161 static int | 23341 int |
24162 item_copy( | 23342 item_copy( |
24163 typval_T *from, | 23343 typval_T *from, |
24164 typval_T *to, | 23344 typval_T *to, |
24165 int deep, | 23345 int deep, |
24166 int copyID) | 23346 int copyID) |