summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2020-02-22 14:27:04 +0100
committerBram Moolenaar <Bram@vim.org>2020-02-22 14:27:04 +0100
commitf9706e9df0e37d214fb08eda30ba29627e97a607 (patch)
tree9d90ad2977ed759664a2c2d0776901f34a8e0350
parentc036e87bd7001238ab7cc5d9e30e59bbf989a5fd (diff)
patch 8.2.0296: mixing up "long long" and __int64 may cause problemsv8.2.0296
Problem: Mixing up "long long" and __int64 may cause problems. (John Marriott) Solution: Pass varnumber_T to vim_snprintf(). Add v:numbersize.
-rw-r--r--runtime/doc/eval.txt7
-rw-r--r--runtime/doc/various.txt6
-rw-r--r--src/eval.c2
-rw-r--r--src/evalvars.c4
-rw-r--r--src/fileio.c4
-rw-r--r--src/json.c2
-rw-r--r--src/message.c14
-rw-r--r--src/ops.c44
-rw-r--r--src/structs.h52
-rw-r--r--src/testdir/test_eval_stuff.vim6
-rw-r--r--src/version.c2
-rw-r--r--src/vim.h61
12 files changed, 108 insertions, 96 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 62a73048b7..4349e76ef5 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -48,8 +48,7 @@ There are ten types of variables:
*Number* *Integer*
Number A 32 or 64 bit signed number. |expr-number|
- 64-bit Numbers are available only when compiled with the
- |+num64| feature.
+ The number of bits is available in |v:numbersize|.
Examples: -123 0x10 0177 0b1011
Float A floating point number. |floating-point-format| *Float*
@@ -1991,6 +1990,10 @@ v:null An empty String. Used to put "null" in JSON. See
That is so that eval() can parse the string back to the same
value. Read-only.
+ *v:numbersize* *numbersize-variable*
+v:numbersize Number of bits in a Number. This is normally 64, but on some
+ systems it my be 32.
+
*v:oldfiles* *oldfiles-variable*
v:oldfiles List of file names that is loaded from the |viminfo| file on
startup. These are the files that Vim remembers marks for.
diff --git a/runtime/doc/various.txt b/runtime/doc/various.txt
index 85e18b3f62..547ca762af 100644
--- a/runtime/doc/various.txt
+++ b/runtime/doc/various.txt
@@ -1,4 +1,4 @@
-*various.txt* For Vim version 8.2. Last change: 2019 Dec 07
+*various.txt* For Vim version 8.2. Last change: 2020 Feb 22
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -407,7 +407,9 @@ N *+multi_lang* non-English language support |multi-lang|
m *+mzscheme* Mzscheme interface |mzscheme|
m *+mzscheme/dyn* Mzscheme interface |mzscheme-dynamic| |/dyn|
m *+netbeans_intg* |netbeans|
- *+num64* 64-bit Number support |Number|
+ *+num64* 64-bit Number support |Number|
+ Always enabled since 8.2.0271, use v:numbersize to
+ check the actual size of a 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/eval.c b/src/eval.c
index f01724389d..dcaf2f02cc 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -5665,7 +5665,7 @@ tv_get_string_buf_chk(typval_T *varp, char_u *buf)
{
case VAR_NUMBER:
vim_snprintf((char *)buf, NUMBUFLEN, "%lld",
- (long_long_T)varp->vval.v_number);
+ (varnumber_T)varp->vval.v_number);
return buf;
case VAR_FUNC:
case VAR_PARTIAL:
diff --git a/src/evalvars.c b/src/evalvars.c
index 2bbc3553b6..25d23c8606 100644
--- a/src/evalvars.c
+++ b/src/evalvars.c
@@ -120,8 +120,9 @@ static struct vimvar
{VV_NAME("errors", VAR_LIST), 0},
{VV_NAME("false", VAR_BOOL), VV_RO},
{VV_NAME("true", VAR_BOOL), VV_RO},
- {VV_NAME("null", VAR_SPECIAL), VV_RO},
{VV_NAME("none", VAR_SPECIAL), VV_RO},
+ {VV_NAME("null", VAR_SPECIAL), VV_RO},
+ {VV_NAME("numbersize", VAR_NUMBER), VV_RO},
{VV_NAME("vim_did_enter", VAR_NUMBER), VV_RO},
{VV_NAME("testing", VAR_NUMBER), 0},
{VV_NAME("t_number", VAR_NUMBER), VV_RO},
@@ -229,6 +230,7 @@ evalvars_init(void)
set_vim_var_nr(VV_TRUE, VVAL_TRUE);
set_vim_var_nr(VV_NONE, VVAL_NONE);
set_vim_var_nr(VV_NULL, VVAL_NULL);
+ set_vim_var_nr(VV_NUMBERSIZE, sizeof(varnumber_T) * 8);
set_vim_var_nr(VV_TYPE_NUMBER, VAR_TYPE_NUMBER);
set_vim_var_nr(VV_TYPE_STRING, VAR_TYPE_STRING);
diff --git a/src/fileio.c b/src/fileio.c
index 575efafd24..e80009fbe1 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -3016,14 +3016,14 @@ msg_add_lines(
*p++ = ' ';
if (shortmess(SHM_LINES))
vim_snprintf((char *)p, IOSIZE - (p - IObuff),
- "%ldL, %lldC", lnum, (long_long_T)nchars);
+ "%ldL, %lldC", lnum, (varnumber_T)nchars);
else
{
sprintf((char *)p, NGETTEXT("%ld line, ", "%ld lines, ", lnum), lnum);
p += STRLEN(p);
vim_snprintf((char *)p, IOSIZE - (p - IObuff),
NGETTEXT("%lld character", "%lld characters", nchars),
- (long_long_T)nchars);
+ (varnumber_T)nchars);
}
}
diff --git a/src/json.c b/src/json.c
index bfa5d50ddb..770e144398 100644
--- a/src/json.c
+++ b/src/json.c
@@ -215,7 +215,7 @@ json_encode_item(garray_T *gap, typval_T *val, int copyID, int options)
case VAR_NUMBER:
vim_snprintf((char *)numbuf, NUMBUFLEN, "%lld",
- (long_long_T)val->vval.v_number);
+ (varnumber_T)val->vval.v_number);
ga_concat(gap, numbuf);
break;
diff --git a/src/message.c b/src/message.c
index 9ab0eaefeb..c2855fb34b 100644
--- a/src/message.c
+++ b/src/message.c
@@ -4129,7 +4129,7 @@ infinity_str(int positive,
* Limited support for floating point was added: 'f', 'F', 'e', 'E', 'g', 'G'.
*
* Length modifiers 'h' (short int) and 'l' (long int) and 'll' (long long int)
- * are supported.
+ * are supported. NOTE: for 'll' the argument is varnumber_T or uvarnumber_T.
*
* The locale is not used, the string is used as a byte string. This is only
* relevant for double-byte encodings where the second byte may be '%'.
@@ -4371,7 +4371,7 @@ vim_vsnprintf_typval(
p++;
if (length_modifier == 'l' && *p == 'l')
{
- // double l = long long
+ // double l = __int64 / varnumber_T
length_modifier = 'L';
p++;
}
@@ -4501,20 +4501,20 @@ vim_vsnprintf_typval(
// argument is never negative)
int arg_sign = 0;
- // only defined for length modifier h, or for no
- // length modifiers
+ // only set for length modifier h, or for no length
+ // modifiers
int int_arg = 0;
unsigned int uint_arg = 0;
- // only defined for length modifier l
+ // only set for length modifier l
long int long_arg = 0;
unsigned long int ulong_arg = 0;
- // only defined for length modifier ll
+ // only set for length modifier ll
varnumber_T llong_arg = 0;
uvarnumber_T ullong_arg = 0;
- // only defined for b conversion
+ // only set for b conversion
uvarnumber_T bin_arg = 0;
// pointer argument value -only defined for p
diff --git a/src/ops.c b/src/ops.c
index 6a6abf7837..d4b842c601 100644
--- a/src/ops.c
+++ b/src/ops.c
@@ -3364,17 +3364,13 @@ do_addsub(
buf2[i] = '\0';
}
else if (pre == 0)
- vim_snprintf((char *)buf2, NUMBUFLEN, "%llu",
- (long_long_u_T)n);
+ vim_snprintf((char *)buf2, NUMBUFLEN, "%llu", (uvarnumber_T)n);
else if (pre == '0')
- vim_snprintf((char *)buf2, NUMBUFLEN, "%llo",
- (long_long_u_T)n);
+ vim_snprintf((char *)buf2, NUMBUFLEN, "%llo", (uvarnumber_T)n);
else if (pre && hexupper)
- vim_snprintf((char *)buf2, NUMBUFLEN, "%llX",
- (long_long_u_T)n);
+ vim_snprintf((char *)buf2, NUMBUFLEN, "%llX", (uvarnumber_T)n);
else
- vim_snprintf((char *)buf2, NUMBUFLEN, "%llx",
- (long_long_u_T)n);
+ vim_snprintf((char *)buf2, NUMBUFLEN, "%llx", (uvarnumber_T)n);
length -= (int)STRLEN(buf2);
/*
@@ -3773,21 +3769,21 @@ cursor_pos_info(dict_T *dict)
_("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,
- (long_long_T)word_count_cursor,
- (long_long_T)word_count,
- (long_long_T)byte_count_cursor,
- (long_long_T)byte_count);
+ (varnumber_T)word_count_cursor,
+ (varnumber_T)word_count,
+ (varnumber_T)byte_count_cursor,
+ (varnumber_T)byte_count);
else
vim_snprintf((char *)IObuff, IOSIZE,
_("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,
- (long_long_T)word_count_cursor,
- (long_long_T)word_count,
- (long_long_T)char_count_cursor,
- (long_long_T)char_count,
- (long_long_T)byte_count_cursor,
- (long_long_T)byte_count);
+ (varnumber_T)word_count_cursor,
+ (varnumber_T)word_count,
+ (varnumber_T)char_count_cursor,
+ (varnumber_T)char_count,
+ (varnumber_T)byte_count_cursor,
+ (varnumber_T)byte_count);
}
else
{
@@ -3805,17 +3801,17 @@ cursor_pos_info(dict_T *dict)
(char *)buf1, (char *)buf2,
(long)curwin->w_cursor.lnum,
(long)curbuf->b_ml.ml_line_count,
- (long_long_T)word_count_cursor, (long_long_T)word_count,
- (long_long_T)byte_count_cursor, (long_long_T)byte_count);
+ (varnumber_T)word_count_cursor, (varnumber_T)word_count,
+ (varnumber_T)byte_count_cursor, (varnumber_T)byte_count);
else
vim_snprintf((char *)IObuff, IOSIZE,
_("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,
- (long_long_T)word_count_cursor, (long_long_T)word_count,
- (long_long_T)char_count_cursor, (long_long_T)char_count,
- (long_long_T)byte_count_cursor, (long_long_T)byte_count);
+ (varnumber_T)word_count_cursor, (varnumber_T)word_count,
+ (varnumber_T)char_count_cursor, (varnumber_T)char_count,
+ (varnumber_T)byte_count_cursor, (varnumber_T)byte_count);
}
}
@@ -3825,7 +3821,7 @@ cursor_pos_info(dict_T *dict)
size_t len = STRLEN(IObuff);
vim_snprintf((char *)IObuff + len, IOSIZE - len,
- _("(+%lld for BOM)"), (long_long_T)bom_count);
+ _("(+%lld for BOM)"), (varnumber_T)bom_count);
}
if (dict == NULL)
{
diff --git a/src/structs.h b/src/structs.h
index 823dfda3ca..4b70641711 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -1248,30 +1248,40 @@ typedef long_u hash_T; // Type for hi_hash
// Use 64-bit Number.
#ifdef MSWIN
# ifdef PROTO
-typedef long varnumber_T;
-typedef unsigned long uvarnumber_T;
-# define VARNUM_MIN LONG_MIN
-# define VARNUM_MAX LONG_MAX
-# define UVARNUM_MAX ULONG_MAX
+ // workaround for cproto that doesn't recognize __int64
+ typedef long varnumber_T;
+ typedef unsigned long uvarnumber_T;
+# define VARNUM_MIN LONG_MIN
+# define VARNUM_MAX LONG_MAX
+# define UVARNUM_MAX ULONG_MAX
# else
-typedef __int64 varnumber_T;
-typedef unsigned __int64 uvarnumber_T;
-# define VARNUM_MIN _I64_MIN
-# define VARNUM_MAX _I64_MAX
-# define UVARNUM_MAX _UI64_MAX
+ typedef __int64 varnumber_T;
+ typedef unsigned __int64 uvarnumber_T;
+# define VARNUM_MIN _I64_MIN
+# define VARNUM_MAX _I64_MAX
+# define UVARNUM_MAX _UI64_MAX
+# endif
+#elif defined(HAVE_NO_LONG_LONG)
+# if defined(HAVE_STDINT_H)
+ typedef int64_t varnumber_T;
+ typedef uint64_t uvarnumber_T;
+# define VARNUM_MIN INT64_MIN
+# define VARNUM_MAX INT64_MAX
+# define UVARNUM_MAX UINT64_MAX
+# else
+ // this may cause trouble for code that depends on 64 bit ints
+ typedef long varnumber_T;
+ typedef unsigned long uvarnumber_T;
+# define VARNUM_MIN LONG_MIN
+# define VARNUM_MAX LONG_MAX
+# define UVARNUM_MAX ULONG_MAX
# endif
-#elif defined(HAVE_STDINT_H)
-typedef int64_t varnumber_T;
-typedef uint64_t uvarnumber_T;
-# define VARNUM_MIN INT64_MIN
-# define VARNUM_MAX INT64_MAX
-# define UVARNUM_MAX UINT64_MAX
#else
-typedef long varnumber_T;
-typedef unsigned long uvarnumber_T;
-# define VARNUM_MIN LONG_MIN
-# define VARNUM_MAX LONG_MAX
-# define UVARNUM_MAX ULONG_MAX
+ typedef long long varnumber_T;
+ typedef unsigned long long uvarnumber_T;
+# define VARNUM_MIN LLONG_MIN
+# define VARNUM_MAX LLONG_MAX
+# define UVARNUM_MAX ULLONG_MAX
#endif
typedef double float_T;
diff --git a/src/testdir/test_eval_stuff.vim b/src/testdir/test_eval_stuff.vim
index 53627557a0..b691192b4b 100644
--- a/src/testdir/test_eval_stuff.vim
+++ b/src/testdir/test_eval_stuff.vim
@@ -228,3 +228,9 @@ func Test_excute_null()
call assert_fails('execute test_null_channel()', 'E908:')
endif
endfunc
+
+func Test_numbersize()
+ " This will fail on systems without 64 bit int support or when not configured
+ " correctly.
+ call assert_equal(64, v:numbersize)
+endfunc
diff --git a/src/version.c b/src/version.c
index 4b186bfee0..5eb0d05c98 100644
--- a/src/version.c
+++ b/src/version.c
@@ -739,6 +739,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 296,
+/**/
295,
/**/
294,
diff --git a/src/vim.h b/src/vim.h
index 62cc46cd03..4d3ac36633 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -328,16 +328,6 @@ typedef unsigned char char_u;
typedef unsigned short short_u;
typedef unsigned int int_u;
-// Older systems do not have support for long long
-// use a typedef instead of hard-coded long long
-#ifdef HAVE_NO_LONG_LONG
- typedef long long_long_T;
- typedef long unsigned long_long_u_T;
-#else
- typedef long long long_long_T;
- typedef long long unsigned long_long_u_T;
-#endif
-
// Make sure long_u is big enough to hold a pointer.
// On Win64, longs are 32 bits and pointers are 64 bits.
// For printf() and scanf(), we need to take care of long_u specifically.
@@ -1975,31 +1965,32 @@ typedef int sock_T;
#define VV_ERRORS 67
#define VV_FALSE 68
#define VV_TRUE 69
-#define VV_NULL 70
-#define VV_NONE 71
-#define VV_VIM_DID_ENTER 72
-#define VV_TESTING 73
-#define VV_TYPE_NUMBER 74
-#define VV_TYPE_STRING 75
-#define VV_TYPE_FUNC 76
-#define VV_TYPE_LIST 77
-#define VV_TYPE_DICT 78
-#define VV_TYPE_FLOAT 79
-#define VV_TYPE_BOOL 80
-#define VV_TYPE_NONE 81
-#define VV_TYPE_JOB 82
-#define VV_TYPE_CHANNEL 83
-#define VV_TYPE_BLOB 84
-#define VV_TERMRFGRESP 85
-#define VV_TERMRBGRESP 86
-#define VV_TERMU7RESP 87
-#define VV_TERMSTYLERESP 88
-#define VV_TERMBLINKRESP 89
-#define VV_EVENT 90
-#define VV_VERSIONLONG 91
-#define VV_ECHOSPACE 92
-#define VV_ARGV 93
-#define VV_LEN 94 // number of v: vars
+#define VV_NONE 70
+#define VV_NULL 71
+#define VV_NUMBERSIZE 72
+#define VV_VIM_DID_ENTER 73
+#define VV_TESTING 74
+#define VV_TYPE_NUMBER 75
+#define VV_TYPE_STRING 76
+#define VV_TYPE_FUNC 77
+#define VV_TYPE_LIST 78
+#define VV_TYPE_DICT 79
+#define VV_TYPE_FLOAT 80
+#define VV_TYPE_BOOL 81
+#define VV_TYPE_NONE 82
+#define VV_TYPE_JOB 83
+#define VV_TYPE_CHANNEL 84
+#define VV_TYPE_BLOB 85
+#define VV_TERMRFGRESP 86
+#define VV_TERMRBGRESP 87
+#define VV_TERMU7RESP 88
+#define VV_TERMSTYLERESP 89
+#define VV_TERMBLINKRESP 90
+#define VV_EVENT 91
+#define VV_VERSIONLONG 92
+#define VV_ECHOSPACE 93
+#define VV_ARGV 94
+#define VV_LEN 95 // number of v: vars
// used for v_number in VAR_BOOL and VAR_SPECIAL
#define VVAL_FALSE 0L // VAR_BOOL