aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Dewar <seandewar@users.noreply.github.com>2021-05-22 19:44:53 +0100
committerSean Dewar <seandewar@users.noreply.github.com>2021-09-11 15:33:20 +0100
commit6617629ad6eceeb77d49633780a7213eeb17a2c9 (patch)
tree9788c7d628daf61d19466d64d1bdec9279b3dc39
parentdda977f5c4d2fc81a0582fbaec7a6397aaf7aebf (diff)
downloadrneovim-6617629ad6eceeb77d49633780a7213eeb17a2c9.tar.gz
rneovim-6617629ad6eceeb77d49633780a7213eeb17a2c9.tar.bz2
rneovim-6617629ad6eceeb77d49633780a7213eeb17a2c9.zip
vim-patch:8.1.2035: recognizing octal numbers is confusing
Problem: Recognizing octal numbers is confusing. Solution: Introduce scriptversion 4: do not use octal and allow for single quote inside numbers. https://github.com/vim/vim/commit/60a8de28d11595f4df0419ece8afa7d6accc9fbd :scriptversion is N/A. Cherry-pick Test_readfile_binary() from v8.1.0742. Note that this patch was missing vim_str2nr() changes, and so fails the tests; this was fixed in v8.1.2036.
-rw-r--r--runtime/doc/eval.txt7
-rw-r--r--src/nvim/charset.h4
-rw-r--r--src/nvim/eval.lua2
-rw-r--r--src/nvim/eval/funcs.c14
-rw-r--r--src/nvim/testdir/test_eval_stuff.vim36
-rw-r--r--src/nvim/testdir/test_functions.vim6
6 files changed, 49 insertions, 20 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 211774ad2d..cd449a5d34 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -2508,7 +2508,8 @@ stdpath({what}) String/List returns the standard path(s) for {w
str2float({expr}) Float convert String to Float
str2list({expr} [, {utf8}]) List convert each character of {expr} to
ASCII/UTF8 value
-str2nr({expr} [, {base}]) Number convert String to Number
+str2nr({expr} [, {base} [, {quoted}]])
+ Number convert String to Number
strchars({expr} [, {skipcc}]) Number character length of the String {expr}
strcharpart({str}, {start} [, {len}])
String {len} characters of {str} at
@@ -8637,9 +8638,11 @@ str2list({expr} [, {utf8}]) *str2list()*
< Can also be used as a |method|: >
GetString()->str2list()
-str2nr({expr} [, {base}]) *str2nr()*
+str2nr({expr} [, {base} [, {quoted}]]) *str2nr()*
Convert string {expr} to a number.
{base} is the conversion base, it can be 2, 8, 10 or 16.
+ When {quoted} is present and non-zero then embedded single
+ quotes are ignored, thus "1'000'000" is a million.
When {base} is omitted base 10 is used. This also means that
a leading zero doesn't cause octal conversion to be used, as
diff --git a/src/nvim/charset.h b/src/nvim/charset.h
index e657ce19b6..b5f1f8506b 100644
--- a/src/nvim/charset.h
+++ b/src/nvim/charset.h
@@ -27,9 +27,11 @@ typedef enum {
///
/// STR2NR_FORCE|STR2NR_DEC is actually not different from supplying zero
/// as flags, but still present for completeness.
- STR2NR_FORCE = (1 << 3),
+ STR2NR_FORCE = (1 << 7),
/// Recognize all formats vim_str2nr() can recognize.
STR2NR_ALL = STR2NR_BIN | STR2NR_OCT | STR2NR_HEX,
+ STR2NR_NO_OCT = STR2NR_BIN | STR2NR_HEX, ///< Disallow octal numbers.
+ STR2NR_QUOTE = (1 << 4), ///< Ignore embedded single quotes.
} ChStr2NrFlags;
#ifdef INCLUDE_GENERATED_DECLARATIONS
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
index faff29b268..a7242ba73a 100644
--- a/src/nvim/eval.lua
+++ b/src/nvim/eval.lua
@@ -344,7 +344,7 @@ return {
stdpath={args=1},
str2float={args=1, base=1},
str2list={args={1, 2}, base=1},
- str2nr={args={1, 2}},
+ str2nr={args={1, 3}},
strcharpart={args={2, 3}},
strchars={args={1,2}},
strdisplaywidth={args={1, 2}},
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index 519b268bd1..61f535e32e 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -9998,7 +9998,7 @@ static void f_str2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int base = 10;
varnumber_T n;
- int what;
+ int what = 0;
if (argvars[1].v_type != VAR_UNKNOWN) {
base = tv_get_number(&argvars[1]);
@@ -10006,6 +10006,9 @@ static void f_str2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
EMSG(_(e_invarg));
return;
}
+ if (argvars[2].v_type != VAR_UNKNOWN && tv_get_number(&argvars[2])) {
+ what |= STR2NR_QUOTE;
+ }
}
char_u *p = skipwhite((const char_u *)tv_get_string(&argvars[0]));
@@ -10015,20 +10018,17 @@ static void f_str2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
switch (base) {
case 2: {
- what = STR2NR_BIN | STR2NR_FORCE;
+ what |= STR2NR_BIN | STR2NR_FORCE;
break;
}
case 8: {
- what = STR2NR_OCT | STR2NR_FORCE;
+ what |= STR2NR_OCT | STR2NR_FORCE;
break;
}
case 16: {
- what = STR2NR_HEX | STR2NR_FORCE;
+ what |= STR2NR_HEX | STR2NR_FORCE;
break;
}
- default: {
- what = 0;
- }
}
vim_str2nr(p, NULL, NULL, what, &n, NULL, 0, false);
// Text after the number is silently ignored.
diff --git a/src/nvim/testdir/test_eval_stuff.vim b/src/nvim/testdir/test_eval_stuff.vim
index 4870b9a60a..084c856ba0 100644
--- a/src/nvim/testdir/test_eval_stuff.vim
+++ b/src/nvim/testdir/test_eval_stuff.vim
@@ -33,6 +33,24 @@ func Test_for_invalid()
redraw
endfunc
+func Test_readfile_binary()
+ new
+ call setline(1, ['one', 'two', 'three'])
+ setlocal ff=dos
+ silent write XReadfile
+ let lines = readfile('XReadfile')
+ call assert_equal(['one', 'two', 'three'], lines)
+ let lines = readfile('XReadfile', '', 2)
+ call assert_equal(['one', 'two'], lines)
+ let lines = readfile('XReadfile', 'b')
+ call assert_equal(["one\r", "two\r", "three\r", ""], lines)
+ let lines = readfile('XReadfile', 'b', 2)
+ call assert_equal(["one\r", "two\r"], lines)
+
+ bwipe!
+ call delete('XReadfile')
+endfunc
+
func Test_mkdir_p()
call mkdir('Xmkdir/nested', 'p')
call assert_true(isdirectory('Xmkdir/nested'))
@@ -90,6 +108,15 @@ func Test_string_concatenation()
call assert_equal('ab', a)
endfunc
+" Test fix for issue #4507
+func Test_skip_after_throw()
+ try
+ throw 'something'
+ let x = wincol() || &ts
+ catch /something/
+ endtry
+endfunc
+
func Test_nocatch_restore_silent_emsg()
silent! try
throw 1
@@ -111,15 +138,6 @@ func Test_let_errmsg()
let v:errmsg = ''
endfunc
-" Test fix for issue #4507
-func Test_skip_after_throw()
- try
- throw 'something'
- let x = wincol() || &ts
- catch /something/
- endtry
-endfunc
-
func Test_number_max_min_size()
" This will fail on systems without 64 bit number support or when not
" configured correctly.
diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim
index 6cb3e24201..a78e617572 100644
--- a/src/nvim/testdir/test_functions.vim
+++ b/src/nvim/testdir/test_functions.vim
@@ -161,6 +161,12 @@ func Test_str2nr()
call assert_equal(11259375, str2nr('0XABCDEF', 16))
call assert_equal(-11259375, str2nr('-0xABCDEF', 16))
+ call assert_equal(1, str2nr("1'000'000", 10, 0))
+ call assert_equal(256, str2nr("1'0000'0000", 2, 1))
+ call assert_equal(262144, str2nr("1'000'000", 8, 1))
+ call assert_equal(1000000, str2nr("1'000'000", 10, 1))
+ call assert_equal(65536, str2nr("1'00'00", 16, 1))
+
call assert_equal(0, str2nr('0x10'))
call assert_equal(0, str2nr('0b10'))
call assert_equal(1, str2nr('12', 2))