To: vim_dev@googlegroups.com Subject: Patch 8.2.0296 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.0296 Problem: Mixing up "long long" and __int64 may cause problems. (John Marriott) Solution: Pass varnumber_T to vim_snprintf(). Add v:numbersize. Files: src/message.c, src/eval.c, src/fileio.c, src/json.c, src/ops.c, src/vim.h, src/structs.h, src/evalvars.c, runtime/doc/eval.txt, runtime/doc/various.txt, src/testdir/test_eval_stuff.vim *** ../vim-8.2.0295/src/message.c 2020-02-17 22:11:39.666644199 +0100 --- src/message.c 2020-02-22 13:48:59.926745359 +0100 *************** *** 4129,4135 **** * 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. * * 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 '%'. --- 4129,4135 ---- * 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. 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,4377 **** p++; if (length_modifier == 'l' && *p == 'l') { ! // double l = long long length_modifier = 'L'; p++; } --- 4371,4377 ---- p++; if (length_modifier == 'l' && *p == 'l') { ! // double l = __int64 / varnumber_T length_modifier = 'L'; p++; } *************** *** 4501,4520 **** // argument is never negative) int arg_sign = 0; ! // only defined for length modifier h, or for no ! // length modifiers int int_arg = 0; unsigned int uint_arg = 0; ! // only defined for length modifier l long int long_arg = 0; unsigned long int ulong_arg = 0; ! // only defined for length modifier ll varnumber_T llong_arg = 0; uvarnumber_T ullong_arg = 0; ! // only defined for b conversion uvarnumber_T bin_arg = 0; // pointer argument value -only defined for p --- 4501,4520 ---- // argument is never negative) int arg_sign = 0; ! // only set for length modifier h, or for no length ! // modifiers int int_arg = 0; unsigned int uint_arg = 0; ! // only set for length modifier l long int long_arg = 0; unsigned long int ulong_arg = 0; ! // only set for length modifier ll varnumber_T llong_arg = 0; uvarnumber_T ullong_arg = 0; ! // only set for b conversion uvarnumber_T bin_arg = 0; // pointer argument value -only defined for p *** ../vim-8.2.0295/src/eval.c 2020-01-27 22:09:35.796838619 +0100 --- src/eval.c 2020-02-22 13:42:31.772357764 +0100 *************** *** 5665,5671 **** { case VAR_NUMBER: vim_snprintf((char *)buf, NUMBUFLEN, "%lld", ! (long_long_T)varp->vval.v_number); return buf; case VAR_FUNC: case VAR_PARTIAL: --- 5665,5671 ---- { case VAR_NUMBER: vim_snprintf((char *)buf, NUMBUFLEN, "%lld", ! (varnumber_T)varp->vval.v_number); return buf; case VAR_FUNC: case VAR_PARTIAL: *** ../vim-8.2.0295/src/fileio.c 2020-02-04 22:32:56.310097798 +0100 --- src/fileio.c 2020-02-22 13:43:06.000214036 +0100 *************** *** 3016,3029 **** *p++ = ' '; if (shortmess(SHM_LINES)) vim_snprintf((char *)p, IOSIZE - (p - IObuff), ! "%ldL, %lldC", lnum, (long_long_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); } } --- 3016,3029 ---- *p++ = ' '; if (shortmess(SHM_LINES)) vim_snprintf((char *)p, IOSIZE - (p - IObuff), ! "%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), ! (varnumber_T)nchars); } } *** ../vim-8.2.0295/src/json.c 2020-01-27 22:09:35.796838619 +0100 --- src/json.c 2020-02-22 13:43:41.556065131 +0100 *************** *** 215,221 **** case VAR_NUMBER: vim_snprintf((char *)numbuf, NUMBUFLEN, "%lld", ! (long_long_T)val->vval.v_number); ga_concat(gap, numbuf); break; --- 215,221 ---- case VAR_NUMBER: vim_snprintf((char *)numbuf, NUMBUFLEN, "%lld", ! (varnumber_T)val->vval.v_number); ga_concat(gap, numbuf); break; *** ../vim-8.2.0295/src/ops.c 2020-01-26 21:59:25.628718127 +0100 --- src/ops.c 2020-02-22 13:46:05.851464333 +0100 *************** *** 3364,3380 **** buf2[i] = '\0'; } else if (pre == 0) ! vim_snprintf((char *)buf2, NUMBUFLEN, "%llu", ! (long_long_u_T)n); else if (pre == '0') ! vim_snprintf((char *)buf2, NUMBUFLEN, "%llo", ! (long_long_u_T)n); else if (pre && hexupper) ! vim_snprintf((char *)buf2, NUMBUFLEN, "%llX", ! (long_long_u_T)n); else ! vim_snprintf((char *)buf2, NUMBUFLEN, "%llx", ! (long_long_u_T)n); length -= (int)STRLEN(buf2); /* --- 3364,3376 ---- buf2[i] = '\0'; } else if (pre == 0) ! vim_snprintf((char *)buf2, NUMBUFLEN, "%llu", (uvarnumber_T)n); else if (pre == '0') ! vim_snprintf((char *)buf2, NUMBUFLEN, "%llo", (uvarnumber_T)n); else if (pre && hexupper) ! vim_snprintf((char *)buf2, NUMBUFLEN, "%llX", (uvarnumber_T)n); else ! vim_snprintf((char *)buf2, NUMBUFLEN, "%llx", (uvarnumber_T)n); length -= (int)STRLEN(buf2); /* *************** *** 3773,3793 **** _("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); 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); } else { --- 3769,3789 ---- _("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, ! (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, ! (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,3821 **** (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); 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); } } --- 3801,3817 ---- (char *)buf1, (char *)buf2, (long)curwin->w_cursor.lnum, (long)curbuf->b_ml.ml_line_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, ! (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,3831 **** size_t len = STRLEN(IObuff); vim_snprintf((char *)IObuff + len, IOSIZE - len, ! _("(+%lld for BOM)"), (long_long_T)bom_count); } if (dict == NULL) { --- 3821,3827 ---- size_t len = STRLEN(IObuff); vim_snprintf((char *)IObuff + len, IOSIZE - len, ! _("(+%lld for BOM)"), (varnumber_T)bom_count); } if (dict == NULL) { *** ../vim-8.2.0295/src/vim.h 2020-02-12 21:15:37.543497435 +0100 --- src/vim.h 2020-02-22 14:15:18.991628742 +0100 *************** *** 328,343 **** 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. --- 328,333 ---- *************** *** 1975,2005 **** #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 // used for v_number in VAR_BOOL and VAR_SPECIAL #define VVAL_FALSE 0L // VAR_BOOL --- 1965,1996 ---- #define VV_ERRORS 67 #define VV_FALSE 68 #define VV_TRUE 69 ! #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 *** ../vim-8.2.0295/src/structs.h 2020-02-17 22:11:39.666644199 +0100 --- src/structs.h 2020-02-22 14:08:48.457306883 +0100 *************** *** 1248,1277 **** // 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 # 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 # 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 #endif typedef double float_T; --- 1248,1287 ---- // Use 64-bit Number. #ifdef MSWIN # ifdef PROTO ! // 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 ! # 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 #else ! 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; *** ../vim-8.2.0295/src/evalvars.c 2020-02-03 20:50:55.672929674 +0100 --- src/evalvars.c 2020-02-22 14:16:29.783327780 +0100 *************** *** 120,127 **** {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("vim_did_enter", VAR_NUMBER), VV_RO}, {VV_NAME("testing", VAR_NUMBER), 0}, {VV_NAME("t_number", VAR_NUMBER), VV_RO}, --- 120,128 ---- {VV_NAME("errors", VAR_LIST), 0}, {VV_NAME("false", VAR_BOOL), VV_RO}, {VV_NAME("true", VAR_BOOL), 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,234 **** --- 230,236 ---- 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); *** ../vim-8.2.0295/runtime/doc/eval.txt 2020-02-14 16:52:08.315436441 +0100 --- runtime/doc/eval.txt 2020-02-22 14:13:14.248161133 +0100 *************** *** 48,55 **** *Number* *Integer* Number A 32 or 64 bit signed number. |expr-number| ! 64-bit Numbers are available only when compiled with the ! |+num64| feature. Examples: -123 0x10 0177 0b1011 Float A floating point number. |floating-point-format| *Float* --- 48,54 ---- *Number* *Integer* Number A 32 or 64 bit signed number. |expr-number| ! The number of bits is available in |v:numbersize|. Examples: -123 0x10 0177 0b1011 Float A floating point number. |floating-point-format| *Float* *************** *** 1989,1994 **** --- 1990,1999 ---- 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. *** ../vim-8.2.0295/runtime/doc/various.txt 2019-12-12 12:49:07.000000000 +0100 --- runtime/doc/various.txt 2020-02-22 14:20:07.422406507 +0100 *************** *** 407,413 **** 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' --- 407,415 ---- m *+mzscheme* Mzscheme interface |mzscheme| m *+mzscheme/dyn* Mzscheme interface |mzscheme-dynamic| |/dyn| m *+netbeans_intg* |netbeans| ! *+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' *************** *** 702,709 **** :5sleep "sleep for five seconds :sleep 100m "sleep for a hundred milliseconds 10gs "sleep for ten seconds ! < Can be interrupted with CTRL-C (CTRL-Break on MS-DOS). ! "gs" stands for "goto sleep". While sleeping the cursor is positioned in the text, if at a visible position. Also process the received netbeans messages. {only --- 704,711 ---- :5sleep "sleep for five seconds :sleep 100m "sleep for a hundred milliseconds 10gs "sleep for ten seconds ! < Can be interrupted with CTRL-C (CTRL-Break on ! MS-Windows). "gs" stands for "goto sleep". While sleeping the cursor is positioned in the text, if at a visible position. Also process the received netbeans messages. {only *** ../vim-8.2.0295/src/testdir/test_eval_stuff.vim 2020-01-08 20:08:55.602187006 +0100 --- src/testdir/test_eval_stuff.vim 2020-02-22 14:18:56.394706604 +0100 *************** *** 228,230 **** --- 228,236 ---- 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 *** ../vim-8.2.0295/src/version.c 2020-02-21 21:30:33.871979710 +0100 --- src/version.c 2020-02-22 14:15:36.227555397 +0100 *************** *** 740,741 **** --- 740,743 ---- { /* Add new patch number below this line */ + /**/ + 296, /**/ -- From "know your smileys": :-E Has major dental problems /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///