comparison src/eval.c @ 121:86d71ae0c85a v7.0042

updated for version 7.0042
author vimboss
date Wed, 19 Jan 2005 22:24:34 +0000
parents d4ea645c7748
children f455396f3c3f
comparison
equal deleted inserted replaced
120:34423a71d203 121:86d71ae0c85a
107 107
108 #define VAR_MAXNEST 100 /* maximum nesting of lists and dicts */ 108 #define VAR_MAXNEST 100 /* maximum nesting of lists and dicts */
109 109
110 /* 110 /*
111 * Structure to hold an item of a Dictionary. 111 * Structure to hold an item of a Dictionary.
112 * The key is copied into "di_key" to avoid an extra alloc/free for it.
112 */ 113 */
113 struct dictitem_S 114 struct dictitem_S
114 { 115 {
115 struct dictitem_S *di_next; /* next item in list */
116 char_u *di_key; /* key (never NULL!) */
117 typeval di_tv; /* type and value of the variable */ 116 typeval di_tv; /* type and value of the variable */
117 char_u di_key[1]; /* key (actually longer!) */
118 }; 118 };
119 119
120 typedef struct dictitem_S dictitem; 120 typedef struct dictitem_S dictitem;
121 121
122 /* 122 /*
123 * In a hashtable item "hi_key" points to "di_key" in a dictitem.
124 * This avoids adding a pointer to the hashtable item.
125 * DI2HIKEY() converts a dictitem pointer to a hashitem key pointer.
126 * HIKEY2DI() converts a hashitem key pointer to a dictitem pointer.
127 * HI2DI() converts a hashitem pointer to a dictitem pointer.
128 */
129 static dictitem dumdi;
130 #define DI2HIKEY(p) ((p)->di_key)
131 #define HIKEY2DI(p) ((dictitem *)(p - (dumdi.di_key - (char_u *)&dumdi.di_tv)))
132 #define HI2DI(p) HIKEY2DI((p)->hi_key)
133
134 /*
123 * Structure to hold info about a Dictionary. 135 * Structure to hold info about a Dictionary.
124 */ 136 */
125 struct dictvar_S 137 struct dictvar_S
126 { 138 {
127 int dv_refcount; /* reference count */ 139 int dv_refcount; /* reference count */
128 dictitem *dv_first; /* first item, NULL if none */ 140 hashtable dv_hashtable; /* hashtable that refers to the items */
129 }; 141 };
130 142
131 typedef struct dictvar_S dictvar; 143 typedef struct dictvar_S dictvar;
132 144
133 /* 145 /*
171 long ll_n2; /* Second index for list range */ 183 long ll_n2; /* Second index for list range */
172 int ll_empty2; /* Second index is empty: [i:] */ 184 int ll_empty2; /* Second index is empty: [i:] */
173 dictvar *ll_dict; /* The Dictionary or NULL */ 185 dictvar *ll_dict; /* The Dictionary or NULL */
174 dictitem *ll_di; /* The dictitem or NULL */ 186 dictitem *ll_di; /* The dictitem or NULL */
175 char_u *ll_newkey; /* New key for Dict in alloc. mem or NULL. */ 187 char_u *ll_newkey; /* New key for Dict in alloc. mem or NULL. */
176 dictitem **ll_pdi; /* di_next field pointing to found dictitem */
177 } lval; 188 } lval;
178 189
179 190
180 static char *e_letunexp = N_("E18: Unexpected characters in :let"); 191 static char *e_letunexp = N_("E18: Unexpected characters in :let");
181 static char *e_listidx = N_("E684: list index out of range: %ld"); 192 static char *e_listidx = N_("E684: list index out of range: %ld");
182 static char *e_undefvar = N_("E121: Undefined variable: %s"); 193 static char *e_undefvar = N_("E121: Undefined variable: %s");
183 static char *e_missbrac = N_("E111: Missing ']'"); 194 static char *e_missbrac = N_("E111: Missing ']'");
184 static char *e_intern2 = N_("E685: Internal error: %s");
185 static char *e_listarg = N_("E686: Argument of %s must be a List"); 195 static char *e_listarg = N_("E686: Argument of %s must be a List");
186 static char *e_listdictarg = N_("E712: Argument of %s must be a List or Dictionaary"); 196 static char *e_listdictarg = N_("E712: Argument of %s must be a List or Dictionaary");
187 static char *e_emptykey = N_("E713: Empty key in Dictionary"); 197 static char *e_emptykey = N_("E713: Cannot use empty key for Dictionary");
188 static char *e_listreq = N_("E714: List required"); 198 static char *e_listreq = N_("E714: List required");
189 static char *e_dictreq = N_("E715: Dictionary required"); 199 static char *e_dictreq = N_("E715: Dictionary required");
190 static char *e_toomanyarg = N_("E118: Too many arguments for function: %s"); 200 static char *e_toomanyarg = N_("E118: Too many arguments for function: %s");
191 static char *e_dictkey = N_("E716: Key not present in Dictionary: %s"); 201 static char *e_dictkey = N_("E716: Key not present in Dictionary: %s");
192 static char *e_funcexts = N_("E122: Function %s already exists, add ! to replace it"); 202 static char *e_funcexts = N_("E122: Function %s already exists, add ! to replace it");
287 typedef struct 297 typedef struct
288 { 298 {
289 dictvar *fd_dict; /* Dictionary used */ 299 dictvar *fd_dict; /* Dictionary used */
290 char_u *fd_newkey; /* new key in "dict" */ 300 char_u *fd_newkey; /* new key in "dict" */
291 dictitem *fd_di; /* Dictionary item used */ 301 dictitem *fd_di; /* Dictionary item used */
292 dictitem **fd_pdi; /* field that points to "fd_di" */
293 } funcdict; 302 } funcdict;
294 303
295 /* 304 /*
296 * Return the name of the executed function. 305 * Return the name of the executed function.
297 */ 306 */
449 static void list_join __ARGS((garray_T *gap, listvar *l, char_u *sep, int echo)); 458 static void list_join __ARGS((garray_T *gap, listvar *l, char_u *sep, int echo));
450 459
451 static dictvar *dict_alloc __ARGS((void)); 460 static dictvar *dict_alloc __ARGS((void));
452 static void dict_unref __ARGS((dictvar *d)); 461 static void dict_unref __ARGS((dictvar *d));
453 static void dict_free __ARGS((dictvar *d)); 462 static void dict_free __ARGS((dictvar *d));
454 static dictitem *dictitem_alloc __ARGS((void)); 463 static dictitem *dictitem_alloc __ARGS((char_u *key));
455 static dictitem *dictitem_copy __ARGS((dictitem *org)); 464 static dictitem *dictitem_copy __ARGS((dictitem *org));
465 static void dictitem_remove __ARGS((dictvar *dict, dictitem *item));
456 static void dictitem_free __ARGS((dictitem *item)); 466 static void dictitem_free __ARGS((dictitem *item));
457 static void dict_add __ARGS((dictvar *d, dictitem *item)); 467 static int dict_add __ARGS((dictvar *d, dictitem *item));
458 static long dict_len __ARGS((dictvar *d)); 468 static long dict_len __ARGS((dictvar *d));
459 static dictitem *dict_find __ARGS((dictvar *d, char_u *key, int len, dictitem ***pdi)); 469 static dictitem *dict_find __ARGS((dictvar *d, char_u *key, int len));
460 static char_u *dict2string __ARGS((typeval *tv)); 470 static char_u *dict2string __ARGS((typeval *tv));
461 static int get_dict_tv __ARGS((char_u **arg, typeval *rettv, int evaluate)); 471 static int get_dict_tv __ARGS((char_u **arg, typeval *rettv, int evaluate));
462 472
463 static char_u *echo_string __ARGS((typeval *tv, char_u **tofree, char_u *numbuf)); 473 static char_u *echo_string __ARGS((typeval *tv, char_u **tofree, char_u *numbuf));
464 static char_u *tv2string __ARGS((typeval *tv, char_u **tofree, char_u *numbuf)); 474 static char_u *tv2string __ARGS((typeval *tv, char_u **tofree, char_u *numbuf));
1827 /* Report an invalid expression in braces, unless the 1837 /* Report an invalid expression in braces, unless the
1828 * expression evaluation has been cancelled due to an 1838 * expression evaluation has been cancelled due to an
1829 * aborting error, an interrupt, or an exception. */ 1839 * aborting error, an interrupt, or an exception. */
1830 if (!aborting() && !quiet) 1840 if (!aborting() && !quiet)
1831 { 1841 {
1832 if (unlet) 1842 emsg_severe = TRUE;
1833 emsg_severe = TRUE;
1834 EMSG2(_(e_invarg2), name); 1843 EMSG2(_(e_invarg2), name);
1835 return NULL; 1844 return NULL;
1836 } 1845 }
1837 } 1846 }
1838 lp->ll_name = lp->ll_exp_name; 1847 lp->ll_name = lp->ll_exp_name;
1968 return NULL; 1977 return NULL;
1969 } 1978 }
1970 } 1979 }
1971 lp->ll_list = NULL; 1980 lp->ll_list = NULL;
1972 lp->ll_dict = lp->ll_tv->vval.v_dict; 1981 lp->ll_dict = lp->ll_tv->vval.v_dict;
1973 lp->ll_di = dict_find(lp->ll_dict, key, len, &lp->ll_pdi); 1982 lp->ll_di = dict_find(lp->ll_dict, key, len);
1974 if (lp->ll_di == NULL) 1983 if (lp->ll_di == NULL)
1975 { 1984 {
1976 /* Key does not exist in dict: may need toadd it. */ 1985 /* Key does not exist in dict: may need to add it. */
1977 if (*p == '[' || *p == '.' || unlet) 1986 if (*p == '[' || *p == '.' || unlet)
1978 { 1987 {
1979 if (!quiet) 1988 if (!quiet)
1980 EMSG2(_(e_dictkey), key); 1989 EMSG2(_(e_dictkey), key);
1981 if (len == -1) 1990 if (len == -1)
2163 EMSG2(_(e_letwrong), op); 2172 EMSG2(_(e_letwrong), op);
2164 return; 2173 return;
2165 } 2174 }
2166 2175
2167 /* Need to add an item to the Dictionary. */ 2176 /* Need to add an item to the Dictionary. */
2168 di = dictitem_alloc(); 2177 di = dictitem_alloc(lp->ll_newkey);
2169 if (di == NULL) 2178 if (di == NULL)
2170 return; 2179 return;
2171 di->di_key = lp->ll_newkey; 2180 if (dict_add(lp->ll_tv->vval.v_dict, di) == FAIL)
2172 lp->ll_newkey = NULL; 2181 {
2173 dict_add(lp->ll_tv->vval.v_dict, di); 2182 vim_free(di);
2183 return;
2184 }
2174 lp->ll_tv = &di->di_tv; 2185 lp->ll_tv = &di->di_tv;
2175 } 2186 }
2176 else if (op != NULL && *op != '=') 2187 else if (op != NULL && *op != '=')
2177 { 2188 {
2178 tv_op(lp->ll_tv, rettv, op); 2189 tv_op(lp->ll_tv, rettv, op);
2530 int len; 2541 int len;
2531 typeval rettv; 2542 typeval rettv;
2532 linenr_T lnum; 2543 linenr_T lnum;
2533 int doesrange; 2544 int doesrange;
2534 int failed = FALSE; 2545 int failed = FALSE;
2535 2546 funcdict fudi;
2536 tofree = trans_function_name(&arg, eap->skip, TFN_INT, NULL); 2547
2548 tofree = trans_function_name(&arg, eap->skip, TFN_INT, &fudi);
2549 vim_free(fudi.fd_newkey);
2537 if (tofree == NULL) 2550 if (tofree == NULL)
2538 return; 2551 return;
2552
2553 /* Increase refcount on dictionary, it could get deleted when evaluating
2554 * the arguments. */
2555 if (fudi.fd_dict != NULL)
2556 ++fudi.fd_dict->dv_refcount;
2539 2557
2540 /* If it is the name of a variable of type VAR_FUNC use its contents. */ 2558 /* If it is the name of a variable of type VAR_FUNC use its contents. */
2541 len = STRLEN(tofree); 2559 len = STRLEN(tofree);
2542 name = deref_func_name(tofree, &len); 2560 name = deref_func_name(tofree, &len);
2543 2561
2570 curwin->w_cursor.lnum = lnum; 2588 curwin->w_cursor.lnum = lnum;
2571 curwin->w_cursor.col = 0; 2589 curwin->w_cursor.col = 0;
2572 } 2590 }
2573 arg = startarg; 2591 arg = startarg;
2574 if (get_func_tv(name, STRLEN(name), &rettv, &arg, 2592 if (get_func_tv(name, STRLEN(name), &rettv, &arg,
2575 eap->line1, eap->line2, &doesrange, !eap->skip, NULL) == FAIL) 2593 eap->line1, eap->line2, &doesrange,
2594 !eap->skip, fudi.fd_dict) == FAIL)
2576 { 2595 {
2577 failed = TRUE; 2596 failed = TRUE;
2578 break; 2597 break;
2579 } 2598 }
2580 clear_tv(&rettv); 2599 clear_tv(&rettv);
2601 else 2620 else
2602 eap->nextcmd = check_nextcmd(arg); 2621 eap->nextcmd = check_nextcmd(arg);
2603 } 2622 }
2604 2623
2605 end: 2624 end:
2625 dict_unref(fudi.fd_dict);
2606 vim_free(tofree); 2626 vim_free(tofree);
2607 } 2627 }
2608 2628
2609 /* 2629 /*
2610 * ":unlet[!] var1 ... " command. 2630 * ":unlet[!] var1 ... " command.
2689 ++lp->ll_n1; 2709 ++lp->ll_n1;
2690 } 2710 }
2691 } 2711 }
2692 else 2712 else
2693 { 2713 {
2694 clear_tv(lp->ll_tv);
2695 if (lp->ll_list != NULL) 2714 if (lp->ll_list != NULL)
2696 {
2697 /* unlet a List item. */ 2715 /* unlet a List item. */
2698 listitem_remove(lp->ll_list, lp->ll_li); 2716 listitem_remove(lp->ll_list, lp->ll_li);
2699 }
2700 else 2717 else
2701 {
2702 /* unlet a Dictionary item. */ 2718 /* unlet a Dictionary item. */
2703 *lp->ll_pdi = lp->ll_di->di_next; 2719 dictitem_remove(lp->ll_dict, lp->ll_di);
2704 dictitem_free(lp->ll_di);
2705 }
2706 } 2720 }
2707 2721
2708 return ret; 2722 return ret;
2709 } 2723 }
2710 2724
3759 *arg = skipwhite(*arg); 3773 *arg = skipwhite(*arg);
3760 3774
3761 /* 3775 /*
3762 * Handle expr[expr], expr[expr:expr] subscript and .name lookup. 3776 * Handle expr[expr], expr[expr:expr] subscript and .name lookup.
3763 * Also handle function call with Funcref variable: func(expr) 3777 * Also handle function call with Funcref variable: func(expr)
3764 * Can all be combined: dict.func(expr)[idx].func(expr) 3778 * Can all be combined: dict.func(expr)[idx]['func'](expr)
3765 */ 3779 */
3766 selfdict = NULL; 3780 selfdict = NULL;
3767 while (ret == OK 3781 while (ret == OK
3768 && (**arg == '[' 3782 && (**arg == '['
3769 || (**arg == '.' && rettv->v_type == VAR_DICT) 3783 || (**arg == '.' && rettv->v_type == VAR_DICT)
3777 /* Invoke the function. Recursive! */ 3791 /* Invoke the function. Recursive! */
3778 ret = get_func_tv(s, STRLEN(s), rettv, arg, 3792 ret = get_func_tv(s, STRLEN(s), rettv, arg,
3779 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 3793 curwin->w_cursor.lnum, curwin->w_cursor.lnum,
3780 &len, evaluate, selfdict); 3794 &len, evaluate, selfdict);
3781 3795
3782 /* Stop the expression evaluation when immediately 3796 /* Stop the expression evaluation when immediately aborting on
3783 * aborting on error, or when an interrupt occurred or 3797 * error, or when an interrupt occurred or an exception was thrown
3784 * an exception was thrown but not caught. */ 3798 * but not caught. */
3785 if (aborting()) 3799 if (aborting())
3786 { 3800 {
3787 if (ret == OK) 3801 if (ret == OK)
3788 clear_tv(rettv); 3802 clear_tv(rettv);
3789 ret = FAIL; 3803 ret = FAIL;
3790 } 3804 }
3805 dict_unref(selfdict);
3791 selfdict = NULL; 3806 selfdict = NULL;
3792 } 3807 }
3793 else 3808 else /* **arg == '[' || **arg == '.' */
3794 { 3809 {
3810 dict_unref(selfdict);
3795 if (rettv->v_type == VAR_DICT) 3811 if (rettv->v_type == VAR_DICT)
3812 {
3796 selfdict = rettv->vval.v_dict; 3813 selfdict = rettv->vval.v_dict;
3814 if (selfdict != NULL)
3815 ++selfdict->dv_refcount;
3816 }
3797 else 3817 else
3798 selfdict = NULL; 3818 selfdict = NULL;
3799 if (eval_index(arg, rettv, evaluate) == FAIL) 3819 if (eval_index(arg, rettv, evaluate) == FAIL)
3800 { 3820 {
3801 clear_tv(rettv); 3821 clear_tv(rettv);
3802 ret = FAIL; 3822 ret = FAIL;
3803 } 3823 }
3804 } 3824 }
3805 } 3825 }
3826 dict_unref(selfdict);
3806 3827
3807 /* 3828 /*
3808 * Apply logical NOT and unary '-', from right to left, ignore '+'. 3829 * Apply logical NOT and unary '-', from right to left, ignore '+'.
3809 */ 3830 */
3810 if (ret == OK && evaluate && end_leader > start_leader) 3831 if (ret == OK && evaluate && end_leader > start_leader)
4031 clear_tv(&var1); 4052 clear_tv(&var1);
4032 return FAIL; 4053 return FAIL;
4033 } 4054 }
4034 } 4055 }
4035 4056
4036 item = dict_find(rettv->vval.v_dict, key, (int)len, NULL); 4057 item = dict_find(rettv->vval.v_dict, key, (int)len);
4037 4058
4038 if (item == NULL) 4059 if (item == NULL)
4039 EMSG2(_(e_dictkey), key); 4060 EMSG2(_(e_dictkey), key);
4040 if (len == -1) 4061 if (len == -1)
4041 clear_tv(&var1); 4062 clear_tv(&var1);
4369 if (item != NULL) 4390 if (item != NULL)
4370 { 4391 {
4371 item->li_tv = tv; 4392 item->li_tv = tv;
4372 list_append(l, item); 4393 list_append(l, item);
4373 } 4394 }
4395 else
4396 clear_tv(&tv);
4374 } 4397 }
4375 4398
4376 if (**arg == ']') 4399 if (**arg == ']')
4377 break; 4400 break;
4378 if (**arg != ',') 4401 if (**arg != ',')
4521 dict_equal(d1, d2, ic) 4544 dict_equal(d1, d2, ic)
4522 dictvar *d1; 4545 dictvar *d1;
4523 dictvar *d2; 4546 dictvar *d2;
4524 int ic; /* ignore case for strings */ 4547 int ic; /* ignore case for strings */
4525 { 4548 {
4526 dictitem *item1, *item2; 4549 hashitem *hi;
4550 dictitem *item2;
4551 int todo;
4527 4552
4528 if (dict_len(d1) != dict_len(d2)) 4553 if (dict_len(d1) != dict_len(d2))
4529 return FALSE; 4554 return FALSE;
4530 4555
4531 for (item1 = d1->dv_first; item1 != NULL; item1 = item1->di_next) 4556 todo = d1->dv_hashtable.ht_used;
4532 { 4557 for (hi = d1->dv_hashtable.ht_array; todo > 0; ++hi)
4533 item2 = dict_find(d2, item1->di_key, -1, NULL); 4558 {
4534 if (item2 == NULL) 4559 if (!HASHITEM_EMPTY(hi))
4535 return FALSE; 4560 {
4536 if (!tv_equal(&item1->di_tv, &item2->di_tv, ic)) 4561 item2 = dict_find(d2, hi->hi_key, -1);
4537 return FALSE; 4562 if (item2 == NULL)
4563 return FALSE;
4564 if (!tv_equal(&HI2DI(hi)->di_tv, &item2->di_tv, ic))
4565 return FALSE;
4566 --todo;
4567 }
4538 } 4568 }
4539 return TRUE; 4569 return TRUE;
4540 } 4570 }
4541 4571
4542 /* 4572 /*
4554 if (tv1->v_type == VAR_LIST || tv2->v_type == VAR_LIST) 4584 if (tv1->v_type == VAR_LIST || tv2->v_type == VAR_LIST)
4555 { 4585 {
4556 /* recursive! */ 4586 /* recursive! */
4557 if (tv1->v_type != tv2->v_type 4587 if (tv1->v_type != tv2->v_type
4558 || !list_equal(tv1->vval.v_list, tv2->vval.v_list, ic)) 4588 || !list_equal(tv1->vval.v_list, tv2->vval.v_list, ic))
4589 return FALSE;
4590 }
4591 else if (tv1->v_type == VAR_DICT || tv2->v_type == VAR_DICT)
4592 {
4593 /* recursive! */
4594 if (tv1->v_type != tv2->v_type
4595 || !dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic))
4559 return FALSE; 4596 return FALSE;
4560 } 4597 }
4561 else if (tv1->v_type == VAR_FUNC || tv2->v_type == VAR_FUNC) 4598 else if (tv1->v_type == VAR_FUNC || tv2->v_type == VAR_FUNC)
4562 { 4599 {
4563 if (tv1->v_type != tv2->v_type 4600 if (tv1->v_type != tv2->v_type
4929 * Allocate an empty header for a dictionary. 4966 * Allocate an empty header for a dictionary.
4930 */ 4967 */
4931 static dictvar * 4968 static dictvar *
4932 dict_alloc() 4969 dict_alloc()
4933 { 4970 {
4934 return (dictvar *)alloc_clear(sizeof(dictvar)); 4971 dictvar *d;
4972
4973 d = (dictvar *)alloc(sizeof(dictvar));
4974 if (d != NULL)
4975 hash_init(&d->dv_hashtable);
4976 return d;
4935 } 4977 }
4936 4978
4937 /* 4979 /*
4938 * Unreference a Dictionary: decrement the reference count and free it when it 4980 * Unreference a Dictionary: decrement the reference count and free it when it
4939 * becomes zero. 4981 * becomes zero.
4952 */ 4994 */
4953 static void 4995 static void
4954 dict_free(d) 4996 dict_free(d)
4955 dictvar *d; 4997 dictvar *d;
4956 { 4998 {
4957 dictitem *item; 4999 int todo;
4958 dictitem *next; 5000 hashitem *hi;
4959 5001
4960 for (item = d->dv_first; item != NULL; item = next) 5002 /* Careful: we free the dictitems while they still appear in the
4961 { 5003 * hashtable. Must not try to resize the hashtable! */
4962 next = item->di_next; 5004 todo = d->dv_hashtable.ht_used;
4963 dictitem_free(item); 5005 for (hi = d->dv_hashtable.ht_array; todo > 0; ++hi)
5006 {
5007 if (!HASHITEM_EMPTY(hi))
5008 {
5009 dictitem_free(HI2DI(hi));
5010 --todo;
5011 }
4964 } 5012 }
4965 vim_free(d); 5013 vim_free(d);
4966 } 5014 }
4967 5015
4968 /* 5016 /*
4969 * Allocate a Dictionary item. 5017 * Allocate a Dictionary item.
5018 * The "key" is copied to the new item.
5019 * Note that the value of the item "di_tv" still needs to be initialized!
5020 * Returns NULL when out of memory.
4970 */ 5021 */
4971 static dictitem * 5022 static dictitem *
4972 dictitem_alloc() 5023 dictitem_alloc(key)
4973 { 5024 char_u *key;
4974 return (dictitem *)alloc(sizeof(dictitem)); 5025 {
5026 dictitem *di;
5027
5028 di = (dictitem *)alloc(sizeof(dictitem) + STRLEN(key));
5029 if (di != NULL)
5030 STRCPY(di->di_key, key);
5031 return di;
4975 } 5032 }
4976 5033
4977 /* 5034 /*
4978 * Make a copy of a Dictionary item. 5035 * Make a copy of a Dictionary item.
4979 */ 5036 */
4981 dictitem_copy(org) 5038 dictitem_copy(org)
4982 dictitem *org; 5039 dictitem *org;
4983 { 5040 {
4984 dictitem *di; 5041 dictitem *di;
4985 5042
4986 di = (dictitem *)alloc(sizeof(dictitem)); 5043 di = (dictitem *)alloc(sizeof(dictitem) + STRLEN(org->di_key));
4987 if (di != NULL) 5044 if (di != NULL)
4988 { 5045 {
4989 di->di_key = vim_strsave(org->di_key); 5046 STRCPY(di->di_key, org->di_key);
4990 if (di->di_key == NULL)
4991 {
4992 vim_free(di);
4993 return NULL;
4994 }
4995 copy_tv(&org->di_tv, &di->di_tv); 5047 copy_tv(&org->di_tv, &di->di_tv);
4996 } 5048 }
4997 return di; 5049 return di;
5050 }
5051
5052 /*
5053 * Remove item "item" from Dictionary "dict" and free it.
5054 */
5055 static void
5056 dictitem_remove(dict, item)
5057 dictvar *dict;
5058 dictitem *item;
5059 {
5060 hashitem *hi;
5061
5062 hi = hash_find(&dict->dv_hashtable, item->di_key);
5063 if (HASHITEM_EMPTY(hi))
5064 EMSG2(_(e_intern2), "dictitem_remove()");
5065 else
5066 hash_remove(&dict->dv_hashtable, hi);
5067 dictitem_free(item);
4998 } 5068 }
4999 5069
5000 /* 5070 /*
5001 * Free a dict item. Also clears the value. 5071 * Free a dict item. Also clears the value.
5002 */ 5072 */
5003 static void 5073 static void
5004 dictitem_free(item) 5074 dictitem_free(item)
5005 dictitem *item; 5075 dictitem *item;
5006 { 5076 {
5007 vim_free(item->di_key);
5008 clear_tv(&item->di_tv); 5077 clear_tv(&item->di_tv);
5009 vim_free(item); 5078 vim_free(item);
5010 } 5079 }
5011 5080
5012 /* 5081 /*
5018 dict_copy(orig, deep) 5087 dict_copy(orig, deep)
5019 dictvar *orig; 5088 dictvar *orig;
5020 int deep; 5089 int deep;
5021 { 5090 {
5022 dictvar *copy; 5091 dictvar *copy;
5023 dictitem *item;
5024 dictitem *di; 5092 dictitem *di;
5093 int todo;
5094 hashitem *hi;
5025 5095
5026 if (orig == NULL) 5096 if (orig == NULL)
5027 return NULL; 5097 return NULL;
5028 5098
5029 copy = dict_alloc(); 5099 copy = dict_alloc();
5030 if (copy != NULL) 5100 if (copy != NULL)
5031 { 5101 {
5032 for (item = orig->dv_first; item != NULL; item = item->di_next) 5102 todo = orig->dv_hashtable.ht_used;
5033 { 5103 for (hi = orig->dv_hashtable.ht_array; todo > 0; ++hi)
5034 di = dictitem_alloc(); 5104 {
5035 if (di == NULL) 5105 if (!HASHITEM_EMPTY(hi))
5036 break;
5037 di->di_key = vim_strsave(item->di_key);
5038 if (di->di_key == NULL)
5039 { 5106 {
5040 vim_free(di); 5107 --todo;
5041 break; 5108
5109 di = dictitem_alloc(hi->hi_key);
5110 if (di == NULL)
5111 break;
5112 if (deep)
5113 item_copy(&HI2DI(hi)->di_tv, &di->di_tv, deep);
5114 else
5115 copy_tv(&HI2DI(hi)->di_tv, &di->di_tv);
5116 if (dict_add(copy, di) == FAIL)
5117 {
5118 dictitem_free(di);
5119 break;
5120 }
5042 } 5121 }
5043 if (deep) 5122 }
5044 item_copy(&item->di_tv, &di->di_tv, deep); 5123
5045 else
5046 copy_tv(&item->di_tv, &di->di_tv);
5047 dict_add(copy, di);
5048 }
5049 ++copy->dv_refcount; 5124 ++copy->dv_refcount;
5050 } 5125 }
5051 5126
5052 return copy; 5127 return copy;
5053 } 5128 }
5054 5129
5055 /* 5130 /*
5056 * Add item "item" to Dictionary "d". 5131 * Add item "item" to Dictionary "d".
5057 */ 5132 * Returns FAIL when out of memory and when key already existed.
5058 static void 5133 */
5134 static int
5059 dict_add(d, item) 5135 dict_add(d, item)
5060 dictvar *d; 5136 dictvar *d;
5061 dictitem *item; 5137 dictitem *item;
5062 { 5138 {
5063 item->di_next = d->dv_first; 5139 return hash_add(&d->dv_hashtable, item->di_key);
5064 d->dv_first = item; 5140 }
5065 }
5066
5067 #if 0 /* not currently used */
5068 static void dict_set_item __ARGS((dictvar *d, int type, char *key, void *val));
5069
5070 /*
5071 * Add an item to Dictionary "d" with type "type", key "key" and value "val".
5072 * If it already exists it is overwritten.
5073 * The key and value are copied to allocated memory.
5074 */
5075 static void
5076 dict_set_item(d, type, key, val)
5077 dictvar *d;
5078 int type;
5079 char *key;
5080 void *val;
5081 {
5082 dictitem *di;
5083 char_u *dkey;
5084
5085 di = dict_find(d, (char_u *)key, -1, NULL);
5086 if (di == NULL)
5087 {
5088 dkey = vim_strsave((char_u *)key);
5089 if (dkey != NULL)
5090 {
5091 di = dictitem_alloc();
5092 if (di == NULL)
5093 vim_free(dkey);
5094 else
5095 di->di_key = dkey;
5096 }
5097 }
5098 else
5099 clear_tv(&di->di_tv);
5100
5101 if (di != NULL)
5102 {
5103 di->di_tv.v_type = type;
5104 switch (type)
5105 {
5106 case VAR_NUMBER:
5107 di->di_tv.vval.v_number = (varnumber_T)val;
5108 break;
5109 case VAR_FUNC:
5110 case VAR_STRING:
5111 di->di_tv.vval.v_string = vim_strsave((char_u *)val);
5112 break;
5113 default:
5114 EMSG2(_(e_intern2), "dict_set_item()");
5115 }
5116 dict_add(d, di);
5117 }
5118 }
5119 #endif
5120 5141
5121 /* 5142 /*
5122 * Get the number of items in a Dictionary. 5143 * Get the number of items in a Dictionary.
5123 */ 5144 */
5124 static long 5145 static long
5125 dict_len(d) 5146 dict_len(d)
5126 dictvar *d; 5147 dictvar *d;
5127 { 5148 {
5128 dictitem *item;
5129 long len = 0;
5130
5131 if (d == NULL) 5149 if (d == NULL)
5132 return 0L; 5150 return 0L;
5133 for (item = d->dv_first; item != NULL; item = item->di_next) 5151 return d->dv_hashtable.ht_used;
5134 ++len;
5135 return len;
5136 } 5152 }
5137 5153
5138 /* 5154 /*
5139 * Find item "key[len]" in Dictionary "d". 5155 * Find item "key[len]" in Dictionary "d".
5140 * If "len" is negative use strlen(key). 5156 * If "len" is negative use strlen(key).
5141 * Sets "*pdi" to pointer to found item, unless "pdi" is NULL.
5142 * Returns NULL when not found. 5157 * Returns NULL when not found.
5143 */ 5158 */
5144 static dictitem * 5159 static dictitem *
5145 dict_find(d, key, len, pdi) 5160 dict_find(d, key, len)
5146 dictvar *d; 5161 dictvar *d;
5147 char_u *key; 5162 char_u *key;
5148 int len; 5163 int len;
5149 dictitem ***pdi; 5164 {
5150 { 5165 #define AKEYLEN 200
5151 static dictitem *di; 5166 char_u buf[AKEYLEN];
5152 5167 char_u *akey;
5153 if (pdi != NULL) 5168 char_u *tofree = NULL;
5154 *pdi = &d->dv_first; 5169 hashitem *hi;
5155 for (di = d->dv_first; di != NULL; di = di->di_next) 5170
5156 { 5171 if (len < 0)
5157 if (len < 0 5172 akey = key;
5158 ? STRCMP(di->di_key, key) == 0 5173 else if (len >= AKEYLEN)
5159 : STRNCMP(di->di_key, key, len) == 0 && di->di_key[len] == NUL) 5174 {
5160 return di; 5175 tofree = akey = vim_strnsave(key, len);
5161 if (pdi != NULL) 5176 if (akey == NULL)
5162 *pdi = &di->di_next; 5177 return NULL;
5163 } 5178 }
5164 return NULL; 5179 else
5180 {
5181 /* Avoid a malloc/free by using buf[]. */
5182 STRNCPY(buf, key, len);
5183 buf[len] = NUL;
5184 akey = buf;
5185 }
5186
5187 hi = hash_find(&d->dv_hashtable, akey);
5188 vim_free(tofree);
5189 if (HASHITEM_EMPTY(hi))
5190 return NULL;
5191 return HI2DI(hi);
5165 } 5192 }
5166 5193
5167 /* 5194 /*
5168 * Return an allocated string with the string representation of a Dictionary. 5195 * Return an allocated string with the string representation of a Dictionary.
5169 * May return NULL. 5196 * May return NULL.
5174 { 5201 {
5175 garray_T ga; 5202 garray_T ga;
5176 int first = TRUE; 5203 int first = TRUE;
5177 char_u *tofree; 5204 char_u *tofree;
5178 char_u numbuf[NUMBUFLEN]; 5205 char_u numbuf[NUMBUFLEN];
5179 dictitem *item; 5206 hashitem *hi;
5180 char_u *s; 5207 char_u *s;
5181 5208 dictvar *d;
5182 if (tv->vval.v_dict == NULL) 5209 int todo;
5210
5211 if ((d = tv->vval.v_dict) == NULL)
5183 return NULL; 5212 return NULL;
5184 ga_init2(&ga, (int)sizeof(char), 80); 5213 ga_init2(&ga, (int)sizeof(char), 80);
5185 ga_append(&ga, '{'); 5214 ga_append(&ga, '{');
5186 5215
5187 for (item = tv->vval.v_dict->dv_first; item != NULL; item = item->di_next) 5216 todo = d->dv_hashtable.ht_used;
5188 { 5217 for (hi = d->dv_hashtable.ht_array; todo > 0; ++hi)
5189 if (first) 5218 {
5190 first = FALSE; 5219 if (!HASHITEM_EMPTY(hi))
5191 else 5220 {
5192 ga_concat(&ga, (char_u *)", "); 5221 --todo;
5193 5222
5194 tofree = string_quote(item->di_key, FALSE); 5223 if (first)
5195 if (tofree != NULL) 5224 first = FALSE;
5196 { 5225 else
5197 ga_concat(&ga, tofree); 5226 ga_concat(&ga, (char_u *)", ");
5227
5228 tofree = string_quote(hi->hi_key, FALSE);
5229 if (tofree != NULL)
5230 {
5231 ga_concat(&ga, tofree);
5232 vim_free(tofree);
5233 }
5234 ga_concat(&ga, (char_u *)": ");
5235 s = tv2string(&HI2DI(hi)->di_tv, &tofree, numbuf);
5236 if (s != NULL)
5237 ga_concat(&ga, s);
5198 vim_free(tofree); 5238 vim_free(tofree);
5199 } 5239 }
5200 ga_concat(&ga, (char_u *)": ");
5201 s = tv2string(&item->di_tv, &tofree, numbuf);
5202 if (s != NULL)
5203 ga_concat(&ga, s);
5204 vim_free(tofree);
5205 } 5240 }
5206 5241
5207 ga_append(&ga, '}'); 5242 ga_append(&ga, '}');
5208 ga_append(&ga, NUL); 5243 ga_append(&ga, NUL);
5209 return (char_u *)ga.ga_data; 5244 return (char_u *)ga.ga_data;
5218 char_u **arg; 5253 char_u **arg;
5219 typeval *rettv; 5254 typeval *rettv;
5220 int evaluate; 5255 int evaluate;
5221 { 5256 {
5222 dictvar *d = NULL; 5257 dictvar *d = NULL;
5258 typeval tvkey;
5223 typeval tv; 5259 typeval tv;
5224 char_u *key; 5260 char_u *key;
5225 dictitem *item; 5261 dictitem *item;
5226 char_u *start = skipwhite(*arg + 1); 5262 char_u *start = skipwhite(*arg + 1);
5263 char_u buf[NUMBUFLEN];
5227 5264
5228 /* 5265 /*
5229 * First check if it's not a curly-braces thing: {expr}. 5266 * First check if it's not a curly-braces thing: {expr}.
5230 * Must do this without evaluating, otherwise a function may be called 5267 * Must do this without evaluating, otherwise a function may be called
5231 * twice. Unfortunately this means we need to call eval1() twice for the 5268 * twice. Unfortunately this means we need to call eval1() twice for the
5244 { 5281 {
5245 d = dict_alloc(); 5282 d = dict_alloc();
5246 if (d == NULL) 5283 if (d == NULL)
5247 return FAIL; 5284 return FAIL;
5248 } 5285 }
5286 tvkey.v_type = VAR_UNKNOWN;
5287 tv.v_type = VAR_UNKNOWN;
5249 5288
5250 *arg = skipwhite(*arg + 1); 5289 *arg = skipwhite(*arg + 1);
5251 while (**arg != '}' && **arg != NUL) 5290 while (**arg != '}' && **arg != NUL)
5252 { 5291 {
5253 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 5292 if (eval1(arg, &tvkey, evaluate) == FAIL) /* recursive! */
5254 goto failret; 5293 goto failret;
5255 if (**arg != ':') 5294 if (**arg != ':')
5256 { 5295 {
5257 EMSG2(_("E720: Missing colon in Dictionary: %s"), *arg); 5296 EMSG2(_("E720: Missing colon in Dictionary: %s"), *arg);
5258 clear_tv(&tv); 5297 clear_tv(&tvkey);
5259 goto failret; 5298 goto failret;
5260 } 5299 }
5261 key = get_tv_string(&tv); 5300 key = get_tv_string_buf(&tvkey, buf);
5262 if (*key == NUL) 5301 if (*key == NUL)
5263 { 5302 {
5264 EMSG(_(e_emptykey)); 5303 EMSG(_(e_emptykey));
5265 clear_tv(&tv); 5304 clear_tv(&tvkey);
5266 goto failret; 5305 goto failret;
5267 } 5306 }
5268 key = vim_strsave(key);
5269 clear_tv(&tv);
5270 if (key == NULL)
5271 goto failret;
5272 5307
5273 *arg = skipwhite(*arg + 1); 5308 *arg = skipwhite(*arg + 1);
5274 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 5309 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */
5275 { 5310 {
5276 vim_free(key); 5311 clear_tv(&tvkey);
5277 goto failret; 5312 goto failret;
5278 } 5313 }
5279 if (evaluate) 5314 if (evaluate)
5280 { 5315 {
5281 item = dict_find(d, key, -1, NULL); 5316 item = dict_find(d, key, -1);
5282 if (item != NULL) 5317 if (item != NULL)
5283 { 5318 {
5284 EMSG(_("E721: Duplicate key in Dictionary")); 5319 EMSG(_("E721: Duplicate key in Dictionary"));
5285 vim_free(key); 5320 clear_tv(&tvkey);
5286 clear_tv(&tv); 5321 clear_tv(&tv);
5287 goto failret; 5322 goto failret;
5288 } 5323 }
5289 item = dictitem_alloc(); 5324 item = dictitem_alloc(key);
5290 if (item == NULL) 5325 clear_tv(&tvkey);
5291 vim_free(key); 5326 if (item != NULL)
5292 else
5293 { 5327 {
5294 item->di_key = key;
5295 item->di_tv = tv; 5328 item->di_tv = tv;
5296 dict_add(d, item); 5329 if (dict_add(d, item) == FAIL)
5330 dictitem_free(item);
5297 } 5331 }
5298 } 5332 }
5299 5333
5300 if (**arg == '}') 5334 if (**arg == '}')
5301 break; 5335 break;
5992 saveRedobuff(); 6026 saveRedobuff();
5993 ++fp->calls; 6027 ++fp->calls;
5994 call_user_func(fp, argcount, argvars, rettv, 6028 call_user_func(fp, argcount, argvars, rettv,
5995 firstline, lastline, 6029 firstline, lastline,
5996 (fp->flags & FC_DICT) ? selfdict : NULL); 6030 (fp->flags & FC_DICT) ? selfdict : NULL);
5997 if (--fp->calls <= 0 && isdigit(*fp->name)) 6031 if (--fp->calls <= 0 && isdigit(*fp->name)
6032 && fp->refcount <= 0)
5998 /* Function was unreferenced while being used, free it 6033 /* Function was unreferenced while being used, free it
5999 * now. */ 6034 * now. */
6000 func_free(fp); 6035 func_free(fp);
6001 restoreRedobuff(); 6036 restoreRedobuff();
6002 restore_search_patterns(); 6037 restore_search_patterns();
6742 ++n; 6777 ++n;
6743 } 6778 }
6744 } 6779 }
6745 else if (argvars[0].v_type == VAR_DICT) 6780 else if (argvars[0].v_type == VAR_DICT)
6746 { 6781 {
6747 if (argvars[0].vval.v_dict != NULL) 6782 int todo;
6748 { 6783 dictvar *d;
6749 dictitem *di; 6784 hashitem *hi;
6750 6785
6751 di = argvars[0].vval.v_dict->dv_first; 6786 if ((d = argvars[0].vval.v_dict) != NULL)
6787 {
6752 if (argvars[2].v_type != VAR_UNKNOWN) 6788 if (argvars[2].v_type != VAR_UNKNOWN)
6753 { 6789 {
6754 ic = get_tv_number(&argvars[2]); 6790 ic = get_tv_number(&argvars[2]);
6755 if (argvars[3].v_type != VAR_UNKNOWN) 6791 if (argvars[3].v_type != VAR_UNKNOWN)
6756 EMSG(_(e_invarg)); 6792 EMSG(_(e_invarg));
6757 } 6793 }
6758 6794
6759 for ( ; di != NULL; di = di->di_next) 6795 todo = d->dv_hashtable.ht_used;
6760 if (tv_equal(&di->di_tv, &argvars[1], ic)) 6796 for (hi = d->dv_hashtable.ht_array; todo > 0; ++hi)
6761 ++n; 6797 {
6798 if (!HASHITEM_EMPTY(hi))
6799 {
6800 --todo;
6801 if (tv_equal(&HI2DI(hi)->di_tv, &argvars[1], ic))
6802 ++n;
6803 }
6804 }
6762 } 6805 }
6763 } 6806 }
6764 else 6807 else
6765 EMSG2(_(e_listdictarg), "count()"); 6808 EMSG2(_(e_listdictarg), "count()");
6766 rettv->vval.v_number = n; 6809 rettv->vval.v_number = n;
6970 n = argvars[0].vval.v_list == NULL 7013 n = argvars[0].vval.v_list == NULL
6971 || argvars[0].vval.v_list->lv_first == NULL; 7014 || argvars[0].vval.v_list->lv_first == NULL;
6972 break; 7015 break;
6973 case VAR_DICT: 7016 case VAR_DICT:
6974 n = argvars[0].vval.v_dict == NULL 7017 n = argvars[0].vval.v_dict == NULL
6975 || argvars[0].vval.v_dict->dv_first == NULL; 7018 || argvars[0].vval.v_dict->dv_hashtable.ht_used == 0;
6976 break; 7019 break;
6977 default: 7020 default:
6978 EMSG2(_(e_intern2), "f_empty()"); 7021 EMSG2(_(e_intern2), "f_empty()");
6979 n = 0; 7022 n = 0;
6980 } 7023 }
7195 } 7238 }
7196 } 7239 }
7197 else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT) 7240 else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT)
7198 { 7241 {
7199 dictvar *d1, *d2; 7242 dictvar *d1, *d2;
7200 dictitem *d1i, *d2i; 7243 dictitem *di1;
7201 char_u *action; 7244 char_u *action;
7202 int i; 7245 int i;
7246 hashitem *hi2;
7247 int todo;
7203 7248
7204 d1 = argvars[0].vval.v_dict; 7249 d1 = argvars[0].vval.v_dict;
7205 d2 = argvars[1].vval.v_dict; 7250 d2 = argvars[1].vval.v_dict;
7206 if (d1 != NULL && d2 != NULL) 7251 if (d1 != NULL && d2 != NULL)
7207 { 7252 {
7223 else 7268 else
7224 action = (char_u *)"force"; 7269 action = (char_u *)"force";
7225 7270
7226 /* Go over all entries in the second dict and add them to the 7271 /* Go over all entries in the second dict and add them to the
7227 * first dict. */ 7272 * first dict. */
7228 for (d2i = d2->dv_first; d2i != NULL; d2i = d2i->di_next) 7273 todo = d2->dv_hashtable.ht_used;
7274 for (hi2 = d2->dv_hashtable.ht_array; todo > 0; ++hi2)
7229 { 7275 {
7230 d1i = dict_find(d1, d2i->di_key, -1, NULL); 7276 if (!HASHITEM_EMPTY(hi2))
7231 if (d1i == NULL)
7232 { 7277 {
7233 d1i = dictitem_copy(d2i); 7278 --todo;
7234 if (d1i != NULL) 7279 di1 = dict_find(d1, hi2->hi_key, -1);
7235 dict_add(d1, d1i); 7280 if (di1 == NULL)
7236 } 7281 {
7237 else if (*action == 'e') 7282 di1 = dictitem_copy(HI2DI(hi2));
7238 { 7283 if (di1 != NULL && dict_add(d1, di1) == FAIL)
7239 EMSG2(_("Key already exists: %s"), d2i->di_key); 7284 dictitem_free(di1);
7240 break; 7285 }
7241 } 7286 else if (*action == 'e')
7242 else if (*action == 'f') 7287 {
7243 { 7288 EMSG2(_("E737: Key already exists: %s"), hi2->hi_key);
7244 clear_tv(&d1i->di_tv); 7289 break;
7245 copy_tv(&d2i->di_tv, &d1i->di_tv); 7290 }
7291 else if (*action == 'f')
7292 {
7293 clear_tv(&di1->di_tv);
7294 copy_tv(&HI2DI(hi2)->di_tv, &di1->di_tv);
7295 }
7246 } 7296 }
7247 } 7297 }
7248 7298
7249 ++d1->dv_refcount; 7299 ++d1->dv_refcount;
7250 copy_tv(&argvars[0], rettv); 7300 copy_tv(&argvars[0], rettv);
7376 { 7426 {
7377 char_u buf[NUMBUFLEN]; 7427 char_u buf[NUMBUFLEN];
7378 char_u *expr; 7428 char_u *expr;
7379 listitem *li, *nli; 7429 listitem *li, *nli;
7380 listvar *l = NULL; 7430 listvar *l = NULL;
7381 dictitem *di, **pdi; 7431 dictitem *di;
7432 hashitem *hi;
7382 dictvar *d = NULL; 7433 dictvar *d = NULL;
7383 typeval save_val; 7434 typeval save_val;
7384 typeval save_key; 7435 typeval save_key;
7385 int rem; 7436 int rem;
7437 int todo;
7386 7438
7387 rettv->vval.v_number = 0; 7439 rettv->vval.v_number = 0;
7388 if (argvars[0].v_type == VAR_LIST) 7440 if (argvars[0].v_type == VAR_LIST)
7389 { 7441 {
7390 if ((l = argvars[0].vval.v_list) == NULL) 7442 if ((l = argvars[0].vval.v_list) == NULL)
7406 7458
7407 if (argvars[0].v_type == VAR_DICT) 7459 if (argvars[0].v_type == VAR_DICT)
7408 { 7460 {
7409 save_key = vimvars[VV_KEY].tv; 7461 save_key = vimvars[VV_KEY].tv;
7410 vimvars[VV_KEY].tv.v_type = VAR_STRING; 7462 vimvars[VV_KEY].tv.v_type = VAR_STRING;
7411 pdi = &d->dv_first; 7463
7412 for (di = d->dv_first; di != NULL; di = *pdi) 7464 todo = d->dv_hashtable.ht_used;
7413 { 7465 for (hi = d->dv_hashtable.ht_array; todo > 0; ++hi)
7414 vimvars[VV_KEY].tv.vval.v_string = vim_strsave(di->di_key); 7466 {
7415 if (filter_map_one(&di->di_tv, expr, map, &rem) == FAIL) 7467 if (!HASHITEM_EMPTY(hi))
7416 break;
7417 if (!map && rem)
7418 { 7468 {
7419 *pdi = di->di_next; 7469 --todo;
7420 dictitem_free(di); 7470 di = HI2DI(hi);
7471 vimvars[VV_KEY].tv.vval.v_string = vim_strsave(di->di_key);
7472 if (filter_map_one(&di->di_tv, expr, map, &rem) == FAIL)
7473 break;
7474 if (!map && rem)
7475 dictitem_remove(d, di);
7476 clear_tv(&vimvars[VV_KEY].tv);
7421 } 7477 }
7422 else 7478 }
7423 pdi = &di->di_next; 7479
7424 clear_tv(&vimvars[VV_KEY].tv);
7425 }
7426 clear_tv(&vimvars[VV_KEY].tv); 7480 clear_tv(&vimvars[VV_KEY].tv);
7427 vimvars[VV_KEY].tv = save_key; 7481 vimvars[VV_KEY].tv = save_key;
7428 } 7482 }
7429 else 7483 else
7430 { 7484 {
7782 } 7836 }
7783 else if (argvars[0].v_type == VAR_DICT) 7837 else if (argvars[0].v_type == VAR_DICT)
7784 { 7838 {
7785 if ((d = argvars[0].vval.v_dict) != NULL) 7839 if ((d = argvars[0].vval.v_dict) != NULL)
7786 { 7840 {
7787 di = dict_find(d, get_tv_string(&argvars[1]), -1, NULL); 7841 di = dict_find(d, get_tv_string(&argvars[1]), -1);
7788 if (di != NULL) 7842 if (di != NULL)
7789 tv = &di->di_tv; 7843 tv = &di->di_tv;
7790 } 7844 }
7791 } 7845 }
7792 else 7846 else
8915 } 8969 }
8916 if (argvars[0].vval.v_dict == NULL) 8970 if (argvars[0].vval.v_dict == NULL)
8917 return; 8971 return;
8918 8972
8919 rettv->vval.v_number = dict_find(argvars[0].vval.v_dict, 8973 rettv->vval.v_number = dict_find(argvars[0].vval.v_dict,
8920 get_tv_string(&argvars[1]), -1, NULL) != NULL; 8974 get_tv_string(&argvars[1]), -1) != NULL;
8921 } 8975 }
8922 8976
8923 /* 8977 /*
8924 * "hasmapto()" function 8978 * "hasmapto()" function
8925 */ 8979 */
9410 int what; 9464 int what;
9411 { 9465 {
9412 listvar *l; 9466 listvar *l;
9413 listvar *l2; 9467 listvar *l2;
9414 dictitem *di; 9468 dictitem *di;
9469 hashitem *hi;
9415 listitem *li; 9470 listitem *li;
9416 listitem *li2; 9471 listitem *li2;
9472 dictvar *d;
9473 int todo;
9417 9474
9418 rettv->vval.v_number = 0; 9475 rettv->vval.v_number = 0;
9419 if (argvars[0].v_type != VAR_DICT) 9476 if (argvars[0].v_type != VAR_DICT)
9420 { 9477 {
9421 EMSG(_(e_dictreq)); 9478 EMSG(_(e_dictreq));
9422 return; 9479 return;
9423 } 9480 }
9424 if (argvars[0].vval.v_dict == NULL) 9481 if ((d = argvars[0].vval.v_dict) == NULL)
9425 return; 9482 return;
9426 9483
9427 l = list_alloc(); 9484 l = list_alloc();
9428 if (l == NULL) 9485 if (l == NULL)
9429 return; 9486 return;
9430 rettv->v_type = VAR_LIST; 9487 rettv->v_type = VAR_LIST;
9431 rettv->vval.v_list = l; 9488 rettv->vval.v_list = l;
9432 ++l->lv_refcount; 9489 ++l->lv_refcount;
9433 9490
9434 for (di = argvars[0].vval.v_dict->dv_first; di != NULL; di = di->di_next) 9491 todo = d->dv_hashtable.ht_used;
9435 { 9492 for (hi = d->dv_hashtable.ht_array; todo > 0; ++hi)
9436 li = listitem_alloc(); 9493 {
9437 if (li == NULL) 9494 if (!HASHITEM_EMPTY(hi))
9438 break; 9495 {
9439 list_append(l, li); 9496 --todo;
9440 9497 di = HI2DI(hi);
9441 if (what == 0) 9498
9442 { 9499 li = listitem_alloc();
9443 /* keys() */ 9500 if (li == NULL)
9444 li->li_tv.v_type = VAR_STRING;
9445 li->li_tv.vval.v_string = vim_strsave(di->di_key);
9446 }
9447 else if (what == 1)
9448 {
9449 /* values() */
9450 copy_tv(&di->di_tv, &li->li_tv);
9451 }
9452 else
9453 {
9454 /* items() */
9455 l2 = list_alloc();
9456 li->li_tv.v_type = VAR_LIST;
9457 li->li_tv.vval.v_list = l2;
9458 if (l2 == NULL)
9459 break; 9501 break;
9460 ++l2->lv_refcount; 9502 list_append(l, li);
9461 9503
9462 li2 = listitem_alloc(); 9504 if (what == 0)
9463 if (li2 == NULL) 9505 {
9464 break; 9506 /* keys() */
9465 list_append(l2, li2); 9507 li->li_tv.v_type = VAR_STRING;
9466 li2->li_tv.v_type = VAR_STRING; 9508 li->li_tv.vval.v_string = vim_strsave(di->di_key);
9467 li2->li_tv.vval.v_string = vim_strsave(di->di_key); 9509 }
9468 9510 else if (what == 1)
9469 li2 = listitem_alloc(); 9511 {
9470 if (li2 == NULL) 9512 /* values() */
9471 break; 9513 copy_tv(&di->di_tv, &li->li_tv);
9472 list_append(l2, li2); 9514 }
9473 copy_tv(&di->di_tv, &li2->li_tv); 9515 else
9516 {
9517 /* items() */
9518 l2 = list_alloc();
9519 li->li_tv.v_type = VAR_LIST;
9520 li->li_tv.vval.v_list = l2;
9521 if (l2 == NULL)
9522 break;
9523 ++l2->lv_refcount;
9524
9525 li2 = listitem_alloc();
9526 if (li2 == NULL)
9527 break;
9528 list_append(l2, li2);
9529 li2->li_tv.v_type = VAR_STRING;
9530 li2->li_tv.vval.v_string = vim_strsave(di->di_key);
9531
9532 li2 = listitem_alloc();
9533 if (li2 == NULL)
9534 break;
9535 list_append(l2, li2);
9536 copy_tv(&di->di_tv, &li2->li_tv);
9537 }
9474 } 9538 }
9475 } 9539 }
9476 } 9540 }
9477 9541
9478 /* 9542 /*
10021 } 10085 }
10022 } 10086 }
10023 else if (argvars[0].v_type == VAR_DICT) 10087 else if (argvars[0].v_type == VAR_DICT)
10024 { 10088 {
10025 dictvar *d; 10089 dictvar *d;
10026 dictitem *di; 10090 int first = TRUE;
10091 hashitem *hi;
10092 int todo;
10027 10093
10028 d = argvars[0].vval.v_dict; 10094 d = argvars[0].vval.v_dict;
10029 if (d != NULL) 10095 if (d != NULL)
10030 { 10096 {
10031 di = d->dv_first; 10097 todo = d->dv_hashtable.ht_used;
10032 if (di != NULL) 10098 for (hi = d->dv_hashtable.ht_array; todo > 0; ++hi)
10033 { 10099 {
10034 n = get_tv_number(&di->di_tv); 10100 if (!HASHITEM_EMPTY(hi))
10035 while (1)
10036 { 10101 {
10037 di = di->di_next; 10102 --todo;
10038 if (di == NULL) 10103 i = get_tv_number(&HI2DI(hi)->di_tv);
10039 break; 10104 if (first)
10040 i = get_tv_number(&di->di_tv); 10105 {
10041 if (domax ? i > n : i < n) 10106 n = i;
10107 first = FALSE;
10108 }
10109 else if (domax ? i > n : i < n)
10042 n = i; 10110 n = i;
10043 } 10111 }
10044 } 10112 }
10045 } 10113 }
10046 } 10114 }
10470 listitem *li; 10538 listitem *li;
10471 long idx; 10539 long idx;
10472 long end; 10540 long end;
10473 char_u *key; 10541 char_u *key;
10474 dictvar *d; 10542 dictvar *d;
10475 dictitem *di, **pdi; 10543 dictitem *di;
10476 10544
10477 rettv->vval.v_number = 0; 10545 rettv->vval.v_number = 0;
10478 if (argvars[0].v_type == VAR_DICT) 10546 if (argvars[0].v_type == VAR_DICT)
10479 { 10547 {
10480 if (argvars[2].v_type != VAR_UNKNOWN) 10548 if (argvars[2].v_type != VAR_UNKNOWN)
10481 EMSG2(_(e_toomanyarg), "remove()"); 10549 EMSG2(_(e_toomanyarg), "remove()");
10482 else if ((d = argvars[0].vval.v_dict) != NULL) 10550 else if ((d = argvars[0].vval.v_dict) != NULL)
10483 { 10551 {
10484 key = get_tv_string(&argvars[1]); 10552 key = get_tv_string(&argvars[1]);
10485 pdi = &d->dv_first; 10553 di = dict_find(d, key, -1);
10486 for (di = d->dv_first; di != NULL; pdi = &di->di_next, di = *pdi)
10487 if (STRCMP(di->di_key, key) == 0)
10488 {
10489 *pdi = di->di_next;
10490 *rettv = di->di_tv;
10491 init_tv(&di->di_tv);
10492 dictitem_free(di);
10493 break;
10494 }
10495 if (di == NULL) 10554 if (di == NULL)
10496 EMSG2(_(e_dictkey), key); 10555 EMSG2(_(e_dictkey), key);
10556 else
10557 {
10558 *rettv = di->di_tv;
10559 init_tv(&di->di_tv);
10560 dictitem_remove(d, di);
10561 }
10497 } 10562 }
10498 } 10563 }
10499 else if (argvars[0].v_type != VAR_LIST) 10564 else if (argvars[0].v_type != VAR_LIST)
10500 EMSG2(_(e_listdictarg), "remove()"); 10565 EMSG2(_(e_listdictarg), "remove()");
10501 else if ((l = argvars[0].vval.v_list) != NULL) 10566 else if ((l = argvars[0].vval.v_list) != NULL)
13132 vim_free(varp->vval.v_string); 13197 vim_free(varp->vval.v_string);
13133 varp->vval.v_string = NULL; 13198 varp->vval.v_string = NULL;
13134 break; 13199 break;
13135 case VAR_LIST: 13200 case VAR_LIST:
13136 list_unref(varp->vval.v_list); 13201 list_unref(varp->vval.v_list);
13202 varp->vval.v_list = NULL;
13137 break; 13203 break;
13138 case VAR_DICT: 13204 case VAR_DICT:
13139 dict_unref(varp->vval.v_dict); 13205 dict_unref(varp->vval.v_dict);
13206 varp->vval.v_dict = NULL;
13140 break; 13207 break;
13141 case VAR_NUMBER: 13208 case VAR_NUMBER:
13142 varp->vval.v_number = 0; 13209 varp->vval.v_number = 0;
13143 break; 13210 break;
13144 case VAR_UNKNOWN: 13211 case VAR_UNKNOWN:
14001 * evaluation has been cancelled due to an aborting error, an 14068 * evaluation has been cancelled due to an aborting error, an
14002 * interrupt, or an exception. 14069 * interrupt, or an exception.
14003 */ 14070 */
14004 if (!aborting()) 14071 if (!aborting())
14005 { 14072 {
14073 if (!eap->skip && fudi.fd_newkey != NULL)
14074 EMSG2(_(e_dictkey), fudi.fd_newkey);
14006 vim_free(fudi.fd_newkey); 14075 vim_free(fudi.fd_newkey);
14007 return; 14076 return;
14008 } 14077 }
14009 else 14078 else
14010 eap->skip = TRUE; 14079 eap->skip = TRUE;
14346 if (fudi.fd_dict != NULL) 14415 if (fudi.fd_dict != NULL)
14347 { 14416 {
14348 if (fudi.fd_di == NULL) 14417 if (fudi.fd_di == NULL)
14349 { 14418 {
14350 /* add new dict entry */ 14419 /* add new dict entry */
14351 fudi.fd_di = dictitem_alloc(); 14420 fudi.fd_di = dictitem_alloc(fudi.fd_newkey);
14352 if (fudi.fd_di == NULL) 14421 if (fudi.fd_di == NULL)
14353 { 14422 {
14354 vim_free(fp); 14423 vim_free(fp);
14355 goto erret; 14424 goto erret;
14356 } 14425 }
14357 fudi.fd_di->di_key = fudi.fd_newkey; 14426 if (dict_add(fudi.fd_dict, fudi.fd_di) == FAIL)
14358 fudi.fd_newkey = NULL; 14427 {
14359 dict_add(fudi.fd_dict, fudi.fd_di); 14428 vim_free(fudi.fd_di);
14429 goto erret;
14430 }
14360 } 14431 }
14361 else 14432 else
14362 /* overwrite existing dict entry */ 14433 /* overwrite existing dict entry */
14363 clear_tv(&fudi.fd_di->di_tv); 14434 clear_tv(&fudi.fd_di->di_tv);
14364 fudi.fd_di->di_tv.v_type = VAR_FUNC; 14435 fudi.fd_di->di_tv.v_type = VAR_FUNC;
14452 { 14523 {
14453 fdp->fd_dict = lv.ll_dict; 14524 fdp->fd_dict = lv.ll_dict;
14454 fdp->fd_newkey = lv.ll_newkey; 14525 fdp->fd_newkey = lv.ll_newkey;
14455 lv.ll_newkey = NULL; 14526 lv.ll_newkey = NULL;
14456 fdp->fd_di = lv.ll_di; 14527 fdp->fd_di = lv.ll_di;
14457 fdp->fd_pdi = lv.ll_pdi;
14458 } 14528 }
14459 if (lv.ll_tv->v_type == VAR_FUNC && lv.ll_tv->vval.v_string != NULL) 14529 if (lv.ll_tv->v_type == VAR_FUNC && lv.ll_tv->vval.v_string != NULL)
14460 { 14530 {
14461 name = vim_strsave(lv.ll_tv->vval.v_string); 14531 name = vim_strsave(lv.ll_tv->vval.v_string);
14462 *pp = end; 14532 *pp = end;
14463 } 14533 }
14464 else 14534 else
14465 { 14535 {
14466 if (!skip && !(flags & TFN_QUIET) 14536 if (!skip && !(flags & TFN_QUIET) && (fdp == NULL
14467 && (fdp == NULL || lv.ll_dict == NULL)) 14537 || lv.ll_dict == NULL || fdp->fd_newkey == NULL))
14468 EMSG(_(e_funcref)); 14538 EMSG(_(e_funcref));
14469 else 14539 else
14470 *pp = end; 14540 *pp = end;
14471 name = NULL; 14541 name = NULL;
14472 } 14542 }
14741 14811
14742 if (fudi.fd_dict != NULL) 14812 if (fudi.fd_dict != NULL)
14743 { 14813 {
14744 /* Delete the dict item that refers to the function, it will 14814 /* Delete the dict item that refers to the function, it will
14745 * invoke func_unref() and possibly delete the function. */ 14815 * invoke func_unref() and possibly delete the function. */
14746 *fudi.fd_pdi = fudi.fd_di->di_next; 14816 dictitem_remove(fudi.fd_dict, fudi.fd_di);
14747 dictitem_free(fudi.fd_di);
14748 } 14817 }
14749 else 14818 else
14750 func_free(fp); 14819 func_free(fp);
14751 } 14820 }
14752 } 14821 }