comparison src/eval.c @ 156:c5b05f6de1ad v7.0047

updated for version 7.0047
author vimboss
date Wed, 02 Feb 2005 23:11:38 +0000
parents 40a0699b6c62
children 389c8abd5925
comparison
equal deleted inserted replaced
155:e91a302ad53a 156:c5b05f6de1ad
328 static int dict_equal __ARGS((dict_T *d1, dict_T *d2, int ic)); 328 static int dict_equal __ARGS((dict_T *d1, dict_T *d2, int ic));
329 static int tv_equal __ARGS((typval_T *tv1, typval_T *tv2, int ic)); 329 static int tv_equal __ARGS((typval_T *tv1, typval_T *tv2, int ic));
330 static int string_isa_number __ARGS((char_u *s)); 330 static int string_isa_number __ARGS((char_u *s));
331 static listitem_T *list_find __ARGS((list_T *l, long n)); 331 static listitem_T *list_find __ARGS((list_T *l, long n));
332 static long list_idx_of_item __ARGS((list_T *l, listitem_T *item)); 332 static long list_idx_of_item __ARGS((list_T *l, listitem_T *item));
333 static listitem_T *list_find_ext __ARGS((list_T *l, long *ip));
334 static void list_append __ARGS((list_T *l, listitem_T *item)); 333 static void list_append __ARGS((list_T *l, listitem_T *item));
335 static int list_append_tv __ARGS((list_T *l, typval_T *tv)); 334 static int list_append_tv __ARGS((list_T *l, typval_T *tv));
336 static int list_insert_tv __ARGS((list_T *l, typval_T *tv, listitem_T *item)); 335 static int list_insert_tv __ARGS((list_T *l, typval_T *tv, listitem_T *item));
337 static int list_extend __ARGS((list_T *l1, list_T *l2, listitem_T *bef)); 336 static int list_extend __ARGS((list_T *l1, list_T *l2, listitem_T *bef));
338 static int list_concat __ARGS((list_T *l1, list_T *l2, typval_T *tv)); 337 static int list_concat __ARGS((list_T *l1, list_T *l2, typval_T *tv));
1056 else 1055 else
1057 { 1056 {
1058 /* If the result is a number, just return the number. */ 1057 /* If the result is a number, just return the number. */
1059 if (tv.v_type == VAR_NUMBER) 1058 if (tv.v_type == VAR_NUMBER)
1060 retval = tv.vval.v_number; 1059 retval = tv.vval.v_number;
1061 else if (tv.v_type == VAR_UNKNOWN 1060 else if (tv.v_type != VAR_STRING || tv.vval.v_string == NULL)
1062 || tv.vval.v_string == NULL)
1063 retval = 0; 1061 retval = 0;
1064 else 1062 else
1065 { 1063 {
1066 /* If the result is a string, check if there is a non-digit before 1064 /* If the result is a string, check if there is a non-digit before
1067 * the number. */ 1065 * the number. */
1255 } 1253 }
1256 1254
1257 /* 1255 /*
1258 * ":let [v1, v2] = list" or ":for [v1, v2] in listlist" 1256 * ":let [v1, v2] = list" or ":for [v1, v2] in listlist"
1259 */ 1257 */
1260 l = tv->vval.v_list; 1258 if (tv->v_type != VAR_LIST || (l = tv->vval.v_list) == NULL)
1261 if (tv->v_type != VAR_LIST || l == NULL)
1262 { 1259 {
1263 EMSG(_(e_listreq)); 1260 EMSG(_(e_listreq));
1264 return FAIL; 1261 return FAIL;
1265 } 1262 }
1266 1263
2209 if (copy) 2206 if (copy)
2210 copy_tv(rettv, lp->ll_tv); 2207 copy_tv(rettv, lp->ll_tv);
2211 else 2208 else
2212 { 2209 {
2213 *lp->ll_tv = *rettv; 2210 *lp->ll_tv = *rettv;
2211 lp->ll_tv->v_lock = 0;
2214 init_tv(rettv); 2212 init_tv(rettv);
2215 } 2213 }
2216 } 2214 }
2217 } 2215 }
2218 2216
2291 lw->lw_next = l->lv_watch; 2289 lw->lw_next = l->lv_watch;
2292 l->lv_watch = lw; 2290 l->lv_watch = lw;
2293 } 2291 }
2294 2292
2295 /* 2293 /*
2296 * Remove a watches from a list. 2294 * Remove a watcher from a list.
2297 * No warning when it isn't found... 2295 * No warning when it isn't found...
2298 */ 2296 */
2299 static void 2297 static void
2300 list_rem_watch(l, lwrem) 2298 list_rem_watch(l, lwrem)
2301 list_T *l; 2299 list_T *l;
4732 */ 4730 */
4733 static long 4731 static long
4734 list_len(l) 4732 list_len(l)
4735 list_T *l; 4733 list_T *l;
4736 { 4734 {
4737 listitem_T *item;
4738 long len = 0;
4739
4740 if (l == NULL) 4735 if (l == NULL)
4741 return 0L; 4736 return 0L;
4742 for (item = l->lv_first; item != NULL; item = item->li_next) 4737 return l->lv_len;
4743 ++len;
4744 return len;
4745 } 4738 }
4746 4739
4747 /* 4740 /*
4748 * Return TRUE when two lists have exactly the same values. 4741 * Return TRUE when two lists have exactly the same values.
4749 */ 4742 */
4879 listitem_T *item; 4872 listitem_T *item;
4880 long idx; 4873 long idx;
4881 4874
4882 if (l == NULL) 4875 if (l == NULL)
4883 return NULL; 4876 return NULL;
4877
4878 /* Negative index is relative to the end. */
4884 if (n < 0) 4879 if (n < 0)
4885 { 4880 n = l->lv_len + n;
4886 idx = -1; /* search from the end */ 4881
4887 for (item = l->lv_last; item != NULL && idx > n; item = item->li_prev) 4882 /* Check for index out of range. */
4888 --idx; 4883 if (n < 0 || n >= l->lv_len)
4884 return NULL;
4885
4886 /* When there is a cached index may start search from there. */
4887 if (l->lv_idx_item != NULL)
4888 {
4889 if (n < l->lv_idx / 2)
4890 {
4891 /* closest to the start of the list */
4892 item = l->lv_first;
4893 idx = 0;
4894 }
4895 else if (n > (l->lv_idx + l->lv_len) / 2)
4896 {
4897 /* closest to the end of the list */
4898 item = l->lv_last;
4899 idx = l->lv_len - 1;
4900 }
4901 else
4902 {
4903 /* closest to the cached index */
4904 item = l->lv_idx_item;
4905 idx = l->lv_idx;
4906 }
4889 } 4907 }
4890 else 4908 else
4891 { 4909 {
4892 idx = 0; /* search from the start */ 4910 if (n < l->lv_len / 2)
4893 for (item = l->lv_first; item != NULL && idx < n; item = item->li_next) 4911 {
4894 ++idx; 4912 /* closest to the start of the list */
4895 } 4913 item = l->lv_first;
4896 if (idx != n) 4914 idx = 0;
4897 return NULL; 4915 }
4916 else
4917 {
4918 /* closest to the end of the list */
4919 item = l->lv_last;
4920 idx = l->lv_len - 1;
4921 }
4922 }
4923
4924 while (n > idx)
4925 {
4926 /* search forward */
4927 item = item->li_next;
4928 ++idx;
4929 }
4930 while (n < idx)
4931 {
4932 /* search backward */
4933 item = item->li_prev;
4934 --idx;
4935 }
4936
4937 /* cache the used index */
4938 l->lv_idx = idx;
4939 l->lv_idx_item = item;
4940
4898 return item; 4941 return item;
4899 } 4942 }
4900 4943
4901 /* 4944 /*
4902 * Locate "item" list "l" and return its index. 4945 * Locate "item" list "l" and return its index.
4919 return -1; 4962 return -1;
4920 return idx;; 4963 return idx;;
4921 } 4964 }
4922 4965
4923 /* 4966 /*
4924 * Like list_find(), but also find an item just past the end.
4925 * "*ip" is the item to find.
4926 * When found "*ip" is set to zero, when not found "*ip" is non-zero.
4927 * Returns NULL when item not found or item is just past the end.
4928 */
4929 static listitem_T *
4930 list_find_ext(l, ip)
4931 list_T *l;
4932 long *ip;
4933 {
4934 long n;
4935 listitem_T *item;
4936
4937 if (*ip < 0)
4938 {
4939 /* Count from the end: -1 is before last item. */
4940 item = l->lv_last;
4941 for (n = *ip + 1; n < 0 && item != NULL; ++n)
4942 item = item->li_prev;
4943 if (item == NULL)
4944 n = 1; /* error! */
4945 }
4946 else
4947 {
4948 item = l->lv_first;
4949 for (n = *ip; n > 0 && item != NULL; --n)
4950 item = item->li_next;
4951 }
4952 *ip = n;
4953 return item;
4954 }
4955
4956 /*
4957 * Append item "item" to the end of list "l". 4967 * Append item "item" to the end of list "l".
4958 */ 4968 */
4959 static void 4969 static void
4960 list_append(l, item) 4970 list_append(l, item)
4961 list_T *l; 4971 list_T *l;
4972 { 4982 {
4973 l->lv_last->li_next = item; 4983 l->lv_last->li_next = item;
4974 item->li_prev = l->lv_last; 4984 item->li_prev = l->lv_last;
4975 l->lv_last = item; 4985 l->lv_last = item;
4976 } 4986 }
4987 ++l->lv_len;
4977 item->li_next = NULL; 4988 item->li_next = NULL;
4978 } 4989 }
4979 4990
4980 /* 4991 /*
4981 * Append typval_T "tv" to the end of list "l". 4992 * Append typval_T "tv" to the end of list "l".
5018 { 5029 {
5019 /* Insert new item before existing item. */ 5030 /* Insert new item before existing item. */
5020 ni->li_prev = item->li_prev; 5031 ni->li_prev = item->li_prev;
5021 ni->li_next = item; 5032 ni->li_next = item;
5022 if (item->li_prev == NULL) 5033 if (item->li_prev == NULL)
5034 {
5023 l->lv_first = ni; 5035 l->lv_first = ni;
5036 ++l->lv_idx;
5037 }
5024 else 5038 else
5039 {
5025 item->li_prev->li_next = ni; 5040 item->li_prev->li_next = ni;
5041 l->lv_idx_item = NULL;
5042 }
5026 item->li_prev = ni; 5043 item->li_prev = ni;
5044 ++l->lv_len;
5027 } 5045 }
5028 return OK; 5046 return OK;
5029 } 5047 }
5030 5048
5031 /* 5049 /*
5120 listitem_T *ip; 5138 listitem_T *ip;
5121 5139
5122 /* notify watchers */ 5140 /* notify watchers */
5123 for (ip = item; ip != NULL; ip = ip->li_next) 5141 for (ip = item; ip != NULL; ip = ip->li_next)
5124 { 5142 {
5143 --l->lv_len;
5125 list_fix_watch(l, ip); 5144 list_fix_watch(l, ip);
5126 if (ip == item2) 5145 if (ip == item2)
5127 break; 5146 break;
5128 } 5147 }
5129 5148
5133 item2->li_next->li_prev = item->li_prev; 5152 item2->li_next->li_prev = item->li_prev;
5134 if (item->li_prev == NULL) 5153 if (item->li_prev == NULL)
5135 l->lv_first = item2->li_next; 5154 l->lv_first = item2->li_next;
5136 else 5155 else
5137 item->li_prev->li_next = item2->li_next; 5156 item->li_prev->li_next = item2->li_next;
5157 l->lv_idx_item = NULL;
5138 } 5158 }
5139 5159
5140 /* 5160 /*
5141 * Return an allocated string with the string representation of a list. 5161 * Return an allocated string with the string representation of a list.
5142 * May return NULL. 5162 * May return NULL.
6545 { 6565 {
6546 buf_T *buf = NULL; 6566 buf_T *buf = NULL;
6547 6567
6548 if (avar->v_type == VAR_NUMBER) 6568 if (avar->v_type == VAR_NUMBER)
6549 buf = buflist_findnr((int)avar->vval.v_number); 6569 buf = buflist_findnr((int)avar->vval.v_number);
6550 else if (avar->vval.v_string != NULL) 6570 else if (avar->v_type == VAR_STRING && avar->vval.v_string != NULL)
6551 { 6571 {
6552 buf = buflist_findname_exp(avar->vval.v_string); 6572 buf = buflist_findname_exp(avar->vval.v_string);
6553 if (buf == NULL) 6573 if (buf == NULL)
6554 { 6574 {
6555 /* No full path name match, try a match with a URL or a "nofile" 6575 /* No full path name match, try a match with a URL or a "nofile"
6621 char_u *save_cpo; 6641 char_u *save_cpo;
6622 buf_T *buf; 6642 buf_T *buf;
6623 6643
6624 if (tv->v_type == VAR_NUMBER) 6644 if (tv->v_type == VAR_NUMBER)
6625 return buflist_findnr((int)tv->vval.v_number); 6645 return buflist_findnr((int)tv->vval.v_number);
6646 if (tv->v_type != VAR_STRING)
6647 return NULL;
6626 if (name == NULL || *name == NUL) 6648 if (name == NULL || *name == NUL)
6627 return curbuf; 6649 return curbuf;
6628 if (name[0] == '$' && name[1] == NUL) 6650 if (name[0] == '$' && name[1] == NUL)
6629 return lastbuf; 6651 return lastbuf;
6630 6652
7287 typval_T *argvars; 7309 typval_T *argvars;
7288 typval_T *rettv; 7310 typval_T *rettv;
7289 { 7311 {
7290 char_u buf[NUMBUFLEN]; 7312 char_u buf[NUMBUFLEN];
7291 7313
7292 rettv->vval.v_string = 7314 rettv->vval.v_string = vim_strsave_escaped(get_tv_string(&argvars[0]),
7293 vim_strsave_escaped(get_tv_string(&argvars[0]), 7315 get_tv_string_buf(&argvars[1], buf));
7294 get_tv_string_buf(&argvars[1], buf));
7295 rettv->v_type = VAR_STRING; 7316 rettv->v_type = VAR_STRING;
7296 } 7317 }
7297 7318
7298 /* 7319 /*
7299 * "eval()" function 7320 * "eval()" function
7465 if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST) 7486 if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST)
7466 { 7487 {
7467 list_T *l1, *l2; 7488 list_T *l1, *l2;
7468 listitem_T *item; 7489 listitem_T *item;
7469 long before; 7490 long before;
7470 long n;
7471 7491
7472 l1 = argvars[0].vval.v_list; 7492 l1 = argvars[0].vval.v_list;
7473 l2 = argvars[1].vval.v_list; 7493 l2 = argvars[1].vval.v_list;
7474 if (l1 != NULL && !tv_check_lock(l1->lv_lock, (char_u *)"extend()") 7494 if (l1 != NULL && !tv_check_lock(l1->lv_lock, (char_u *)"extend()")
7475 && l2 != NULL) 7495 && l2 != NULL)
7476 { 7496 {
7477 if (argvars[2].v_type != VAR_UNKNOWN) 7497 if (argvars[2].v_type != VAR_UNKNOWN)
7478 { 7498 {
7479 n = before = get_tv_number(&argvars[2]); 7499 before = get_tv_number(&argvars[2]);
7480 item = list_find_ext(l1, &n); 7500 if (before == l1->lv_len)
7481 if (n != 0) 7501 item = NULL;
7502 else
7482 { 7503 {
7483 EMSGN(_(e_listidx), before); 7504 item = list_find(l1, before);
7484 return; 7505 if (item == NULL)
7506 {
7507 EMSGN(_(e_listidx), before);
7508 return;
7509 }
7485 } 7510 }
7486 } 7511 }
7487 else 7512 else
7488 item = NULL; 7513 item = NULL;
7489 list_extend(l1, l2, item); 7514 list_extend(l1, l2, item);
9485 typval_T *rettv; 9510 typval_T *rettv;
9486 { 9511 {
9487 list_T *l; 9512 list_T *l;
9488 listitem_T *item; 9513 listitem_T *item;
9489 long idx = 0; 9514 long idx = 0;
9490 long min_idx = 0;
9491 int ic = FALSE; 9515 int ic = FALSE;
9492 9516
9493 rettv->vval.v_number = -1; 9517 rettv->vval.v_number = -1;
9494 if (argvars[0].v_type != VAR_LIST) 9518 if (argvars[0].v_type != VAR_LIST)
9495 { 9519 {
9497 return; 9521 return;
9498 } 9522 }
9499 l = argvars[0].vval.v_list; 9523 l = argvars[0].vval.v_list;
9500 if (l != NULL) 9524 if (l != NULL)
9501 { 9525 {
9526 item = l->lv_first;
9502 if (argvars[2].v_type != VAR_UNKNOWN) 9527 if (argvars[2].v_type != VAR_UNKNOWN)
9503 { 9528 {
9504 min_idx = get_tv_number(&argvars[2]); 9529 /* Start at specified item. Use the cached index that list_find()
9530 * sets, so that a negative number also works. */
9531 item = list_find(l, get_tv_number(&argvars[2]));
9532 idx = l->lv_idx;
9505 if (argvars[3].v_type != VAR_UNKNOWN) 9533 if (argvars[3].v_type != VAR_UNKNOWN)
9506 ic = get_tv_number(&argvars[3]); 9534 ic = get_tv_number(&argvars[3]);
9507 } 9535 }
9508 9536
9509 for (item = l->lv_first; item != NULL; item = item->li_next, ++idx) 9537 for ( ; item != NULL; item = item->li_next, ++idx)
9510 if (idx >= min_idx && tv_equal(&item->li_tv, &argvars[1], ic)) 9538 if (tv_equal(&item->li_tv, &argvars[1], ic))
9511 { 9539 {
9512 rettv->vval.v_number = idx; 9540 rettv->vval.v_number = idx;
9513 break; 9541 break;
9514 } 9542 }
9515 } 9543 }
9688 f_insert(argvars, rettv) 9716 f_insert(argvars, rettv)
9689 typval_T *argvars; 9717 typval_T *argvars;
9690 typval_T *rettv; 9718 typval_T *rettv;
9691 { 9719 {
9692 long before = 0; 9720 long before = 0;
9693 long n;
9694 listitem_T *item; 9721 listitem_T *item;
9695 list_T *l; 9722 list_T *l;
9696 9723
9697 rettv->vval.v_number = 0; 9724 rettv->vval.v_number = 0;
9698 if (argvars[0].v_type != VAR_LIST) 9725 if (argvars[0].v_type != VAR_LIST)
9701 && !tv_check_lock(l->lv_lock, (char_u *)"insert()")) 9728 && !tv_check_lock(l->lv_lock, (char_u *)"insert()"))
9702 { 9729 {
9703 if (argvars[2].v_type != VAR_UNKNOWN) 9730 if (argvars[2].v_type != VAR_UNKNOWN)
9704 before = get_tv_number(&argvars[2]); 9731 before = get_tv_number(&argvars[2]);
9705 9732
9706 n = before; 9733 if (before == l->lv_len)
9707 item = list_find_ext(l, &n); 9734 item = NULL;
9708 if (n > 0)
9709 EMSGN(_(e_listidx), before);
9710 else 9735 else
9736 {
9737 item = list_find(l, before);
9738 if (item == NULL)
9739 {
9740 EMSGN(_(e_listidx), before);
9741 l = NULL;
9742 }
9743 }
9744 if (l != NULL)
9711 { 9745 {
9712 list_insert_tv(l, &argvars[1], item); 9746 list_insert_tv(l, &argvars[1], item);
9713 ++l->lv_refcount; 9747 ++l->lv_refcount;
9714 copy_tv(&argvars[0], rettv); 9748 copy_tv(&argvars[0], rettv);
9715 } 9749 }
10019 10053
10020 #ifdef FEAT_LIBCALL 10054 #ifdef FEAT_LIBCALL
10021 /* The first two args must be strings, otherwise its meaningless */ 10055 /* The first two args must be strings, otherwise its meaningless */
10022 if (argvars[0].v_type == VAR_STRING && argvars[1].v_type == VAR_STRING) 10056 if (argvars[0].v_type == VAR_STRING && argvars[1].v_type == VAR_STRING)
10023 { 10057 {
10024 if (argvars[2].v_type == VAR_NUMBER) 10058 string_in = NULL;
10025 string_in = NULL; 10059 if (argvars[2].v_type == VAR_STRING)
10026 else
10027 string_in = argvars[2].vval.v_string; 10060 string_in = argvars[2].vval.v_string;
10028 if (type == VAR_NUMBER) 10061 if (type == VAR_NUMBER)
10029 string_result = NULL; 10062 string_result = NULL;
10030 else 10063 else
10031 string_result = &rettv->vval.v_string; 10064 string_result = &rettv->vval.v_string;
10273 if (l != NULL) 10306 if (l != NULL)
10274 { 10307 {
10275 li = list_find(l, start); 10308 li = list_find(l, start);
10276 if (li == NULL) 10309 if (li == NULL)
10277 goto theend; 10310 goto theend;
10278 if (start < 0) 10311 idx = l->lv_idx; /* use the cached index */
10279 {
10280 listitem_T *ni;
10281
10282 /* Need to compute the index. */
10283 for (ni = li; ni->li_prev != NULL; ni = ni->li_prev)
10284 ++idx;
10285 }
10286 else
10287 idx = start;
10288 } 10312 }
10289 else 10313 else
10290 { 10314 {
10291 if (start < 0) 10315 if (start < 0)
10292 start = 0; 10316 start = 0;
10466 } 10490 }
10467 } 10491 }
10468 } 10492 }
10469 } 10493 }
10470 else 10494 else
10471 EMSG(_(e_listreq)); 10495 EMSG(_(e_listdictarg));
10472 rettv->vval.v_number = n; 10496 rettv->vval.v_number = n;
10473 } 10497 }
10474 10498
10475 /* 10499 /*
10476 * "max()" function 10500 * "max()" function
10902 if (argvars[0].v_type == VAR_DICT) 10926 if (argvars[0].v_type == VAR_DICT)
10903 { 10927 {
10904 if (argvars[2].v_type != VAR_UNKNOWN) 10928 if (argvars[2].v_type != VAR_UNKNOWN)
10905 EMSG2(_(e_toomanyarg), "remove()"); 10929 EMSG2(_(e_toomanyarg), "remove()");
10906 else if ((d = argvars[0].vval.v_dict) != NULL 10930 else if ((d = argvars[0].vval.v_dict) != NULL
10907 && !tv_check_lock(d->dv_lock, (char_u *)"remove()")) 10931 && !tv_check_lock(d->dv_lock, (char_u *)"remove()"))
10908 { 10932 {
10909 key = get_tv_string(&argvars[1]); 10933 key = get_tv_string(&argvars[1]);
10910 di = dict_find(d, key, -1); 10934 di = dict_find(d, key, -1);
10911 if (di == NULL) 10935 if (di == NULL)
10912 EMSG2(_(e_dictkey), key); 10936 EMSG2(_(e_dictkey), key);
10943 item2 = list_find(l, end); 10967 item2 = list_find(l, end);
10944 if (item2 == NULL) 10968 if (item2 == NULL)
10945 EMSGN(_(e_listidx), end); 10969 EMSGN(_(e_listidx), end);
10946 else 10970 else
10947 { 10971 {
10948 for (li = item; li != item2 && li != NULL; li = li->li_next) 10972 int cnt = 0;
10949 ; 10973
10974 for (li = item; li != NULL; li = li->li_next)
10975 {
10976 ++cnt;
10977 if (li == item2)
10978 break;
10979 }
10950 if (li == NULL) /* didn't find "item2" after "item" */ 10980 if (li == NULL) /* didn't find "item2" after "item" */
10951 EMSG(_(e_invrange)); 10981 EMSG(_(e_invrange));
10952 else 10982 else
10953 { 10983 {
10954 list_remove(l, item, item2); 10984 list_remove(l, item, item2);
10960 l->lv_first = item; 10990 l->lv_first = item;
10961 l->lv_last = item2; 10991 l->lv_last = item2;
10962 l->lv_refcount = 1; 10992 l->lv_refcount = 1;
10963 item->li_prev = NULL; 10993 item->li_prev = NULL;
10964 item2->li_next = NULL; 10994 item2->li_next = NULL;
10995 l->lv_len = cnt;
10965 } 10996 }
10966 } 10997 }
10967 } 10998 }
10968 } 10999 }
10969 } 11000 }
11258 else if ((l = argvars[0].vval.v_list) != NULL 11289 else if ((l = argvars[0].vval.v_list) != NULL
11259 && !tv_check_lock(l->lv_lock, (char_u *)"reverse()")) 11290 && !tv_check_lock(l->lv_lock, (char_u *)"reverse()"))
11260 { 11291 {
11261 li = l->lv_last; 11292 li = l->lv_last;
11262 l->lv_first = l->lv_last = li; 11293 l->lv_first = l->lv_last = li;
11294 l->lv_len = 0;
11263 while (li != NULL) 11295 while (li != NULL)
11264 { 11296 {
11265 ni = li->li_prev; 11297 ni = li->li_prev;
11266 list_append(l, li); 11298 list_append(l, li);
11267 li = ni; 11299 li = ni;
11943 qsort((void *)ptrs, (size_t)len, sizeof(listitem_T *), 11975 qsort((void *)ptrs, (size_t)len, sizeof(listitem_T *),
11944 item_compare_func == NULL ? item_compare : item_compare2); 11976 item_compare_func == NULL ? item_compare : item_compare2);
11945 11977
11946 /* Clear the List and append the items in the sorted order. */ 11978 /* Clear the List and append the items in the sorted order. */
11947 l->lv_first = l->lv_last = NULL; 11979 l->lv_first = l->lv_last = NULL;
11980 l->lv_len = 0;
11948 for (i = 0; i < len; ++i) 11981 for (i = 0; i < len; ++i)
11949 list_append(l, ptrs[i]); 11982 list_append(l, ptrs[i]);
11950 } 11983 }
11951 11984
11952 vim_free(ptrs); 11985 vim_free(ptrs);
12771 { 12804 {
12772 case VAR_NUMBER: n = 0; break; 12805 case VAR_NUMBER: n = 0; break;
12773 case VAR_STRING: n = 1; break; 12806 case VAR_STRING: n = 1; break;
12774 case VAR_FUNC: n = 2; break; 12807 case VAR_FUNC: n = 2; break;
12775 case VAR_LIST: n = 3; break; 12808 case VAR_LIST: n = 3; break;
12809 case VAR_DICT: n = 4; break;
12776 default: EMSG2(_(e_intern2), "f_type()"); n = 0; break; 12810 default: EMSG2(_(e_intern2), "f_type()"); n = 0; break;
12777 } 12811 }
12778 rettv->vval.v_number = n; 12812 rettv->vval.v_number = n;
12779 } 12813 }
12780 12814
13518 list_unref(varp->vval.v_list); 13552 list_unref(varp->vval.v_list);
13519 break; 13553 break;
13520 case VAR_DICT: 13554 case VAR_DICT:
13521 dict_unref(varp->vval.v_dict); 13555 dict_unref(varp->vval.v_dict);
13522 break; 13556 break;
13557 case VAR_NUMBER:
13558 case VAR_UNKNOWN:
13559 break;
13523 default: 13560 default:
13561 EMSG2(_(e_intern2), "free_tv()");
13524 break; 13562 break;
13525 } 13563 }
13526 vim_free(varp); 13564 vim_free(varp);
13527 } 13565 }
13528 } 13566 }
13598 if (varp->vval.v_string != NULL) 13636 if (varp->vval.v_string != NULL)
13599 vim_str2nr(varp->vval.v_string, NULL, NULL, 13637 vim_str2nr(varp->vval.v_string, NULL, NULL,
13600 TRUE, TRUE, &n, NULL); 13638 TRUE, TRUE, &n, NULL);
13601 break; 13639 break;
13602 case VAR_LIST: 13640 case VAR_LIST:
13603 EMSG(_("E703: Using a List as a number")); 13641 EMSG(_("E745: Using a List as a number"));
13604 break; 13642 break;
13605 case VAR_DICT: 13643 case VAR_DICT:
13606 EMSG(_("E728: Using a Dictionary as a number")); 13644 EMSG(_("E728: Using a Dictionary as a number"));
13607 break; 13645 break;
13608 default: 13646 default:
14018 EMSG2(_("E706: Variable type mismatch for: %s"), name); 14056 EMSG2(_("E706: Variable type mismatch for: %s"), name);
14019 return; 14057 return;
14020 } 14058 }
14021 14059
14022 /* 14060 /*
14023 * Handle setting internal v: variables separately: we keep the type. 14061 * Handle setting internal v: variables separately: we don't change
14062 * the type.
14024 */ 14063 */
14025 if (ht == &vimvarht) 14064 if (ht == &vimvarht)
14026 { 14065 {
14027 if (v->di_tv.v_type == VAR_STRING) 14066 if (v->di_tv.v_type == VAR_STRING)
14028 { 14067 {
14830 if (fudi.fd_newkey == NULL && !eap->forceit) 14869 if (fudi.fd_newkey == NULL && !eap->forceit)
14831 { 14870 {
14832 EMSG(_(e_funcdict)); 14871 EMSG(_(e_funcdict));
14833 goto erret; 14872 goto erret;
14834 } 14873 }
14874 if (fudi.fd_di == NULL)
14875 {
14876 /* Can't add a function to a locked dictionary */
14877 if (tv_check_lock(fudi.fd_dict->dv_lock, eap->arg))
14878 goto erret;
14879 }
14880 /* Can't change an existing function if it is locked */
14881 else if (tv_check_lock(fudi.fd_di->di_tv.v_lock, eap->arg))
14882 goto erret;
14835 14883
14836 /* Give the function a sequential number. Can only be used with a 14884 /* Give the function a sequential number. Can only be used with a
14837 * Funcref! */ 14885 * Funcref! */
14838 vim_free(name); 14886 vim_free(name);
14839 sprintf(numbuf, "%d", ++func_nr); 14887 sprintf(numbuf, "%d", ++func_nr);
15508 msg_scroll = TRUE; /* always scroll up, don't overwrite */ 15556 msg_scroll = TRUE; /* always scroll up, don't overwrite */
15509 msg_str((char_u *)_("calling %s"), sourcing_name); 15557 msg_str((char_u *)_("calling %s"), sourcing_name);
15510 if (p_verbose >= 14) 15558 if (p_verbose >= 14)
15511 { 15559 {
15512 char_u buf[MSG_BUF_LEN]; 15560 char_u buf[MSG_BUF_LEN];
15561 char_u numbuf[NUMBUFLEN];
15562 char_u *tofree;
15513 15563
15514 msg_puts((char_u *)"("); 15564 msg_puts((char_u *)"(");
15515 for (i = 0; i < argcount; ++i) 15565 for (i = 0; i < argcount; ++i)
15516 { 15566 {
15517 if (i > 0) 15567 if (i > 0)
15518 msg_puts((char_u *)", "); 15568 msg_puts((char_u *)", ");
15519 if (argvars[i].v_type == VAR_NUMBER) 15569 if (argvars[i].v_type == VAR_NUMBER)
15520 msg_outnum((long)argvars[i].vval.v_number); 15570 msg_outnum((long)argvars[i].vval.v_number);
15521 else 15571 else
15522 { 15572 {
15523 trunc_string(get_tv_string(&argvars[i]), 15573 trunc_string(tv2string(&argvars[i], &tofree, numbuf),
15524 buf, MSG_BUF_LEN); 15574 buf, MSG_BUF_LEN);
15525 msg_puts((char_u *)"\"");
15526 msg_puts(buf); 15575 msg_puts(buf);
15527 msg_puts((char_u *)"\""); 15576 vim_free(tofree);
15528 } 15577 }
15529 } 15578 }
15530 msg_puts((char_u *)")"); 15579 msg_puts((char_u *)")");
15531 } 15580 }
15532 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 15581 msg_puts((char_u *)"\n"); /* don't overwrite this either */
15554 } 15603 }
15555 15604
15556 /* when being verbose, mention the return value */ 15605 /* when being verbose, mention the return value */
15557 if (p_verbose >= 12) 15606 if (p_verbose >= 12)
15558 { 15607 {
15559 char_u *sn, *val; 15608 char_u *sn;
15560 15609
15561 ++no_wait_return; 15610 ++no_wait_return;
15562 msg_scroll = TRUE; /* always scroll up, don't overwrite */ 15611 msg_scroll = TRUE; /* always scroll up, don't overwrite */
15563 15612
15564 /* Make sure the output fits in IObuff. */ 15613 /* Make sure the output fits in IObuff. */
15569 if (aborting()) 15618 if (aborting())
15570 smsg((char_u *)_("%s aborted"), sn); 15619 smsg((char_u *)_("%s aborted"), sn);
15571 else if (fc.rettv->v_type == VAR_NUMBER) 15620 else if (fc.rettv->v_type == VAR_NUMBER)
15572 smsg((char_u *)_("%s returning #%ld"), sn, 15621 smsg((char_u *)_("%s returning #%ld"), sn,
15573 (long)fc.rettv->vval.v_number); 15622 (long)fc.rettv->vval.v_number);
15574 else if (fc.rettv->v_type == VAR_STRING) 15623 else
15575 { 15624 {
15576 val = get_tv_string(fc.rettv); 15625 char_u buf[MSG_BUF_LEN];
15577 if (STRLEN(val) > IOSIZE / 2 - 50) 15626 char_u numbuf[NUMBUFLEN];
15578 val = val + STRLEN(val) - (IOSIZE / 2 - 50); 15627 char_u *tofree;
15579 smsg((char_u *)_("%s returning \"%s\""), sn, val); 15628
15629 trunc_string(tv2string(fc.rettv, &tofree, numbuf),
15630 buf, MSG_BUF_LEN);
15631 smsg((char_u *)_("%s returning %s"), sn, buf);
15632 vim_free(tofree);
15580 } 15633 }
15581 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 15634 msg_puts((char_u *)"\n"); /* don't overwrite this either */
15582 cmdline_row = msg_row; 15635 cmdline_row = msg_row;
15583 --no_wait_return; 15636 --no_wait_return;
15584 } 15637 }