aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSean Dewar <seandewar@users.noreply.github.com>2021-06-03 01:55:18 +0100
committerSean Dewar <seandewar@users.noreply.github.com>2021-09-11 15:36:03 +0100
commit90a4cf92d21b730fea7099fb3e12a9ef791a1a57 (patch)
treec342ec4595fd613430bff9e7a6924c7ee3291c71 /src
parent10018958d860780c3766f4e785710201c07f3684 (diff)
downloadrneovim-90a4cf92d21b730fea7099fb3e12a9ef791a1a57.tar.gz
rneovim-90a4cf92d21b730fea7099fb3e12a9ef791a1a57.tar.bz2
rneovim-90a4cf92d21b730fea7099fb3e12a9ef791a1a57.zip
vim-patch:8.2.0886: cannot use octal numbers in scriptversion 4
Problem: Cannot use octal numbers in scriptversion 4. Solution: Add the "0o" notation. (Ken Takata, closes vim/vim#5304) https://github.com/vim/vim/commit/c17e66c5c0acd5038f1eb3d7b3049b64bb6ea30b :scriptversion is N/A. Cherry-pick latest str2nr() doc changes from v8.1.2035. Cherry-pick various mentions of the 0o prefix from: - v8.2.2324 - https://github.com/vim/vim/commit/2346a6378483c9871016f9fc821ec5cbea638f13 - https://github.com/vim/vim/commit/11e3c5ba820325b69cb56f70e13c21d7b8808d33 - https://github.com/vim/vim/commit/82be4849eed0b8fbee45bc8da99b685ec89af59a Patch used ascii_isbdigit() by mistake, which was fixed in v8.2.2309. Make STR2NR_OOCT work the same as STR2NR_OCT when forcing. In Vim, STR2NR_FORCE | STR2NR_OOCT isn't handled, and doesn't actually force anything. Rather than abort(), make it work as STR2NR_OCT. This means STR2NR_FORCE | STR2NR_OCT works the same as STR2NR_FORCE | STR2NR_OOCT and STR2NR_FORCE | STR2NR_OCT | STR2NR_OOCT.
Diffstat (limited to 'src')
-rw-r--r--src/nvim/charset.c37
-rw-r--r--src/nvim/charset.h9
-rw-r--r--src/nvim/eval/funcs.c2
-rw-r--r--src/nvim/testdir/test_functions.vim5
4 files changed, 41 insertions, 12 deletions
diff --git a/src/nvim/charset.c b/src/nvim/charset.c
index 7b08488925..94b6b7a8d7 100644
--- a/src/nvim/charset.c
+++ b/src/nvim/charset.c
@@ -1385,6 +1385,8 @@ bool vim_isblankline(char_u *lbuf)
/// If "prep" is not NULL, returns a flag to indicate the type of the number:
/// 0 decimal
/// '0' octal
+/// 'O' octal
+/// 'o' octal
/// 'B' bin
/// 'b' bin
/// 'X' hex
@@ -1402,8 +1404,8 @@ bool vim_isblankline(char_u *lbuf)
///
/// @param start
/// @param prep Returns guessed type of number 0 = decimal, 'x' or 'X' is
-/// hexadecimal, '0' = octal, 'b' or 'B' is binary. When using
-/// STR2NR_FORCE is always zero.
+/// hexadecimal, '0', 'o' or 'O' is octal, 'b' or 'B' is binary.
+/// When using STR2NR_FORCE is always zero.
/// @param len Returns the detected length of number.
/// @param what Recognizes what number passed, @see ChStr2NrFlags.
/// @param nptr Returns the signed result.
@@ -1433,8 +1435,8 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len,
}
if (what & STR2NR_FORCE) {
- // When forcing main consideration is skipping the prefix. Octal and decimal
- // numbers have no prefixes to skip. pre is not set.
+ // When forcing main consideration is skipping the prefix. Decimal numbers
+ // have no prefixes to skip. pre is not set.
switch (what & ~(STR2NR_FORCE | STR2NR_QUOTE)) {
case STR2NR_HEX: {
if (!STRING_ENDED(ptr + 2)
@@ -1454,7 +1456,16 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len,
}
goto vim_str2nr_bin;
}
- case STR2NR_OCT: {
+ // Make STR2NR_OOCT work the same as STR2NR_OCT when forcing.
+ case STR2NR_OCT:
+ case STR2NR_OOCT:
+ case STR2NR_OCT | STR2NR_OOCT: {
+ if (!STRING_ENDED(ptr + 2)
+ && ptr[0] == '0'
+ && (ptr[1] == 'o' || ptr[1] == 'O')
+ && ascii_isbdigit(ptr[2])) {
+ ptr += 2;
+ }
goto vim_str2nr_oct;
}
case 0: {
@@ -1464,9 +1475,9 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len,
abort();
}
}
- } else if ((what & (STR2NR_HEX|STR2NR_OCT|STR2NR_BIN))
- && !STRING_ENDED(ptr + 1)
- && ptr[0] == '0' && ptr[1] != '8' && ptr[1] != '9') {
+ } else if ((what & (STR2NR_HEX | STR2NR_OCT | STR2NR_OOCT | STR2NR_BIN))
+ && !STRING_ENDED(ptr + 1) && ptr[0] == '0' && ptr[1] != '8'
+ && ptr[1] != '9') {
pre = ptr[1];
// Detect hexadecimal: 0x or 0X followed by hex digit.
if ((what & STR2NR_HEX)
@@ -1484,7 +1495,15 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len,
ptr += 2;
goto vim_str2nr_bin;
}
- // Detect octal number: zero followed by octal digits without '8' or '9'.
+ // Detect octal: 0o or 0O followed by octal digits (without '8' or '9').
+ if ((what & STR2NR_OOCT)
+ && !STRING_ENDED(ptr + 2)
+ && (pre == 'O' || pre == 'o')
+ && ascii_isbdigit(ptr[2])) {
+ ptr += 2;
+ goto vim_str2nr_oct;
+ }
+ // Detect old octal format: 0 followed by octal digits.
pre = 0;
if (!(what & STR2NR_OCT)
|| !('0' <= ptr[1] && ptr[1] <= '7')) {
diff --git a/src/nvim/charset.h b/src/nvim/charset.h
index b5f1f8506b..2fef4d78a2 100644
--- a/src/nvim/charset.h
+++ b/src/nvim/charset.h
@@ -23,14 +23,19 @@ typedef enum {
STR2NR_BIN = (1 << 0), ///< Allow binary numbers.
STR2NR_OCT = (1 << 1), ///< Allow octal numbers.
STR2NR_HEX = (1 << 2), ///< Allow hexadecimal numbers.
+ STR2NR_OOCT = (1 << 3), ///< Octal with prefix "0o": 0o777
/// Force one of the above variants.
///
/// STR2NR_FORCE|STR2NR_DEC is actually not different from supplying zero
/// as flags, but still present for completeness.
+ ///
+ /// STR2NR_FORCE|STR2NR_OCT|STR2NR_OOCT is the same as STR2NR_FORCE|STR2NR_OCT
+ /// or STR2NR_FORCE|STR2NR_OOCT.
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_ALL = STR2NR_BIN | STR2NR_OCT | STR2NR_HEX | STR2NR_OOCT,
+ /// Disallow octals numbers without the 0o prefix.
+ STR2NR_NO_OCT = STR2NR_BIN | STR2NR_HEX | STR2NR_OOCT,
STR2NR_QUOTE = (1 << 4), ///< Ignore embedded single quotes.
} ChStr2NrFlags;
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index 61f535e32e..801b0f9d1c 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -10022,7 +10022,7 @@ static void f_str2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
break;
}
case 8: {
- what |= STR2NR_OCT | STR2NR_FORCE;
+ what |= STR2NR_OCT | STR2NR_OOCT | STR2NR_FORCE;
break;
}
case 16: {
diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim
index 2e838f73b6..ed46730cbb 100644
--- a/src/nvim/testdir/test_functions.vim
+++ b/src/nvim/testdir/test_functions.vim
@@ -152,6 +152,10 @@ func Test_str2nr()
call assert_equal(65, str2nr('0101', 8))
call assert_equal(-65, str2nr('-101', 8))
call assert_equal(-65, str2nr('-0101', 8))
+ call assert_equal(65, str2nr('0o101', 8))
+ call assert_equal(65, str2nr('0O0101', 8))
+ call assert_equal(-65, str2nr('-0O101', 8))
+ call assert_equal(-65, str2nr('-0o0101', 8))
call assert_equal(11259375, str2nr('abcdef', 16))
call assert_equal(11259375, str2nr('ABCDEF', 16))
@@ -170,6 +174,7 @@ func Test_str2nr()
call assert_equal(0, str2nr('0x10'))
call assert_equal(0, str2nr('0b10'))
+ call assert_equal(0, str2nr('0o10'))
call assert_equal(1, str2nr('12', 2))
call assert_equal(1, str2nr('18', 8))
call assert_equal(1, str2nr('1g', 16))