]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 8.2.0886: cannot use octal numbers in scriptversion 4 v8.2.0886
authorBram Moolenaar <Bram@vim.org>
Tue, 2 Jun 2020 19:38:22 +0000 (21:38 +0200)
committerBram Moolenaar <Bram@vim.org>
Tue, 2 Jun 2020 19:38:22 +0000 (21:38 +0200)
Problem:    Cannot use octal numbers in scriptversion 4.
Solution:   Add the "0o" notation. (Ken Takata, closes #5304)

runtime/doc/eval.txt
src/charset.c
src/evalfunc.c
src/testdir/test_eval_stuff.vim
src/testdir/test_functions.vim
src/version.c
src/vim.h

index 7b85acd55deee37996146011a21c4287221a454a..7c4c59a8cc831a18712879404117fc72285a4668 100644 (file)
@@ -95,15 +95,17 @@ the Number.  Examples:
        Number -1       -->     String "-1" ~
                                                        *octal*
 Conversion from a String to a Number is done by converting the first digits to
-a number.  Hexadecimal "0xf9", Octal "017", and Binary "0b10" numbers are
-recognized (NOTE: when using |scriptversion-4| octal is not recognized).  If
-the String doesn't start with digits, the result is zero.
+a number.  Hexadecimal "0xf9", Octal "017" or "0o17", and Binary "0b10"
+numbers are recognized (NOTE: when using |scriptversion-4| octal with a
+leading "0" is not recognized).  If the String doesn't start with digits, the
+result is zero.
 Examples:
        String "456"    -->     Number 456 ~
        String "6bar"   -->     Number 6 ~
        String "foo"    -->     Number 0 ~
        String "0xf1"   -->     Number 241 ~
        String "0100"   -->     Number 64 ~
+       String "0o100"  -->     Number 64 ~
        String "0b101"  -->     Number 5 ~
        String "-8"     -->     Number -8 ~
        String "+8"     -->     Number 0 ~
@@ -1264,7 +1266,7 @@ number                    number constant                 *expr-number*
                                *hex-number* *octal-number* *binary-number*
 
 Decimal, Hexadecimal (starting with 0x or 0X), Binary (starting with 0b or 0B)
-and Octal (starting with 0).
+and Octal (starting with 0, 0o or 0O).
 
                                                *floating-point-format*
 Floating point numbers can be written in two forms:
@@ -9642,8 +9644,8 @@ str2nr({expr} [, {base} [, {quoted}]])                            *str2nr()*
 <
                When {base} is 16 a leading "0x" or "0X" is ignored.  With a
                different base the result will be zero.  Similarly, when
-               {base} is 8 a leading "0" is ignored, and when {base} is 2 a
-               leading "0b" or "0B" is ignored.
+               {base} is 8 a leading "0", "0o" or "0O" is ignored, and when
+               {base} is 2 a leading "0b" or "0B" is ignored.
                Text after the number is silently ignored.
 
                Can also be used as a |method|: >
@@ -13593,13 +13595,16 @@ instead of failing in mysterious ways.
 <
                                                        *scriptversion-4*  >
  :scriptversion 4
-<      Numbers with a leading zero are not recognized as octal.  With the
+<      Numbers with a leading zero are not recognized as octal.  "0o" or "0O"
+       is still recognized as octal.  With the
        previous version you get: >
-               echo 017   " displays 15
-               echo 018   " displays 18
+               echo 017   " displays 15 (octal)
+               echo 0o17  " displays 15 (octal)
+               echo 018   " displays 18 (decimal)
 <      with script version 4: >
-               echo 017   " displays 17
-               echo 018   " displays 18
+               echo 017   " displays 17 (decimal)
+               echo 0o17  " displays 15 (octal)
+               echo 018   " displays 18 (decimal)
 <      Also, it is possible to use single quotes inside numbers to make them
        easier to read: >
                echo 1'000'000
index 7415c24719c03db41a453da87249e5864e705dbc..6cf4a2bb135983029e16466714c87012a1fdd903 100644 (file)
@@ -1764,6 +1764,8 @@ 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
@@ -1783,8 +1785,8 @@ vim_isblankline(char_u *lbuf)
 vim_str2nr(
     char_u             *start,
     int                        *prep,      // return: type of number 0 = decimal, 'x'
-                                   // or 'X' is hex, '0' = octal, 'b' or 'B'
-                                   // is bin
+                                   // or 'X' is hex, '0', 'o' or 'O' is octal,
+                                   // 'b' or 'B' is bin
     int                        *len,       // return: detected length of number
     int                        what,       // what numbers to recognize
     varnumber_T                *nptr,      // return: signed result
@@ -1822,6 +1824,11 @@ vim_str2nr(
                && (maxlen == 0 || maxlen > 2))
            // binary
            ptr += 2;
+       else if ((what & STR2NR_OOCT)
+               && (pre == 'O' || pre == 'o') && vim_isbdigit(ptr[2])
+               && (maxlen == 0 || maxlen > 2))
+           // octal with prefix "0o"
+           ptr += 2;
        else
        {
            // decimal or octal, default is decimal
@@ -1869,9 +1876,12 @@ vim_str2nr(
            }
        }
     }
-    else if (pre == '0' || ((what & STR2NR_OCT) && (what & STR2NR_FORCE)))
+    else if (pre == 'O' || pre == 'o' ||
+               pre == '0' || ((what & STR2NR_OCT) && (what & STR2NR_FORCE)))
     {
        // octal
+       if (pre != 0 && pre != '0')
+           n += 2;         // skip over "0o"
        while ('0' <= *ptr && *ptr <= '7')
        {
            // avoid ubsan error for overflow
index bfc811bff5f4f19429ad5001fd159542d06b7390..d8e88e5c692f6d12cbf98df5856daf0f92e6bf38 100644 (file)
@@ -7737,7 +7737,7 @@ f_str2nr(typval_T *argvars, typval_T *rettv)
     switch (base)
     {
        case 2: what |= STR2NR_BIN + STR2NR_FORCE; break;
-       case 8: what |= STR2NR_OCT + STR2NR_FORCE; break;
+       case 8: what |= STR2NR_OCT + STR2NR_OOCT + STR2NR_FORCE; break;
        case 16: what |= STR2NR_HEX + STR2NR_FORCE; break;
     }
     vim_str2nr(p, NULL, NULL, what, &n, NULL, 0, FALSE);
index 325f8e2a49291cd670af587018a77ff9cf644f5e..33c57fd0528092e9ed286fa6f1b76e86b4850a1d 100644 (file)
@@ -199,9 +199,12 @@ scriptversion 4
 func Test_vvar_scriptversion4()
   call assert_true(has('vimscript-4'))
   call assert_equal(17, 017)
+  call assert_equal(15, 0o17)
+  call assert_equal(15, 0O17)
   call assert_equal(18, 018)
   call assert_equal(64, 0b1'00'00'00)
   call assert_equal(1048576, 0x10'00'00)
+  call assert_equal(32768, 0o10'00'00)
   call assert_equal(1000000, 1'000'000)
   call assert_equal("1234", execute("echo 1'234")->trim())
   call assert_equal('1  234', execute("echo 1''234")->trim())
@@ -211,6 +214,8 @@ endfunc
 scriptversion 1
 func Test_vvar_scriptversion1()
   call assert_equal(15, 017)
+  call assert_equal(15, 0o17)
+  call assert_equal(15, 0O17)
   call assert_equal(18, 018)
 endfunc
 
index 2253879c9ffa7cc857f03b768cb3b374c15e3bff..a82c70bbc2334c9f276e6fd44c58a84dda7d331b 100644 (file)
@@ -189,6 +189,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))
@@ -207,6 +211,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))
index 5bee0d81517a89ab4bf05809f86ea9e6fedd592e..9a34111d66fe36b139d14ae3d33c36678ae37f67 100644 (file)
@@ -746,6 +746,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    886,
 /**/
     885,
 /**/
index 251e190c20a78d46a2fa542b402d5af136571358..99afe297504872d1835a49e72eb2826e5240fa18 100644 (file)
--- a/src/vim.h
+++ b/src/vim.h
 #define NUMBUFLEN 65
 
 // flags for vim_str2nr()
-#define STR2NR_BIN 0x01
-#define STR2NR_OCT 0x02
-#define STR2NR_HEX 0x04
-#define STR2NR_ALL (STR2NR_BIN + STR2NR_OCT + STR2NR_HEX)
-#define STR2NR_NO_OCT (STR2NR_BIN + STR2NR_HEX)
+#define STR2NR_BIN  0x01
+#define STR2NR_OCT  0x02
+#define STR2NR_HEX  0x04
+#define STR2NR_OOCT 0x08    // Octal with prefix "0o": 0o777
+#define STR2NR_ALL (STR2NR_BIN + STR2NR_OCT + STR2NR_HEX + STR2NR_OOCT)
+#define STR2NR_NO_OCT (STR2NR_BIN + STR2NR_HEX + STR2NR_OOCT)
 
 #define STR2NR_FORCE 0x80   // only when ONE of the above is used