diff src/eval.c @ 9389:32e34e574716 v7.4.1976

commit https://github.com/vim/vim/commit/22fcfad29276bd5f317faf516637dcd491b96a12 Author: Bram Moolenaar <Bram@vim.org> Date: Fri Jul 1 18:17:26 2016 +0200 patch 7.4.1976 Problem: Number variables are not 64 bits while they could be. Solution: Add the num64 feature. (Ken Takata)
author Christian Brabandt <cb@256bit.org>
date Fri, 01 Jul 2016 18:30:07 +0200
parents f094d4085014
children cbf052ccb120
line wrap: on
line diff
--- a/src/eval.c
+++ b/src/eval.c
@@ -1376,7 +1376,7 @@ eval_to_bool(
     int		skip)	    /* only parse, don't execute */
 {
     typval_T	tv;
-    int		retval = FALSE;
+    varnumber_T	retval = FALSE;
 
     if (skip)
 	++emsg_skip;
@@ -1394,7 +1394,7 @@ eval_to_bool(
     if (skip)
 	--emsg_skip;
 
-    return retval;
+    return (int)retval;
 }
 
 /*
@@ -1519,11 +1519,11 @@ eval_to_string_safe(
  * Evaluates "expr" silently.
  * Returns -1 for an error.
  */
-    int
+    varnumber_T
 eval_to_number(char_u *expr)
 {
     typval_T	rettv;
-    int		retval;
+    varnumber_T	retval;
     char_u	*p = skipwhite(expr);
 
     ++emsg_off;
@@ -1628,7 +1628,7 @@ get_spellword(list_T *list, char_u **pp)
     li = li->li_next;
     if (li == NULL)
 	return -1;
-    return get_tv_number(&li->li_tv);
+    return (int)get_tv_number(&li->li_tv);
 }
 #endif
 
@@ -1669,7 +1669,7 @@ call_vim_function(
     typval_T	*rettv)
 {
     typval_T	*argvars;
-    long	n;
+    varnumber_T	n;
     int		len;
     int		i;
     int		doesrange;
@@ -1735,7 +1735,7 @@ call_vim_function(
  * Returns -1 when calling the function fails.
  * Uses argv[argc] for the function arguments.
  */
-    long
+    varnumber_T
 call_func_retnr(
     char_u      *func,
     int		argc,
@@ -1743,7 +1743,7 @@ call_func_retnr(
     int		safe)		/* use the sandbox */
 {
     typval_T	rettv;
-    long	retval;
+    varnumber_T	retval;
 
     /* All arguments are passed as strings, no conversion to number. */
     if (call_vim_function(func, argc, argv, safe, TRUE, &rettv) == FAIL)
@@ -1880,7 +1880,7 @@ prof_child_exit(
 eval_foldexpr(char_u *arg, int *cp)
 {
     typval_T	tv;
-    int		retval;
+    varnumber_T	retval;
     char_u	*s;
     int		use_sandbox = was_set_insecurely((char_u *)"foldexpr",
 								   OPT_LOCAL);
@@ -1915,7 +1915,7 @@ eval_foldexpr(char_u *arg, int *cp)
 	--sandbox;
     --textlock;
 
-    return retval;
+    return (int)retval;
 }
 #endif
 
@@ -2480,7 +2480,7 @@ ex_let_one(
 	    c1 = *p;
 	    *p = NUL;
 
-	    n = get_tv_number(tv);
+	    n = (long)get_tv_number(tv);
 	    s = get_tv_string_chk(tv);	    /* != NULL if number or string */
 	    if (s != NULL && op != NULL && *op != '=')
 	    {
@@ -2888,7 +2888,8 @@ get_lval(
 		lp->ll_n1 = 0;
 	    else
 	    {
-		lp->ll_n1 = get_tv_number(&var1);   /* is number or string */
+		lp->ll_n1 = (long)get_tv_number(&var1);
+						    /* is number or string */
 		clear_tv(&var1);
 	    }
 	    lp->ll_dict = NULL;
@@ -2919,7 +2920,8 @@ get_lval(
 	     */
 	    if (lp->ll_range && !lp->ll_empty2)
 	    {
-		lp->ll_n2 = get_tv_number(&var2);   /* is number or string */
+		lp->ll_n2 = (long)get_tv_number(&var2);
+						    /* is number or string */
 		clear_tv(&var2);
 		if (lp->ll_n2 < 0)
 		{
@@ -3117,7 +3119,7 @@ set_var_lval(
     static int
 tv_op(typval_T *tv1, typval_T *tv2, char_u *op)
 {
-    long	n;
+    varnumber_T	n;
     char_u	numbuf[NUMBUFLEN];
     char_u	*s;
 
@@ -4468,7 +4470,7 @@ eval4(char_u **arg, typval_T *rettv, int
     exptype_T	type = TYPE_UNKNOWN;
     int		type_is = FALSE;    /* TRUE for "is" and "isnot" */
     int		len = 2;
-    long	n1, n2;
+    varnumber_T	n1, n2;
     char_u	*s1, *s2;
     char_u	buf1[NUMBUFLEN], buf2[NUMBUFLEN];
     int		ic;
@@ -4766,7 +4768,7 @@ eval5(char_u **arg, typval_T *rettv, int
     typval_T	var2;
     typval_T	var3;
     int		op;
-    long	n1, n2;
+    varnumber_T	n1, n2;
 #ifdef FEAT_FLOAT
     float_T	f1 = 0, f2 = 0;
 #endif
@@ -4951,7 +4953,7 @@ eval6(
 {
     typval_T	var2;
     int		op;
-    long	n1, n2;
+    varnumber_T	n1, n2;
 #ifdef FEAT_FLOAT
     int		use_float = FALSE;
     float_T	f1 = 0, f2;
@@ -5072,12 +5074,21 @@ eval6(
 		{
 		    if (n2 == 0)	/* give an error message? */
 		    {
+#ifdef FEAT_NUM64
+			if (n1 == 0)
+			    n1 = -0x7fffffffffffffff - 1; /* similar to NaN */
+			else if (n1 < 0)
+			    n1 = -0x7fffffffffffffff;
+			else
+			    n1 = 0x7fffffffffffffff;
+#else
 			if (n1 == 0)
 			    n1 = -0x7fffffffL - 1L;	/* similar to NaN */
 			else if (n1 < 0)
 			    n1 = -0x7fffffffL;
 			else
 			    n1 = 0x7fffffffL;
+#endif
 		    }
 		    else
 			n1 = n1 / n2;
@@ -5131,7 +5142,7 @@ eval7(
     int		evaluate,
     int		want_string UNUSED)	/* after "." operator */
 {
-    long	n;
+    varnumber_T	n;
     int		len;
     char_u	*s;
     char_u	*start_leader, *end_leader;
@@ -5356,7 +5367,7 @@ eval7(
     if (ret == OK && evaluate && end_leader > start_leader)
     {
 	int	    error = FALSE;
-	int	    val = 0;
+	varnumber_T val = 0;
 #ifdef FEAT_FLOAT
 	float_T	    f = 0.0;
 
@@ -6525,7 +6536,7 @@ list_find_nr(
 	    *errorp = TRUE;
 	return -1L;
     }
-    return get_tv_number_chk(&li->li_tv, errorp);
+    return (long)get_tv_number_chk(&li->li_tv, errorp);
 }
 
 /*
@@ -7770,7 +7781,7 @@ dict_add(dict_T *d, dictitem_T *item)
 dict_add_nr_str(
     dict_T	*d,
     char	*key,
-    long	nr,
+    varnumber_T	nr,
     char_u	*str)
 {
     dictitem_T	*item;
@@ -7894,7 +7905,7 @@ get_dict_string(dict_T *d, char_u *key, 
  * Get a number item from a dictionary.
  * Returns 0 if the entry doesn't exist.
  */
-    long
+    varnumber_T
 get_dict_number(dict_T *d, char_u *key)
 {
     dictitem_T	*di;
@@ -9612,7 +9623,7 @@ f_argv(typval_T *argvars, typval_T *rett
 
     if (argvars[0].v_type != VAR_UNKNOWN)
     {
-	idx = get_tv_number_chk(&argvars[0], NULL);
+	idx = (int)get_tv_number_chk(&argvars[0], NULL);
 	if (idx >= 0 && idx < ARGCOUNT)
 	    rettv->vval.v_string = vim_strsave(alist_name(&ARGLIST[idx]));
 	else
@@ -10012,7 +10023,7 @@ f_browse(typval_T *argvars UNUSED, typva
     char_u	buf2[NUMBUFLEN];
     int		error = FALSE;
 
-    save = get_tv_number_chk(&argvars[0], &error);
+    save = (int)get_tv_number_chk(&argvars[0], &error);
     title = get_tv_string_chk(&argvars[1]);
     initdir = get_tv_string_buf_chk(&argvars[2], buf);
     defname = get_tv_string_buf_chk(&argvars[3], buf2);
@@ -10290,7 +10301,7 @@ byteidx(typval_T *argvars, typval_T *ret
     char_u	*t;
 #endif
     char_u	*str;
-    long	idx;
+    varnumber_T	idx;
 
     str = get_tv_string_chk(&argvars[0]);
     idx = get_tv_number_chk(&argvars[1], NULL);
@@ -10660,7 +10671,7 @@ f_char2nr(typval_T *argvars, typval_T *r
 	int	utf8 = 0;
 
 	if (argvars[1].v_type != VAR_UNKNOWN)
-	    utf8 = get_tv_number_chk(&argvars[1], NULL);
+	    utf8 = (int)get_tv_number_chk(&argvars[1], NULL);
 
 	if (utf8)
 	    rettv->vval.v_number = (*utf_ptr2char)(get_tv_string(&argvars[0]));
@@ -10783,7 +10794,7 @@ f_complete(typval_T *argvars, typval_T *
 	return;
     }
 
-    startcol = get_tv_number_chk(&argvars[0], NULL);
+    startcol = (int)get_tv_number_chk(&argvars[0], NULL);
     if (startcol <= 0)
 	return;
 
@@ -10840,7 +10851,7 @@ f_confirm(typval_T *argvars UNUSED, typv
 	    error = TRUE;
 	if (argvars[2].v_type != VAR_UNKNOWN)
 	{
-	    def = get_tv_number_chk(&argvars[2], &error);
+	    def = (int)get_tv_number_chk(&argvars[2], &error);
 	    if (argvars[3].v_type != VAR_UNKNOWN)
 	    {
 		typestr = get_tv_string_buf_chk(&argvars[3], buf2);
@@ -10933,10 +10944,10 @@ f_count(typval_T *argvars, typval_T *ret
 	    {
 		int error = FALSE;
 
-		ic = get_tv_number_chk(&argvars[2], &error);
+		ic = (int)get_tv_number_chk(&argvars[2], &error);
 		if (argvars[3].v_type != VAR_UNKNOWN)
 		{
-		    idx = get_tv_number_chk(&argvars[3], &error);
+		    idx = (long)get_tv_number_chk(&argvars[3], &error);
 		    if (!error)
 		    {
 			li = list_find(l, idx);
@@ -10965,7 +10976,7 @@ f_count(typval_T *argvars, typval_T *ret
 
 	    if (argvars[2].v_type != VAR_UNKNOWN)
 	    {
-		ic = get_tv_number_chk(&argvars[2], &error);
+		ic = (int)get_tv_number_chk(&argvars[2], &error);
 		if (argvars[3].v_type != VAR_UNKNOWN)
 		    EMSG(_(e_invarg));
 	    }
@@ -11055,10 +11066,10 @@ f_cursor(typval_T *argvars, typval_T *re
     else
     {
 	line = get_tv_lnum(argvars);
-	col = get_tv_number_chk(&argvars[1], NULL);
+	col = (long)get_tv_number_chk(&argvars[1], NULL);
 #ifdef FEAT_VIRTUALEDIT
 	if (argvars[2].v_type != VAR_UNKNOWN)
-	    coladd = get_tv_number_chk(&argvars[2], NULL);
+	    coladd = (long)get_tv_number_chk(&argvars[2], NULL);
 #endif
     }
     if (line < 0 || col < 0
@@ -11096,7 +11107,7 @@ f_deepcopy(typval_T *argvars, typval_T *
     int		noref = 0;
 
     if (argvars[1].v_type != VAR_UNKNOWN)
-	noref = get_tv_number_chk(&argvars[1], NULL);
+	noref = (int)get_tv_number_chk(&argvars[1], NULL);
     if (noref < 0 || noref > 1)
 	EMSG(_(e_invarg));
     else
@@ -11604,7 +11615,7 @@ f_extend(typval_T *argvars, typval_T *re
 	{
 	    if (argvars[2].v_type != VAR_UNKNOWN)
 	    {
-		before = get_tv_number_chk(&argvars[2], &error);
+		before = (long)get_tv_number_chk(&argvars[2], &error);
 		if (error)
 		    return;		/* type error; errmsg already given */
 
@@ -11807,7 +11818,7 @@ findfilendir(
 		path = p;
 
 	    if (argvars[2].v_type != VAR_UNKNOWN)
-		count = get_tv_number_chk(&argvars[2], &error);
+		count = (int)get_tv_number_chk(&argvars[2], &error);
 	}
     }
 
@@ -12043,12 +12054,21 @@ f_float2nr(typval_T *argvars, typval_T *
 
     if (get_float_arg(argvars, &f) == OK)
     {
+# ifdef FEAT_NUM64
+	if (f < -0x7fffffffffffffff)
+	    rettv->vval.v_number = -0x7fffffffffffffff;
+	else if (f > 0x7fffffffffffffff)
+	    rettv->vval.v_number = 0x7fffffffffffffff;
+	else
+	    rettv->vval.v_number = (varnumber_T)f;
+# else
 	if (f < -0x7fffffff)
 	    rettv->vval.v_number = -0x7fffffff;
 	else if (f > 0x7fffffff)
 	    rettv->vval.v_number = 0x7fffffff;
 	else
 	    rettv->vval.v_number = (varnumber_T)f;
+# endif
     }
 }
 
@@ -12511,7 +12531,7 @@ f_get(typval_T *argvars, typval_T *rettv
 	{
 	    int		error = FALSE;
 
-	    li = list_find(l, get_tv_number_chk(&argvars[1], &error));
+	    li = list_find(l, (long)get_tv_number_chk(&argvars[1], &error));
 	    if (!error && li != NULL)
 		tv = &li->li_tv;
 	}
@@ -13333,9 +13353,9 @@ f_getreg(typval_T *argvars, typval_T *re
 	error = strregname == NULL;
 	if (argvars[1].v_type != VAR_UNKNOWN)
 	{
-	    arg2 = get_tv_number_chk(&argvars[1], &error);
+	    arg2 = (int)get_tv_number_chk(&argvars[1], &error);
 	    if (!error && argvars[2].v_type != VAR_UNKNOWN)
-		return_list = get_tv_number_chk(&argvars[2], &error);
+		return_list = (int)get_tv_number_chk(&argvars[2], &error);
 	}
     }
     else
@@ -13558,7 +13578,7 @@ find_win_by_nr(
 #endif
     int		nr;
 
-    nr = get_tv_number_chk(vp, NULL);
+    nr = (int)get_tv_number_chk(vp, NULL);
 
 #ifdef FEAT_WINDOWS
     if (nr < 0)
@@ -13601,7 +13621,7 @@ find_tabwin(
     {
 	if (tvp->v_type != VAR_UNKNOWN)
 	{
-	    n = get_tv_number(tvp);
+	    n = (long)get_tv_number(tvp);
 	    if (n >= 0)
 		tp = find_tabpage(n);
 	}
@@ -14126,6 +14146,9 @@ f_has(typval_T *argvars, typval_T *rettv
 	"mzscheme",
 #endif
 #endif
+#ifdef FEAT_NUM64
+	"num64",
+#endif
 #ifdef FEAT_OLE
 	"ole",
 #endif
@@ -14468,7 +14491,7 @@ f_hasmapto(typval_T *argvars, typval_T *
     {
 	mode = get_tv_string_buf(&argvars[1], buf);
 	if (argvars[2].v_type != VAR_UNKNOWN)
-	    abbr = get_tv_number(&argvars[2]);
+	    abbr = (int)get_tv_number(&argvars[2]);
     }
 
     if (map_to_exists(name, mode, abbr))
@@ -14696,10 +14719,10 @@ f_index(typval_T *argvars, typval_T *ret
 
 	    /* Start at specified item.  Use the cached index that list_find()
 	     * sets, so that a negative number also works. */
-	    item = list_find(l, get_tv_number_chk(&argvars[2], &error));
+	    item = list_find(l, (long)get_tv_number_chk(&argvars[2], &error));
 	    idx = l->lv_idx;
 	    if (argvars[3].v_type != VAR_UNKNOWN)
-		ic = get_tv_number_chk(&argvars[3], &error);
+		ic = (int)get_tv_number_chk(&argvars[3], &error);
 	    if (error)
 		item = NULL;
 	}
@@ -14983,7 +15006,7 @@ f_insert(typval_T *argvars, typval_T *re
 	    && !tv_check_lock(l->lv_lock, (char_u *)N_("insert() argument"), TRUE))
     {
 	if (argvars[2].v_type != VAR_UNKNOWN)
-	    before = get_tv_number_chk(&argvars[2], &error);
+	    before = (long)get_tv_number_chk(&argvars[2], &error);
 	if (error)
 	    return;		/* type error; errmsg already given */
 
@@ -15588,9 +15611,9 @@ get_maparg(typval_T *argvars, typval_T *
 	which = get_tv_string_buf_chk(&argvars[1], buf);
 	if (argvars[2].v_type != VAR_UNKNOWN)
 	{
-	    abbr = get_tv_number(&argvars[2]);
+	    abbr = (int)get_tv_number(&argvars[2]);
 	    if (argvars[3].v_type != VAR_UNKNOWN)
-		get_dict = get_tv_number(&argvars[3]);
+		get_dict = (int)get_tv_number(&argvars[3]);
 	}
     }
     else
@@ -15781,7 +15804,7 @@ find_some_match(typval_T *argvars, typva
     {
 	int	    error = FALSE;
 
-	start = get_tv_number_chk(&argvars[2], &error);
+	start = (long)get_tv_number_chk(&argvars[2], &error);
 	if (error)
 	    goto theend;
 	if (l != NULL)
@@ -15810,7 +15833,7 @@ find_some_match(typval_T *argvars, typva
 	}
 
 	if (argvars[3].v_type != VAR_UNKNOWN)
-	    nth = get_tv_number_chk(&argvars[3], &error);
+	    nth = (long)get_tv_number_chk(&argvars[3], &error);
 	if (error)
 	    goto theend;
     }
@@ -15969,10 +15992,10 @@ f_matchadd(typval_T *argvars UNUSED, typ
 	return;
     if (argvars[2].v_type != VAR_UNKNOWN)
     {
-	prio = get_tv_number_chk(&argvars[2], &error);
+	prio = (int)get_tv_number_chk(&argvars[2], &error);
 	if (argvars[3].v_type != VAR_UNKNOWN)
 	{
-	    id = get_tv_number_chk(&argvars[3], &error);
+	    id = (int)get_tv_number_chk(&argvars[3], &error);
 	    if (argvars[4].v_type != VAR_UNKNOWN)
 	    {
 		if (argvars[4].v_type != VAR_DICT)
@@ -16032,10 +16055,10 @@ f_matchaddpos(typval_T *argvars UNUSED, 
 
     if (argvars[2].v_type != VAR_UNKNOWN)
     {
-	prio = get_tv_number_chk(&argvars[2], &error);
+	prio = (int)get_tv_number_chk(&argvars[2], &error);
 	if (argvars[3].v_type != VAR_UNKNOWN)
 	{
-	    id = get_tv_number_chk(&argvars[3], &error);
+	    id = (int)get_tv_number_chk(&argvars[3], &error);
 	    if (argvars[4].v_type != VAR_UNKNOWN)
 	    {
 		if (argvars[4].v_type != VAR_DICT)
@@ -16074,7 +16097,7 @@ f_matcharg(typval_T *argvars UNUSED, typ
     if (rettv_list_alloc(rettv) == OK)
     {
 #ifdef FEAT_SEARCH_EXTRA
-	int	    id = get_tv_number(&argvars[0]);
+	int	    id = (int)get_tv_number(&argvars[0]);
 	matchitem_T *m;
 
 	if (id >= 1 && id <= 3)
@@ -16148,8 +16171,8 @@ static void max_min(typval_T *argvars, t
     static void
 max_min(typval_T *argvars, typval_T *rettv, int domax)
 {
-    long	n = 0;
-    long	i;
+    varnumber_T	n = 0;
+    varnumber_T	i;
     int		error = FALSE;
 
     if (argvars[0].v_type == VAR_LIST)
@@ -16285,7 +16308,7 @@ f_mkdir(typval_T *argvars, typval_T *ret
 	if (argvars[1].v_type != VAR_UNKNOWN)
 	{
 	    if (argvars[2].v_type != VAR_UNKNOWN)
-		prot = get_tv_number_chk(&argvars[2], NULL);
+		prot = (int)get_tv_number_chk(&argvars[2], NULL);
 	    if (prot != -1 && STRCMP(get_tv_string(&argvars[1]), "p") == 0)
 		mkdir_recurse(dir, prot);
 	}
@@ -16428,7 +16451,7 @@ f_nr2char(typval_T *argvars, typval_T *r
 	int	utf8 = 0;
 
 	if (argvars[1].v_type != VAR_UNKNOWN)
-	    utf8 = get_tv_number_chk(&argvars[1], NULL);
+	    utf8 = (int)get_tv_number_chk(&argvars[1], NULL);
 	if (utf8)
 	    buf[(*utf_char2bytes)((int)get_tv_number(&argvars[0]), buf)] = NUL;
 	else
@@ -16610,10 +16633,10 @@ f_pyeval(typval_T *argvars, typval_T *re
     static void
 f_range(typval_T *argvars, typval_T *rettv)
 {
-    long	start;
-    long	end;
-    long	stride = 1;
-    long	i;
+    varnumber_T	start;
+    varnumber_T	end;
+    varnumber_T	stride = 1;
+    varnumber_T	i;
     int		error = FALSE;
 
     start = get_tv_number_chk(&argvars[0], &error);
@@ -16671,7 +16694,7 @@ f_readfile(typval_T *argvars, typval_T *
 	if (STRCMP(get_tv_string(&argvars[1]), "b") == 0)
 	    binary = TRUE;
 	if (argvars[2].v_type != VAR_UNKNOWN)
-	    maxline = get_tv_number(&argvars[2]);
+	    maxline = (long)get_tv_number(&argvars[2]);
     }
 
     if (rettv_list_alloc(rettv) == FAIL)
@@ -17244,7 +17267,7 @@ f_remove(typval_T *argvars, typval_T *re
     {
 	int	    error = FALSE;
 
-	idx = get_tv_number_chk(&argvars[1], &error);
+	idx = (long)get_tv_number_chk(&argvars[1], &error);
 	if (error)
 	    ;		/* type error: do nothing, errmsg already given */
 	else if ((item = list_find(l, idx)) == NULL)
@@ -17261,7 +17284,7 @@ f_remove(typval_T *argvars, typval_T *re
 	    else
 	    {
 		/* Remove range of items, return list with values. */
-		end = get_tv_number_chk(&argvars[2], &error);
+		end = (long)get_tv_number_chk(&argvars[2], &error);
 		if (error)
 		    ;		/* type error: do nothing */
 		else if ((item2 = list_find(l, end)) == NULL)
@@ -17325,7 +17348,7 @@ f_repeat(typval_T *argvars, typval_T *re
     char_u	*r;
     int		i;
 
-    n = get_tv_number(&argvars[1]);
+    n = (int)get_tv_number(&argvars[1]);
     if (argvars[0].v_type == VAR_LIST)
     {
 	if (rettv_list_alloc(rettv) == OK && argvars[0].vval.v_list != NULL)
@@ -17696,13 +17719,13 @@ search_cmn(typval_T *argvars, pos_T *mat
     /* Optional arguments: line number to stop searching and timeout. */
     if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN)
     {
-	lnum_stop = get_tv_number_chk(&argvars[2], NULL);
+	lnum_stop = (long)get_tv_number_chk(&argvars[2], NULL);
 	if (lnum_stop < 0)
 	    goto theend;
 #ifdef FEAT_RELTIME
 	if (argvars[3].v_type != VAR_UNKNOWN)
 	{
-	    time_limit = get_tv_number_chk(&argvars[3], NULL);
+	    time_limit = (long)get_tv_number_chk(&argvars[3], NULL);
 	    if (time_limit < 0)
 		goto theend;
 	}
@@ -17798,8 +17821,8 @@ f_screenattr(typval_T *argvars, typval_T
     int		col;
     int		c;
 
-    row = get_tv_number_chk(&argvars[0], NULL) - 1;
-    col = get_tv_number_chk(&argvars[1], NULL) - 1;
+    row = (int)get_tv_number_chk(&argvars[0], NULL) - 1;
+    col = (int)get_tv_number_chk(&argvars[1], NULL) - 1;
     if (row < 0 || row >= screen_Rows
 	    || col < 0 || col >= screen_Columns)
 	c = -1;
@@ -17819,8 +17842,8 @@ f_screenchar(typval_T *argvars, typval_T
     int		off;
     int		c;
 
-    row = get_tv_number_chk(&argvars[0], NULL) - 1;
-    col = get_tv_number_chk(&argvars[1], NULL) - 1;
+    row = (int)get_tv_number_chk(&argvars[0], NULL) - 1;
+    col = (int)get_tv_number_chk(&argvars[1], NULL) - 1;
     if (row < 0 || row >= screen_Rows
 	    || col < 0 || col >= screen_Columns)
 	c = -1;
@@ -17884,9 +17907,9 @@ f_searchdecl(typval_T *argvars, typval_T
     name = get_tv_string_chk(&argvars[0]);
     if (argvars[1].v_type != VAR_UNKNOWN)
     {
-	locally = get_tv_number_chk(&argvars[1], &error) == 0;
+	locally = (int)get_tv_number_chk(&argvars[1], &error) == 0;
 	if (!error && argvars[2].v_type != VAR_UNKNOWN)
-	    thisblock = get_tv_number_chk(&argvars[2], &error) != 0;
+	    thisblock = (int)get_tv_number_chk(&argvars[2], &error) != 0;
     }
     if (!error && name != NULL)
 	rettv->vval.v_number = find_decl(name, (int)STRLEN(name),
@@ -17946,13 +17969,13 @@ searchpair_cmn(typval_T *argvars, pos_T 
 	skip = get_tv_string_buf_chk(&argvars[4], nbuf3);
 	if (argvars[5].v_type != VAR_UNKNOWN)
 	{
-	    lnum_stop = get_tv_number_chk(&argvars[5], NULL);
+	    lnum_stop = (long)get_tv_number_chk(&argvars[5], NULL);
 	    if (lnum_stop < 0)
 		goto theend;
 #ifdef FEAT_RELTIME
 	    if (argvars[6].v_type != VAR_UNKNOWN)
 	    {
-		time_limit = get_tv_number_chk(&argvars[6], NULL);
+		time_limit = (long)get_tv_number_chk(&argvars[6], NULL);
 		if (time_limit < 0)
 		    goto theend;
 	    }
@@ -18267,7 +18290,7 @@ f_setbufvar(typval_T *argvars, typval_T 
 	    int		error = FALSE;
 
 	    ++varname;
-	    numval = get_tv_number_chk(varp, &error);
+	    numval = (long)get_tv_number_chk(varp, &error);
 	    strval = get_tv_string_buf_chk(varp, nbuf);
 	    if (!error && strval != NULL)
 		set_option_value(varname, numval, strval, OPT_LOCAL);
@@ -18323,7 +18346,7 @@ f_setcharsearch(typval_T *argvars, typva
 
 	di = dict_find(d, (char_u *)"forward", -1);
 	if (di != NULL)
-	    set_csearch_direction(get_tv_number(&di->di_tv)
+	    set_csearch_direction((int)get_tv_number(&di->di_tv)
 							? FORWARD : BACKWARD);
 
 	di = dict_find(d, (char_u *)"until", -1);
@@ -18916,7 +18939,7 @@ setwinvar(typval_T *argvars, typval_T *r
 		int		error = FALSE;
 
 		++varname;
-		numval = get_tv_number_chk(varp, &error);
+		numval = (long)get_tv_number_chk(varp, &error);
 		strval = get_tv_string_buf_chk(varp, nbuf);
 		if (!error && strval != NULL)
 		    set_option_value(varname, numval, strval, OPT_LOCAL);
@@ -19083,8 +19106,8 @@ item_compare(const void *s1, const void 
 
     if (sortinfo->item_compare_numbers)
     {
-	long	v1 = get_tv_number(tv1);
-	long	v2 = get_tv_number(tv2);
+	varnumber_T	v1 = get_tv_number(tv1);
+	varnumber_T	v2 = get_tv_number(tv2);
 
 	return v1 == v2 ? 0 : v1 > v2 ? 1 : -1;
     }
@@ -19190,7 +19213,7 @@ item_compare2(const void *s1, const void
     if (res == FAIL)
 	res = ITEM_COMPARE_FAIL;
     else
-	res = get_tv_number_chk(&rettv, &sortinfo->item_compare_func_err);
+	res = (int)get_tv_number_chk(&rettv, &sortinfo->item_compare_func_err);
     if (sortinfo->item_compare_func_err)
 	res = ITEM_COMPARE_FAIL;  /* return value has wrong type */
     clear_tv(&rettv);
@@ -19259,7 +19282,7 @@ do_sort_uniq(typval_T *argvars, typval_T
 	    {
 		int	    error = FALSE;
 
-		i = get_tv_number_chk(&argvars[1], &error);
+		i = (long)get_tv_number_chk(&argvars[1], &error);
 		if (error)
 		    goto theend;	/* type error; errmsg already given */
 		if (i == 1)
@@ -19516,12 +19539,12 @@ f_spellsuggest(typval_T *argvars UNUSED,
 	str = get_tv_string(&argvars[0]);
 	if (argvars[1].v_type != VAR_UNKNOWN)
 	{
-	    maxcount = get_tv_number_chk(&argvars[1], &typeerr);
+	    maxcount = (int)get_tv_number_chk(&argvars[1], &typeerr);
 	    if (maxcount <= 0)
 		return;
 	    if (argvars[2].v_type != VAR_UNKNOWN)
 	    {
-		need_capital = get_tv_number_chk(&argvars[2], &typeerr);
+		need_capital = (int)get_tv_number_chk(&argvars[2], &typeerr);
 		if (typeerr)
 		    return;
 	    }
@@ -19576,7 +19599,7 @@ f_split(typval_T *argvars, typval_T *ret
 	if (pat == NULL)
 	    typeerr = TRUE;
 	if (argvars[2].v_type != VAR_UNKNOWN)
-	    keepempty = get_tv_number_chk(&argvars[2], &typeerr);
+	    keepempty = (int)get_tv_number_chk(&argvars[2], &typeerr);
     }
     if (pat == NULL || *pat == NUL)
 	pat = (char_u *)"[\\x01- ]\\+";
@@ -19669,12 +19692,12 @@ f_str2nr(typval_T *argvars, typval_T *re
 {
     int		base = 10;
     char_u	*p;
-    long	n;
+    varnumber_T	n;
     int		what;
 
     if (argvars[1].v_type != VAR_UNKNOWN)
     {
-	base = get_tv_number(&argvars[1]);
+	base = (int)get_tv_number(&argvars[1]);
 	if (base != 2 && base != 8 && base != 10 && base != 16)
 	{
 	    EMSG(_(e_invarg));
@@ -19772,7 +19795,7 @@ f_strgetchar(typval_T *argvars, typval_T
     if (str == NULL)
 	return;
     len = (int)STRLEN(str);
-    charidx = get_tv_number_chk(&argvars[1], &error);
+    charidx = (int)get_tv_number_chk(&argvars[1], &error);
     if (error)
 	return;
 #ifdef FEAT_MBYTE
@@ -19819,7 +19842,7 @@ f_stridx(typval_T *argvars, typval_T *re
     {
 	int	    error = FALSE;
 
-	start_idx = get_tv_number_chk(&argvars[2], &error);
+	start_idx = (int)get_tv_number_chk(&argvars[2], &error);
 	if (error || start_idx >= (int)STRLEN(haystack))
 	    return;
 	if (start_idx >= 0)
@@ -19872,7 +19895,7 @@ f_strchars(typval_T *argvars, typval_T *
 #endif
 
     if (argvars[1].v_type != VAR_UNKNOWN)
-	skipcc = get_tv_number_chk(&argvars[1], NULL);
+	skipcc = (int)get_tv_number_chk(&argvars[1], NULL);
     if (skipcc < 0 || skipcc > 1)
 	EMSG(_(e_invarg));
     else
@@ -19901,7 +19924,7 @@ f_strdisplaywidth(typval_T *argvars, typ
     int		col = 0;
 
     if (argvars[1].v_type != VAR_UNKNOWN)
-	col = get_tv_number(&argvars[1]);
+	col = (int)get_tv_number(&argvars[1]);
 
     rettv->vval.v_number = (varnumber_T)(linetabsize_col(col, s) - col);
 }
@@ -19941,7 +19964,7 @@ f_strcharpart(typval_T *argvars, typval_
     p = get_tv_string(&argvars[0]);
     slen = (int)STRLEN(p);
 
-    nchar = get_tv_number_chk(&argvars[1], &error);
+    nchar = (int)get_tv_number_chk(&argvars[1], &error);
     if (!error)
     {
 	if (nchar > 0)
@@ -19954,7 +19977,7 @@ f_strcharpart(typval_T *argvars, typval_
 	    nbyte = nchar;
 	if (argvars[2].v_type != VAR_UNKNOWN)
 	{
-	    charlen = get_tv_number(&argvars[2]);
+	    charlen = (int)get_tv_number(&argvars[2]);
 	    while (charlen > 0 && nbyte + len < slen)
 	    {
 		int off = nbyte + len;
@@ -20008,11 +20031,11 @@ f_strpart(typval_T *argvars, typval_T *r
     p = get_tv_string(&argvars[0]);
     slen = (int)STRLEN(p);
 
-    n = get_tv_number_chk(&argvars[1], &error);
+    n = (int)get_tv_number_chk(&argvars[1], &error);
     if (error)
 	len = 0;
     else if (argvars[2].v_type != VAR_UNKNOWN)
-	len = get_tv_number(&argvars[2]);
+	len = (int)get_tv_number(&argvars[2]);
     else
 	len = slen - n;	    /* default len: all bytes that are available. */
 
@@ -20060,7 +20083,7 @@ f_strridx(typval_T *argvars, typval_T *r
     if (argvars[2].v_type != VAR_UNKNOWN)
     {
 	/* Third argument: upper limit for index */
-	end_idx = get_tv_number_chk(&argvars[2], NULL);
+	end_idx = (int)get_tv_number_chk(&argvars[2], NULL);
 	if (end_idx < 0)
 	    return;	/* can never find a match */
     }
@@ -20114,7 +20137,7 @@ f_submatch(typval_T *argvars, typval_T *
 	return;
     error = FALSE;
     if (argvars[1].v_type != VAR_UNKNOWN)
-	retList = get_tv_number_chk(&argvars[1], &error);
+	retList = (int)get_tv_number_chk(&argvars[1], &error);
     if (error)
 	return;
 
@@ -20160,14 +20183,14 @@ f_synID(typval_T *argvars UNUSED, typval
 {
     int		id = 0;
 #ifdef FEAT_SYN_HL
-    long	lnum;
-    long	col;
+    linenr_T	lnum;
+    colnr_T	col;
     int		trans;
     int		transerr = FALSE;
 
     lnum = get_tv_lnum(argvars);		/* -1 on type error */
-    col = get_tv_number(&argvars[1]) - 1;	/* -1 on type error */
-    trans = get_tv_number_chk(&argvars[2], &transerr);
+    col = (linenr_T)get_tv_number(&argvars[1]) - 1;	/* -1 on type error */
+    trans = (int)get_tv_number_chk(&argvars[2], &transerr);
 
     if (!transerr && lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count
 	    && col >= 0 && col < (long)STRLEN(ml_get(lnum)))
@@ -20191,7 +20214,7 @@ f_synIDattr(typval_T *argvars UNUSED, ty
     char_u	modebuf[NUMBUFLEN];
     int		modec;
 
-    id = get_tv_number(&argvars[0]);
+    id = (int)get_tv_number(&argvars[0]);
     what = get_tv_string(&argvars[1]);
     if (argvars[2].v_type != VAR_UNKNOWN)
     {
@@ -20275,7 +20298,7 @@ f_synIDtrans(typval_T *argvars UNUSED, t
     int		id;
 
 #ifdef FEAT_SYN_HL
-    id = get_tv_number(&argvars[0]);
+    id = (int)get_tv_number(&argvars[0]);
 
     if (id > 0)
 	id = syn_get_final_id(id);
@@ -20293,8 +20316,8 @@ f_synIDtrans(typval_T *argvars UNUSED, t
 f_synconcealed(typval_T *argvars UNUSED, typval_T *rettv)
 {
 #if defined(FEAT_SYN_HL) && defined(FEAT_CONCEAL)
-    long	lnum;
-    long	col;
+    linenr_T	lnum;
+    colnr_T	col;
     int		syntax_flags = 0;
     int		cchar;
     int		matchid = 0;
@@ -20306,7 +20329,7 @@ f_synconcealed(typval_T *argvars UNUSED,
 
 #if defined(FEAT_SYN_HL) && defined(FEAT_CONCEAL)
     lnum = get_tv_lnum(argvars);		/* -1 on type error */
-    col = get_tv_number(&argvars[1]) - 1;	/* -1 on type error */
+    col = (colnr_T)get_tv_number(&argvars[1]) - 1;	/* -1 on type error */
 
     vim_memset(str, NUL, sizeof(str));
 
@@ -20353,8 +20376,8 @@ f_synconcealed(typval_T *argvars UNUSED,
 f_synstack(typval_T *argvars UNUSED, typval_T *rettv)
 {
 #ifdef FEAT_SYN_HL
-    long	lnum;
-    long	col;
+    linenr_T	lnum;
+    colnr_T	col;
     int		i;
     int		id;
 #endif
@@ -20364,7 +20387,7 @@ f_synstack(typval_T *argvars UNUSED, typ
 
 #ifdef FEAT_SYN_HL
     lnum = get_tv_lnum(argvars);		/* -1 on type error */
-    col = get_tv_number(&argvars[1]) - 1;	/* -1 on type error */
+    col = (colnr_T)get_tv_number(&argvars[1]) - 1;	/* -1 on type error */
 
     if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count
 	    && col >= 0 && col <= (long)STRLEN(ml_get(lnum))
@@ -20835,7 +20858,7 @@ f_test_alloc_fail(typval_T *argvars, typ
     static void
 f_test_disable_char_avail(typval_T *argvars, typval_T *rettv UNUSED)
 {
-    disable_char_avail_for_testing = get_tv_number(&argvars[0]);
+    disable_char_avail_for_testing = (int)get_tv_number(&argvars[0]);
 }
 
 /*
@@ -20933,7 +20956,7 @@ get_callback(typval_T *arg, partial_T **
     static void
 f_timer_start(typval_T *argvars, typval_T *rettv)
 {
-    long    msec = get_tv_number(&argvars[0]);
+    long    msec = (long)get_tv_number(&argvars[0]);
     timer_T *timer;
     int	    repeat = 0;
     char_u  *callback;
@@ -20980,7 +21003,7 @@ f_timer_stop(typval_T *argvars, typval_T
          EMSG(_(e_number_exp));
          return;
     }
-    timer = find_timer(get_tv_number(&argvars[0]));
+    timer = find_timer((int)get_tv_number(&argvars[0]));
     if (timer != NULL)
 	stop_timer(timer);
 }
@@ -21436,29 +21459,29 @@ f_winrestview(typval_T *argvars, typval_
     else
     {
 	if (dict_find(dict, (char_u *)"lnum", -1) != NULL)
-	    curwin->w_cursor.lnum = get_dict_number(dict, (char_u *)"lnum");
+	    curwin->w_cursor.lnum = (linenr_T)get_dict_number(dict, (char_u *)"lnum");
 	if (dict_find(dict, (char_u *)"col", -1) != NULL)
-	    curwin->w_cursor.col = get_dict_number(dict, (char_u *)"col");
+	    curwin->w_cursor.col = (colnr_T)get_dict_number(dict, (char_u *)"col");
 #ifdef FEAT_VIRTUALEDIT
 	if (dict_find(dict, (char_u *)"coladd", -1) != NULL)
-	    curwin->w_cursor.coladd = get_dict_number(dict, (char_u *)"coladd");
+	    curwin->w_cursor.coladd = (colnr_T)get_dict_number(dict, (char_u *)"coladd");
 #endif
 	if (dict_find(dict, (char_u *)"curswant", -1) != NULL)
 	{
-	    curwin->w_curswant = get_dict_number(dict, (char_u *)"curswant");
+	    curwin->w_curswant = (colnr_T)get_dict_number(dict, (char_u *)"curswant");
 	    curwin->w_set_curswant = FALSE;
 	}
 
 	if (dict_find(dict, (char_u *)"topline", -1) != NULL)
-	    set_topline(curwin, get_dict_number(dict, (char_u *)"topline"));
+	    set_topline(curwin, (linenr_T)get_dict_number(dict, (char_u *)"topline"));
 #ifdef FEAT_DIFF
 	if (dict_find(dict, (char_u *)"topfill", -1) != NULL)
-	    curwin->w_topfill = get_dict_number(dict, (char_u *)"topfill");
+	    curwin->w_topfill = (int)get_dict_number(dict, (char_u *)"topfill");
 #endif
 	if (dict_find(dict, (char_u *)"leftcol", -1) != NULL)
-	    curwin->w_leftcol = get_dict_number(dict, (char_u *)"leftcol");
+	    curwin->w_leftcol = (colnr_T)get_dict_number(dict, (char_u *)"leftcol");
 	if (dict_find(dict, (char_u *)"skipcol", -1) != NULL)
-	    curwin->w_skipcol = get_dict_number(dict, (char_u *)"skipcol");
+	    curwin->w_skipcol = (colnr_T)get_dict_number(dict, (char_u *)"skipcol");
 
 	check_cursor();
 	win_new_height(curwin, curwin->w_height);
@@ -22120,7 +22143,7 @@ eval_isnamec1(int c)
  * Set number v: variable to "val".
  */
     void
-set_vim_var_nr(int idx, long val)
+set_vim_var_nr(int idx, varnumber_T val)
 {
     vimvars[idx].vv_nr = val;
 }
@@ -22128,7 +22151,7 @@ set_vim_var_nr(int idx, long val)
 /*
  * Get number v: variable value.
  */
-    long
+    varnumber_T
 get_vim_var_nr(int idx)
 {
     return vimvars[idx].vv_nr;
@@ -22742,7 +22765,7 @@ init_tv(typval_T *varp)
  * caller of incompatible types: it sets *denote to TRUE if "denote"
  * is not NULL or returns -1 otherwise.
  */
-    long
+    varnumber_T
 get_tv_number(typval_T *varp)
 {
     int		error = FALSE;
@@ -22750,15 +22773,15 @@ get_tv_number(typval_T *varp)
     return get_tv_number_chk(varp, &error);	/* return 0L on error */
 }
 
-    long
+    varnumber_T
 get_tv_number_chk(typval_T *varp, int *denote)
 {
-    long	n = 0L;
+    varnumber_T	n = 0L;
 
     switch (varp->v_type)
     {
 	case VAR_NUMBER:
-	    return (long)(varp->vval.v_number);
+	    return varp->vval.v_number;
 	case VAR_FLOAT:
 #ifdef FEAT_FLOAT
 	    EMSG(_("E805: Using a Float as a Number"));
@@ -22858,12 +22881,12 @@ get_tv_lnum(typval_T *argvars)
     typval_T	rettv;
     linenr_T	lnum;
 
-    lnum = get_tv_number_chk(&argvars[0], NULL);
+    lnum = (linenr_T)get_tv_number_chk(&argvars[0], NULL);
     if (lnum == 0)  /* no valid number, try using line() */
     {
 	rettv.v_type = VAR_NUMBER;
 	f_line(argvars, &rettv);
-	lnum = rettv.vval.v_number;
+	lnum = (linenr_T)rettv.vval.v_number;
 	clear_tv(&rettv);
     }
     return lnum;
@@ -22882,7 +22905,7 @@ get_tv_lnum_buf(typval_T *argvars, buf_T
 	    && argvars[0].vval.v_string[0] == '$'
 	    && buf != NULL)
 	return buf->b_ml.ml_line_count;
-    return get_tv_number_chk(&argvars[0], NULL);
+    return (linenr_T)get_tv_number_chk(&argvars[0], NULL);
 }
 
 /*
@@ -22928,7 +22951,8 @@ get_tv_string_buf_chk(typval_T *varp, ch
     switch (varp->v_type)
     {
 	case VAR_NUMBER:
-	    sprintf((char *)buf, "%ld", (long)varp->vval.v_number);
+	    vim_snprintf((char *)buf, NUMBUFLEN, "%lld",
+					    (varnumber_T)varp->vval.v_number);
 	    return buf;
 	case VAR_FUNC:
 	case VAR_PARTIAL: