# HG changeset patch # User Christian Brabandt # Date 1467390607 -7200 # Node ID 32e34e574716979ae1ea9fa624f69d590d428a7d # Parent 404ac7af0e7e53dd191de0aa8e1a6bd33dc3bc27 commit https://github.com/vim/vim/commit/22fcfad29276bd5f317faf516637dcd491b96a12 Author: Bram Moolenaar 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) diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1,4 +1,4 @@ -*eval.txt* For Vim version 7.4. Last change: 2016 Jun 06 +*eval.txt* For Vim version 7.4. Last change: 2016 Jul 01 VIM REFERENCE MANUAL by Bram Moolenaar @@ -40,6 +40,8 @@ 1.1 Variable types ~ There are nine types of variables: Number A 32 or 64 bit signed number. |expr-number| *Number* + 64-bit Number is available only when compiled with the + |+num64| feature. Examples: -123 0x10 0177 Float A floating point number. |floating-point-format| *Float* @@ -888,6 +890,11 @@ When dividing a Number by zero the resul <0 / 0 = -0x7fffffff (like negative infinity) (before Vim 7.2 it was always 0x7fffffff) +When 64-bit Number support is enabled: + 0 / 0 = -0x8000000000000000 (like NaN for Float) + >0 / 0 = 0x7fffffffffffffff (like positive infinity) + <0 / 0 = -0x7fffffffffffffff (like negative infinity) + When the righthand side of '%' is zero, the result is 0. None of these work for |Funcref|s. @@ -3566,17 +3573,19 @@ float2nr({expr}) *float2nr()* decimal point. {expr} must evaluate to a |Float| or a Number. When the value of {expr} is out of range for a |Number| the - result is truncated to 0x7fffffff or -0x7fffffff. NaN results - in -0x80000000. + result is truncated to 0x7fffffff or -0x7fffffff (or when + 64-bit Number support is enabled, 0x7fffffffffffffff or + -0x7fffffffffffffff. NaN results in -0x80000000 (or when + 64-bit Number support is enabled, -0x8000000000000000). Examples: > echo float2nr(3.95) < 3 > echo float2nr(-23.45) < -23 > echo float2nr(1.0e100) -< 2147483647 > +< 2147483647 (or 9223372036854775807) > echo float2nr(-1.0e150) -< -2147483647 > +< -2147483647 (or -9223372036854775807) > echo float2nr(1.0e-100) < 0 {only available when compiled with the |+float| feature} @@ -7655,7 +7664,10 @@ winwidth({nr}) *winwidth()* :if winwidth(0) <= 50 : exe "normal 50\|" :endif -< +< For getting the terminal or screen size, see the 'columns' + option. + + wordcount() *wordcount()* The result is a dictionary of byte/chars/word statistics for the current buffer. This is the same info as provided by @@ -7842,6 +7854,7 @@ multi_lang Compiled with support for mu mzscheme Compiled with MzScheme interface |mzscheme|. netbeans_enabled Compiled with support for |netbeans| and connected. netbeans_intg Compiled with support for |netbeans|. +num64 Compiled with 64-bit |Number| support. ole Compiled with OLE automation support for Win32. os2 OS/2 version of Vim. packages Compiled with |packages| support. diff --git a/runtime/doc/various.txt b/runtime/doc/various.txt --- a/runtime/doc/various.txt +++ b/runtime/doc/various.txt @@ -390,6 +390,7 @@ N *+multi_lang* non-English language su m *+mzscheme* Mzscheme interface |mzscheme| m *+mzscheme/dyn* Mzscheme interface |mzscheme-dynamic| |/dyn| m *+netbeans_intg* |netbeans| + *+num64* 64-bit Number support |Number| m *+ole* Win32 GUI only: |ole-interface| N *+packages* Loading |packages| N *+path_extra* Up/downwards search in 'path' and 'tags' diff --git a/src/Make_cyg_ming.mak b/src/Make_cyg_ming.mak --- a/src/Make_cyg_ming.mak +++ b/src/Make_cyg_ming.mak @@ -379,7 +379,7 @@ endif # RUBY # Any other defines can be included here. DEF_GUI=-DFEAT_GUI_W32 -DFEAT_CLIPBOARD DEFINES=-DWIN32 -DWINVER=$(WINVER) -D_WIN32_WINNT=$(WINVER) \ - -DHAVE_PATHDEF -DFEAT_$(FEATURES) + -DHAVE_PATHDEF -DFEAT_$(FEATURES) -DHAVE_STDINT_H ifeq ($(ARCH),x86-64) DEFINES+=-DMS_WIN64 endif diff --git a/src/Make_mvc.mak b/src/Make_mvc.mak --- a/src/Make_mvc.mak +++ b/src/Make_mvc.mak @@ -501,6 +501,11 @@ OPTFLAG = $(OPTFLAG) /GL CFLAGS=$(CFLAGS) $(WP64CHECK) !endif +# VC10 or later has stdint.h. +!if $(MSVC_MAJOR) >= 10 +CFLAGS = $(CFLAGS) -DHAVE_STDINT_H +!endif + # Static code analysis generally available starting with VS2012 (VC11) or # Windows SDK 7.1 (VC10) !if ("$(ANALYZE)" == "yes") && ($(MSVC_MAJOR) >= 10) diff --git a/src/charset.c b/src/charset.c --- a/src/charset.c +++ b/src/charset.c @@ -1836,14 +1836,14 @@ vim_str2nr( is bin */ int *len, /* return: detected length of number */ int what, /* what numbers to recognize */ - long *nptr, /* return: signed result */ - unsigned long *unptr, /* return: unsigned result */ + varnumber_T *nptr, /* return: signed result */ + uvarnumber_T *unptr, /* return: unsigned result */ int maxlen) /* max length of string to check */ { char_u *ptr = start; int pre = 0; /* default is decimal */ int negative = FALSE; - unsigned long un = 0; + uvarnumber_T un = 0; int n; if (ptr[0] == '-') @@ -1912,7 +1912,7 @@ vim_str2nr( /* octal */ while ('0' <= *ptr && *ptr <= '7') { - un = 8 * un + (unsigned long)(*ptr - '0'); + un = 8 * un + (uvarnumber_T)(*ptr - '0'); ++ptr; if (n++ == maxlen) break; @@ -1925,7 +1925,7 @@ vim_str2nr( n += 2; /* skip over "0x" */ while (vim_isxdigit(*ptr)) { - un = 16 * un + (unsigned long)hex2nr(*ptr); + un = 16 * un + (uvarnumber_T)hex2nr(*ptr); ++ptr; if (n++ == maxlen) break; @@ -1936,7 +1936,7 @@ vim_str2nr( /* decimal */ while (VIM_ISDIGIT(*ptr)) { - un = 10 * un + (unsigned long)(*ptr - '0'); + un = 10 * un + (uvarnumber_T)(*ptr - '0'); ++ptr; if (n++ == maxlen) break; @@ -1950,9 +1950,9 @@ vim_str2nr( if (nptr != NULL) { if (negative) /* account for leading '-' for decimal numbers */ - *nptr = -(long)un; + *nptr = -(varnumber_T)un; else - *nptr = (long)un; + *nptr = (varnumber_T)un; } if (unptr != NULL) *unptr = un; diff --git a/src/eval.c b/src/eval.c --- 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: diff --git a/src/ex_cmds.c b/src/ex_cmds.c --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -289,10 +289,10 @@ typedef struct union { struct { - long start_col_nr; /* starting column number */ - long end_col_nr; /* ending column number */ + varnumber_T start_col_nr; /* starting column number */ + varnumber_T end_col_nr; /* ending column number */ } line; - long value; /* value if sorting by integer */ + varnumber_T value; /* value if sorting by integer */ #ifdef FEAT_FLOAT float_T value_flt; /* value if sorting by float */ #endif diff --git a/src/ex_getln.c b/src/ex_getln.c --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -6005,7 +6005,7 @@ get_list_range(char_u **str, int *num1, { int len; int first = FALSE; - long num; + varnumber_T num; *str = skipwhite(*str); if (**str == '-' || vim_isdigit(**str)) /* parse "from" part of range */ diff --git a/src/feature.h b/src/feature.h --- a/src/feature.h +++ b/src/feature.h @@ -362,12 +362,16 @@ * +eval Built-in script language and expression evaluation, * ":let", ":if", etc. * +float Floating point variables. + * +num64 64-bit Number. */ #ifdef FEAT_NORMAL # define FEAT_EVAL # if defined(HAVE_FLOAT_FUNCS) || defined(WIN3264) || defined(MACOS) # define FEAT_FLOAT # endif +# if defined(HAVE_STDINT_H) || defined(WIN3264) || (VIM_SIZEOF_LONG >= 8) +# define FEAT_NUM64 +# endif #endif /* diff --git a/src/fileio.c b/src/fileio.c --- a/src/fileio.c +++ b/src/fileio.c @@ -9481,7 +9481,7 @@ apply_autocmds_group( #ifdef FEAT_EVAL /* set v:cmdarg (only when there is a matching pattern) */ - save_cmdbang = get_vim_var_nr(VV_CMDBANG); + save_cmdbang = (long)get_vim_var_nr(VV_CMDBANG); if (eap != NULL) { save_cmdarg = set_cmdarg(eap, NULL); diff --git a/src/fold.c b/src/fold.c --- a/src/fold.c +++ b/src/fold.c @@ -3032,7 +3032,7 @@ foldlevelExpr(fline_T *flp) /* KeyTyped may be reset to 0 when calling a function which invokes * do_cmdline(). To make 'foldopen' work correctly restore KeyTyped. */ save_keytyped = KeyTyped; - n = eval_foldexpr(flp->wp->w_p_fde, &c); + n = (int)eval_foldexpr(flp->wp->w_p_fde, &c); KeyTyped = save_keytyped; switch (c) diff --git a/src/json.c b/src/json.c --- a/src/json.c +++ b/src/json.c @@ -201,8 +201,8 @@ json_encode_item(garray_T *gap, typval_T break; case VAR_NUMBER: - vim_snprintf((char *)numbuf, NUMBUFLEN, "%ld", - (long)val->vval.v_number); + vim_snprintf((char *)numbuf, NUMBUFLEN, "%lld", + val->vval.v_number); ga_concat(gap, numbuf); break; @@ -538,7 +538,7 @@ json_decode_string(js_read_T *reader, ty int len; char_u *p; int c; - long nr; + varnumber_T nr; if (res != NULL) ga_init2(&ga, 1, 200); @@ -600,7 +600,7 @@ json_decode_string(js_read_T *reader, ty && (int)(reader->js_end - p) >= 6 && *p == '\\' && *(p+1) == 'u') { - long nr2 = 0; + varnumber_T nr2 = 0; /* decode surrogate pair: \ud812\u3456 */ len = 0; @@ -620,7 +620,7 @@ json_decode_string(js_read_T *reader, ty buf[utf_char2bytes((int)nr, buf)] = NUL; ga_concat(&ga, buf); #else - ga_append(&ga, nr); + ga_append(&ga, (int)nr); #endif } break; @@ -766,7 +766,7 @@ json_decode_item(js_read_T *reader, typv else #endif { - long nr; + varnumber_T nr; vim_str2nr(reader->js_buf + reader->js_used, NULL, &len, 0, /* what */ diff --git a/src/message.c b/src/message.c --- a/src/message.c +++ b/src/message.c @@ -3846,7 +3846,7 @@ do_browse( #if defined(FEAT_EVAL) static char *e_printf = N_("E766: Insufficient arguments for printf()"); -static long tv_nr(typval_T *tvs, int *idxp); +static varnumber_T tv_nr(typval_T *tvs, int *idxp); static char *tv_str(typval_T *tvs, int *idxp); # ifdef FEAT_FLOAT static double tv_float(typval_T *tvs, int *idxp); @@ -3855,11 +3855,11 @@ static double tv_float(typval_T *tvs, in /* * Get number argument from "idxp" entry in "tvs". First entry is 1. */ - static long + static varnumber_T tv_nr(typval_T *tvs, int *idxp) { int idx = *idxp - 1; - long n = 0; + varnumber_T n = 0; int err = FALSE; if (tvs[idx].v_type == VAR_UNKNOWN) @@ -3912,7 +3912,7 @@ tv_float(typval_T *tvs, int *idxp) if (tvs[idx].v_type == VAR_FLOAT) f = tvs[idx].vval.v_float; else if (tvs[idx].v_type == VAR_NUMBER) - f = tvs[idx].vval.v_number; + f = (double)tvs[idx].vval.v_number; else EMSG(_("E807: Expected Float argument for printf()")); } @@ -4170,7 +4170,11 @@ vim_vsnprintf( if (length_modifier == 'l' && *p == 'l') { /* double l = long long */ +# ifdef FEAT_NUM64 + length_modifier = 'L'; +# else length_modifier = 'l'; /* treat it as a single 'l' */ +# endif p++; } } @@ -4299,6 +4303,12 @@ vim_vsnprintf( long int long_arg = 0; unsigned long int ulong_arg = 0; +# ifdef FEAT_NUM64 + /* only defined for length modifier ll */ + varnumber_T llong_arg = 0; + uvarnumber_T ullong_arg = 0; +# endif + /* pointer argument value -only defined for p * conversion */ void *ptr_arg = NULL; @@ -4343,6 +4353,19 @@ vim_vsnprintf( else if (long_arg < 0) arg_sign = -1; break; +# ifdef FEAT_NUM64 + case 'L': + llong_arg = +# if defined(FEAT_EVAL) + tvs != NULL ? tv_nr(tvs, &arg_idx) : +# endif + va_arg(ap, varnumber_T); + if (llong_arg > 0) + arg_sign = 1; + else if (llong_arg < 0) + arg_sign = -1; + break; +# endif } } else @@ -4371,6 +4394,18 @@ vim_vsnprintf( if (ulong_arg != 0) arg_sign = 1; break; +# ifdef FEAT_NUM64 + case 'L': + ullong_arg = +# if defined(FEAT_EVAL) + tvs != NULL ? (uvarnumber_T) + tv_nr(tvs, &arg_idx) : +# endif + va_arg(ap, uvarnumber_T); + if (ullong_arg != 0) + arg_sign = 1; + break; +# endif } } @@ -4415,17 +4450,27 @@ vim_vsnprintf( } else { - char f[5]; + char f[6]; int f_l = 0; /* construct a simple format string for sprintf */ f[f_l++] = '%'; if (!length_modifier) ; - else if (length_modifier == '2') + else if (length_modifier == 'L') { +# ifdef FEAT_NUM64 +# ifdef WIN3264 + f[f_l++] = 'I'; + f[f_l++] = '6'; + f[f_l++] = '4'; +# else f[f_l++] = 'l'; f[f_l++] = 'l'; +# endif +# else + f[f_l++] = 'l'; +# endif } else f[f_l++] = length_modifier; @@ -4446,6 +4491,11 @@ vim_vsnprintf( case 'l': str_arg_l += sprintf( tmp + str_arg_l, f, long_arg); break; +# ifdef FEAT_NUM64 + case 'L': str_arg_l += sprintf( + tmp + str_arg_l, f, llong_arg); + break; +# endif } } else @@ -4460,6 +4510,11 @@ vim_vsnprintf( case 'l': str_arg_l += sprintf( tmp + str_arg_l, f, ulong_arg); break; +# ifdef FEAT_NUM64 + case 'L': str_arg_l += sprintf( + tmp + str_arg_l, f, ullong_arg); + break; +# endif } } diff --git a/src/misc1.c b/src/misc1.c --- a/src/misc1.c +++ b/src/misc1.c @@ -9169,7 +9169,7 @@ get_expr_indent(void) if (use_sandbox) ++sandbox; ++textlock; - indent = eval_to_number(curbuf->b_p_inde); + indent = (int)eval_to_number(curbuf->b_p_inde); if (use_sandbox) --sandbox; --textlock; diff --git a/src/misc2.c b/src/misc2.c --- a/src/misc2.c +++ b/src/misc2.c @@ -2719,7 +2719,7 @@ find_special_key( int modifiers; int bit; int key; - unsigned long n; + uvarnumber_T n; int l; src = *srcp; diff --git a/src/ops.c b/src/ops.c --- a/src/ops.c +++ b/src/ops.c @@ -1179,9 +1179,9 @@ stuff_yank(int regname, char_u *p) static int execreg_lastc = NUL; /* - * execute a yank register: copy it into the stuff buffer + * Execute a yank register: copy it into the stuff buffer. * - * return FAIL for failure, OK otherwise + * Return FAIL for failure, OK otherwise. */ int do_execreg( @@ -4755,7 +4755,7 @@ fex_format( */ if (use_sandbox) ++sandbox; - r = eval_to_number(curbuf->b_p_fex); + r = (int)eval_to_number(curbuf->b_p_fex); if (use_sandbox) --sandbox; @@ -5449,8 +5449,8 @@ do_addsub( char_u buf2[NUMBUFLEN]; int pre; /* 'X'/'x': hex; '0': octal; 'B'/'b': bin */ static int hexupper = FALSE; /* 0xABC */ - unsigned long n; - long_u oldn; + uvarnumber_T n; + uvarnumber_T oldn; char_u *ptr; int c; int todel; @@ -5708,9 +5708,9 @@ do_addsub( oldn = n; if (subtract) - n -= (unsigned long)Prenum1; + n -= (uvarnumber_T)Prenum1; else - n += (unsigned long)Prenum1; + n += (uvarnumber_T)Prenum1; /* handle wraparound for decimal numbers */ if (!pre) { @@ -5718,7 +5718,7 @@ do_addsub( { if (n > oldn) { - n = 1 + (n ^ (unsigned long)-1); + n = 1 + (n ^ (uvarnumber_T)-1); negative ^= TRUE; } } @@ -5727,7 +5727,7 @@ do_addsub( /* add */ if (n < oldn) { - n = (n ^ (unsigned long)-1); + n = (n ^ (uvarnumber_T)-1); negative ^= TRUE; } } @@ -5803,7 +5803,7 @@ do_addsub( { int i; int bit = 0; - int bits = sizeof(unsigned long) * 8; + int bits = sizeof(uvarnumber_T) * 8; /* leading zeros */ for (bit = bits; bit > 0; bit--) @@ -5815,13 +5815,13 @@ do_addsub( buf2[i] = '\0'; } else if (pre == 0) - sprintf((char *)buf2, "%lu", n); + vim_snprintf((char *)buf2, NUMBUFLEN, "%llu", n); else if (pre == '0') - sprintf((char *)buf2, "%lo", n); + vim_snprintf((char *)buf2, NUMBUFLEN, "%llo", n); else if (pre && hexupper) - sprintf((char *)buf2, "%lX", n); + vim_snprintf((char *)buf2, NUMBUFLEN, "%llX", n); else - sprintf((char *)buf2, "%lx", n); + vim_snprintf((char *)buf2, NUMBUFLEN, "%llx", n); length -= (int)STRLEN(buf2); /* @@ -7086,7 +7086,7 @@ clear_oparg(oparg_T *oap) vim_memset(oap, 0, sizeof(oparg_T)); } -static long line_count_info(char_u *line, long *wc, long *cc, long limit, int eol_size); +static varnumber_T line_count_info(char_u *line, varnumber_T *wc, varnumber_T *cc, varnumber_T limit, int eol_size); /* * Count the number of bytes, characters and "words" in a line. @@ -7102,17 +7102,17 @@ static long line_count_info(char_u *line * case, eol_size will be added to the character count to account for * the size of the EOL character. */ - static long + static varnumber_T line_count_info( char_u *line, - long *wc, - long *cc, - long limit, + varnumber_T *wc, + varnumber_T *cc, + varnumber_T limit, int eol_size) { - long i; - long words = 0; - long chars = 0; + varnumber_T i; + varnumber_T words = 0; + varnumber_T chars = 0; int is_word = 0; for (i = 0; i < limit && line[i] != NUL; ) @@ -7162,17 +7162,17 @@ cursor_pos_info(dict_T *dict) char_u buf1[50]; char_u buf2[40]; linenr_T lnum; - long byte_count = 0; + varnumber_T byte_count = 0; #ifdef FEAT_MBYTE - long bom_count = 0; -#endif - long byte_count_cursor = 0; - long char_count = 0; - long char_count_cursor = 0; - long word_count = 0; - long word_count_cursor = 0; + varnumber_T bom_count = 0; +#endif + varnumber_T byte_count_cursor = 0; + varnumber_T char_count = 0; + varnumber_T char_count_cursor = 0; + varnumber_T word_count = 0; + varnumber_T word_count_cursor = 0; int eol_size; - long last_check = 100000L; + varnumber_T last_check = 100000L; long line_count_selected = 0; pos_T min_pos, max_pos; oparg_T oparg; @@ -7308,12 +7308,14 @@ cursor_pos_info(dict_T *dict) byte_count_cursor = byte_count + line_count_info(ml_get(lnum), &word_count_cursor, &char_count_cursor, - (long)(curwin->w_cursor.col + 1), eol_size); + (varnumber_T)(curwin->w_cursor.col + 1), + eol_size); } } /* Add to the running totals */ byte_count += line_count_info(ml_get(lnum), &word_count, - &char_count, (long)MAXCOL, eol_size); + &char_count, (varnumber_T)MAXCOL, + eol_size); } /* Correction for when last line doesn't have an EOL. */ @@ -7337,14 +7339,14 @@ cursor_pos_info(dict_T *dict) if (char_count_cursor == byte_count_cursor && char_count == byte_count) vim_snprintf((char *)IObuff, IOSIZE, - _("Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"), + _("Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Bytes"), buf1, line_count_selected, (long)curbuf->b_ml.ml_line_count, word_count_cursor, word_count, byte_count_cursor, byte_count); else vim_snprintf((char *)IObuff, IOSIZE, - _("Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Chars; %ld of %ld Bytes"), + _("Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Chars; %lld of %lld Bytes"), buf1, line_count_selected, (long)curbuf->b_ml.ml_line_count, word_count_cursor, word_count, @@ -7363,7 +7365,7 @@ cursor_pos_info(dict_T *dict) if (char_count_cursor == byte_count_cursor && char_count == byte_count) vim_snprintf((char *)IObuff, IOSIZE, - _("Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"), + _("Col %s of %s; Line %ld of %ld; Word %lld of %lld; Byte %lld of %lld"), (char *)buf1, (char *)buf2, (long)curwin->w_cursor.lnum, (long)curbuf->b_ml.ml_line_count, @@ -7371,7 +7373,7 @@ cursor_pos_info(dict_T *dict) byte_count_cursor, byte_count); else vim_snprintf((char *)IObuff, IOSIZE, - _("Col %s of %s; Line %ld of %ld; Word %ld of %ld; Char %ld of %ld; Byte %ld of %ld"), + _("Col %s of %s; Line %ld of %ld; Word %lld of %lld; Char %lld of %lld; Byte %lld of %lld"), (char *)buf1, (char *)buf2, (long)curwin->w_cursor.lnum, (long)curbuf->b_ml.ml_line_count, @@ -7399,19 +7401,19 @@ cursor_pos_info(dict_T *dict) #if defined(FEAT_EVAL) if (dict != NULL) { - dict_add_nr_str(dict, "words", (long)word_count, NULL); - dict_add_nr_str(dict, "chars", (long)char_count, NULL); - dict_add_nr_str(dict, "bytes", (long)byte_count + dict_add_nr_str(dict, "words", word_count, NULL); + dict_add_nr_str(dict, "chars", char_count, NULL); + dict_add_nr_str(dict, "bytes", byte_count # ifdef FEAT_MBYTE + bom_count # endif , NULL); dict_add_nr_str(dict, VIsual_active ? "visual_bytes" : "cursor_bytes", - (long)byte_count_cursor, NULL); + byte_count_cursor, NULL); dict_add_nr_str(dict, VIsual_active ? "visual_chars" : "cursor_chars", - (long)char_count_cursor, NULL); + char_count_cursor, NULL); dict_add_nr_str(dict, VIsual_active ? "visual_words" : "cursor_words", - (long)word_count_cursor, NULL); + word_count_cursor, NULL); } #endif } diff --git a/src/option.c b/src/option.c --- a/src/option.c +++ b/src/option.c @@ -4179,7 +4179,7 @@ do_set( int afterchar; /* character just after option name */ int len; int i; - long value; + varnumber_T value; int key; long_u flags; /* flags for current option */ char_u *varp = NULL; /* pointer to variable for current option */ @@ -9102,7 +9102,7 @@ get_option_value( if ((int *)varp == &curbuf->b_changed) *numval = curbufIsChanged(); else - *numval = *(int *)varp; + *numval = (long) *(varnumber_T *)varp; } return 1; } diff --git a/src/proto/charset.pro b/src/proto/charset.pro --- a/src/proto/charset.pro +++ b/src/proto/charset.pro @@ -52,7 +52,7 @@ char_u *skiptowhite(char_u *p); char_u *skiptowhite_esc(char_u *p); long getdigits(char_u **pp); int vim_isblankline(char_u *lbuf); -void vim_str2nr(char_u *start, int *prep, int *len, int what, long *nptr, unsigned long *unptr, int maxlen); +void vim_str2nr(char_u *start, int *prep, int *len, int what, varnumber_T *nptr, uvarnumber_T *unptr, int maxlen); int hex2nr(int c); int hexhex2nr(char_u *p); int rem_backslash(char_u *str); diff --git a/src/proto/eval.pro b/src/proto/eval.pro --- a/src/proto/eval.pro +++ b/src/proto/eval.pro @@ -19,12 +19,12 @@ char_u *eval_to_string_skip(char_u *arg, int skip_expr(char_u **pp); char_u *eval_to_string(char_u *arg, char_u **nextcmd, int convert); char_u *eval_to_string_safe(char_u *arg, char_u **nextcmd, int use_sandbox); -int eval_to_number(char_u *expr); +varnumber_T eval_to_number(char_u *expr); list_T *eval_spell_expr(char_u *badword, char_u *expr); int get_spellword(list_T *list, char_u **pp); typval_T *eval_expr(char_u *arg, char_u **nextcmd); int call_vim_function(char_u *func, int argc, char_u **argv, int safe, int str_arg_only, typval_T *rettv); -long call_func_retnr(char_u *func, int argc, char_u **argv, int safe); +varnumber_T call_func_retnr(char_u *func, int argc, char_u **argv, int safe); void *call_func_retstr(char_u *func, int argc, char_u **argv, int safe); void *call_func_retlist(char_u *func, int argc, char_u **argv, int safe); void *save_funccal(void); @@ -76,11 +76,11 @@ void dict_free(dict_T *d); dictitem_T *dictitem_alloc(char_u *key); void dictitem_free(dictitem_T *item); int dict_add(dict_T *d, dictitem_T *item); -int dict_add_nr_str(dict_T *d, char *key, long nr, char_u *str); +int dict_add_nr_str(dict_T *d, char *key, varnumber_T nr, char_u *str); int dict_add_list(dict_T *d, char *key, list_T *list); dictitem_T *dict_find(dict_T *d, char_u *key, int len); char_u *get_dict_string(dict_T *d, char_u *key, int save); -long get_dict_number(dict_T *d, char_u *key); +varnumber_T get_dict_number(dict_T *d, char_u *key); int string2float(char_u *text, float_T *value); char_u *get_function_name(expand_T *xp, int idx); char_u *get_expr_name(expand_T *xp, int idx); @@ -92,8 +92,8 @@ void mzscheme_call_vim(char_u *name, typ float_T vim_round(float_T f); long do_searchpair(char_u *spat, char_u *mpat, char_u *epat, int dir, char_u *skip, int flags, pos_T *match_pos, linenr_T lnum_stop, long time_limit); char_u *get_callback(typval_T *arg, partial_T **pp); -void set_vim_var_nr(int idx, long val); -long get_vim_var_nr(int idx); +void set_vim_var_nr(int idx, varnumber_T val); +varnumber_T get_vim_var_nr(int idx); char_u *get_vim_var_str(int idx); list_T *get_vim_var_list(int idx); void set_vim_var_char(int c); @@ -108,8 +108,8 @@ char_u *set_cmdarg(exarg_T *eap, char_u typval_T *alloc_tv(void); void free_tv(typval_T *varp); void clear_tv(typval_T *varp); -long get_tv_number(typval_T *varp); -long get_tv_number_chk(typval_T *varp, int *denote); +varnumber_T get_tv_number(typval_T *varp); +varnumber_T get_tv_number_chk(typval_T *varp, int *denote); char_u *get_tv_string(typval_T *varp); char_u *get_tv_string_buf(typval_T *varp, char_u *buf); char_u *get_tv_string_chk(typval_T *varp); diff --git a/src/quickfix.c b/src/quickfix.c --- a/src/quickfix.c +++ b/src/quickfix.c @@ -4377,11 +4377,11 @@ set_errorlist( continue; filename = get_dict_string(d, (char_u *)"filename", TRUE); - bufnum = get_dict_number(d, (char_u *)"bufnr"); - lnum = get_dict_number(d, (char_u *)"lnum"); - col = get_dict_number(d, (char_u *)"col"); - vcol = get_dict_number(d, (char_u *)"vcol"); - nr = get_dict_number(d, (char_u *)"nr"); + bufnum = (int)get_dict_number(d, (char_u *)"bufnr"); + lnum = (int)get_dict_number(d, (char_u *)"lnum"); + col = (int)get_dict_number(d, (char_u *)"col"); + vcol = (int)get_dict_number(d, (char_u *)"vcol"); + nr = (int)get_dict_number(d, (char_u *)"nr"); type = get_dict_string(d, (char_u *)"type", TRUE); pattern = get_dict_string(d, (char_u *)"pattern", TRUE); text = get_dict_string(d, (char_u *)"text", TRUE); diff --git a/src/structs.h b/src/structs.h --- a/src/structs.h +++ b/src/structs.h @@ -1111,11 +1111,29 @@ typedef struct hashtable_S typedef long_u hash_T; /* Type for hi_hash */ -#if VIM_SIZEOF_INT <= 3 /* use long if int is smaller than 32 bits */ -typedef long varnumber_T; +#ifdef FEAT_NUM64 +/* Use 64-bit Number. */ +# ifdef WIN3264 +typedef __int64 varnumber_T; +typedef unsigned __int64 uvarnumber_T; +# elif defined(HAVE_STDINT_H) +typedef int64_t varnumber_T; +typedef uint64_t uvarnumber_T; +# else +typedef long varnumber_T; +typedef unsigned long uvarnumber_T; +# endif #else -typedef int varnumber_T; +/* Use 32-bit Number. */ +# if VIM_SIZEOF_INT <= 3 /* use long if int is smaller than 32 bits */ +typedef long varnumber_T; +typedef unsigned long uvarnumber_T; +# else +typedef int varnumber_T; +typedef unsigned int uvarnumber_T; +# endif #endif + typedef double float_T; typedef struct listvar_S list_T; diff --git a/src/testdir/test_viml.vim b/src/testdir/test_viml.vim --- a/src/testdir/test_viml.vim +++ b/src/testdir/test_viml.vim @@ -1197,6 +1197,34 @@ func Test_echo_and_string() endfunc "------------------------------------------------------------------------------- +" Test 94: 64-bit Numbers {{{1 +"------------------------------------------------------------------------------- + +func Test_num64() + if !has('num64') + return + endif + + call assert_notequal( 4294967296, 0) + call assert_notequal(-4294967296, 0) + call assert_equal( 4294967296, 0xFFFFffff + 1) + call assert_equal(-4294967296, -0xFFFFffff - 1) + + call assert_equal( 9223372036854775807, 1 / 0) + call assert_equal(-9223372036854775807, -1 / 0) + call assert_equal(-9223372036854775808, 0 / 0) + + call assert_equal( 0x7FFFffffFFFFffff, float2nr( 1.0e150)) + call assert_equal(-0x7FFFffffFFFFffff, float2nr(-1.0e150)) + + let rng = range(0xFFFFffff, 0x100000001) + call assert_equal([0xFFFFffff, 0x100000000, 0x100000001], rng) + call assert_equal(0x100000001, max(rng)) + call assert_equal(0xFFFFffff, min(rng)) + call assert_equal(rng, sort(range(0x100000001, 0xFFFFffff, -1), 'N')) +endfunc + +"------------------------------------------------------------------------------- " Modelines {{{1 " vim: ts=8 sw=4 tw=80 fdm=marker " vim: fdt=substitute(substitute(foldtext(),\ '\\%(^+--\\)\\@<=\\(\\s*\\)\\(.\\{-}\\)\:\ \\%(\"\ \\)\\=\\(Test\ \\d*\\)\:\\s*',\ '\\3\ (\\2)\:\ \\1',\ \"\"),\ '\\(Test\\s*\\)\\(\\d\\)\\D\\@=',\ '\\1\ \\2',\ "") diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -455,6 +455,11 @@ static char *(features[]) = #else "-netbeans_intg", #endif +#ifdef FEAT_NUM64 + "+num64", +#else + "-num64", +#endif #ifdef FEAT_GUI_W32 # ifdef FEAT_OLE "+ole", @@ -754,6 +759,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1976, +/**/ 1975, /**/ 1974,