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 #5304)
diff --git a/src/charset.c b/src/charset.c
index 7415c24..6cf4a2b 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -1764,6 +1764,8 @@
  * 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_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 @@
 		&& (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 @@
 	    }
 	}
     }
-    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
diff --git a/src/evalfunc.c b/src/evalfunc.c
index bfc811b..d8e88e5 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -7737,7 +7737,7 @@
     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);
diff --git a/src/testdir/test_eval_stuff.vim b/src/testdir/test_eval_stuff.vim
index 325f8e2..33c57fd 100644
--- a/src/testdir/test_eval_stuff.vim
+++ b/src/testdir/test_eval_stuff.vim
@@ -199,9 +199,12 @@
 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 @@
 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
 
diff --git a/src/testdir/test_functions.vim b/src/testdir/test_functions.vim
index 2253879..a82c70b 100644
--- a/src/testdir/test_functions.vim
+++ b/src/testdir/test_functions.vim
@@ -189,6 +189,10 @@
   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 @@
 
   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))
diff --git a/src/version.c b/src/version.c
index 5bee0d8..9a34111 100644
--- a/src/version.c
+++ b/src/version.c
@@ -747,6 +747,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    886,
+/**/
     885,
 /**/
     884,
diff --git a/src/vim.h b/src/vim.h
index 251e190..99afe29 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -312,11 +312,12 @@
 #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