]> granicus.if.org Git - vim/commitdiff
patch 8.2.2254: Vim9: bool option type is number v8.2.2254
authorBram Moolenaar <Bram@vim.org>
Thu, 31 Dec 2020 16:41:01 +0000 (17:41 +0100)
committerBram Moolenaar <Bram@vim.org>
Thu, 31 Dec 2020 16:41:01 +0000 (17:41 +0100)
Problem:    Vim9: bool option type is number.
Solution:   Have get_option_value() return a different value for bool and
            number options. (closes #7583)

12 files changed:
src/evalvars.c
src/if_mzsch.c
src/if_ruby.c
src/option.c
src/option.h
src/proto/option.pro
src/spell.c
src/testdir/test_vim9_assign.vim
src/testdir/test_vim9_cmd.vim
src/typval.c
src/version.c
src/vim9compile.c

index f7982f7f99856761827b3dc185a16e331cfd96d6..f9b3c486cbe87ae1500b48ae4823aa3b8cc75221 100644 (file)
@@ -1354,7 +1354,7 @@ ex_let_one(
        else
        {
            long        n = 0;
-           int         opt_type;
+           getoption_T opt_type;
            long        numval;
            char_u      *stringval = NULL;
            char_u      *s = NULL;
@@ -1364,7 +1364,10 @@ ex_let_one(
            *p = NUL;
 
            opt_type = get_option_value(arg, &numval, &stringval, opt_flags);
-           if ((opt_type == 1 || opt_type == -1)
+           if ((opt_type == gov_bool
+                       || opt_type == gov_number
+                       || opt_type == gov_hidden_bool
+                       || opt_type == gov_hidden_number)
                             && (tv->v_type != VAR_STRING || !in_vim9script()))
                // number, possibly hidden
                n = (long)tv_get_number(tv);
@@ -1377,8 +1380,9 @@ ex_let_one(
 
            if (op != NULL && *op != '=')
            {
-               if ((opt_type == 1 && *op == '.')
-                       || (opt_type == 0 && *op != '.'))
+               if (((opt_type == gov_bool || opt_type == gov_number)
+                                                                && *op == '.')
+                       || (opt_type == gov_string && *op != '.'))
                {
                    semsg(_(e_letwrong), op);
                    failed = TRUE;  // don't set the value
@@ -1386,7 +1390,9 @@ ex_let_one(
                }
                else
                {
-                   if (opt_type == 1)  // number
+                   // number, in legacy script also bool
+                   if (opt_type == gov_number
+                                || (opt_type == gov_bool && !in_vim9script()))
                    {
                        switch (*op)
                        {
@@ -1397,7 +1403,8 @@ ex_let_one(
                            case '%': n = (long)num_modulus(numval, n); break;
                        }
                    }
-                   else if (opt_type == 0 && stringval != NULL && s != NULL)
+                   else if (opt_type == gov_string
+                                            && stringval != NULL && s != NULL)
                    {
                        // string
                        s = concat_str(stringval, s);
@@ -1409,7 +1416,7 @@ ex_let_one(
 
            if (!failed)
            {
-               if (opt_type != 0 || s != NULL)
+               if (opt_type != gov_string || s != NULL)
                {
                    set_option_value(arg, n, s, opt_flags);
                    arg_end = p;
index 7b5293670976e79c5027d91c9026f40d394d2081..58b169231b60f35e84b927cfc6f4d3d1b31d6ca3 100644 (file)
@@ -1712,7 +1712,7 @@ get_option(void *data, int argc, Scheme_Object **argv)
     Vim_Prim       *prim = (Vim_Prim *)data;
     long           value;
     char           *strval;
-    int                    rc;
+    getoption_T            rc;
     Scheme_Object   *rval = NULL;
     Scheme_Object   *name = NULL;
     int                    opt_flags = 0;
@@ -1754,27 +1754,30 @@ get_option(void *data, int argc, Scheme_Object **argv)
            scheme_wrong_type(prim->name, "vim-buffer/window", 1, argc, argv);
     }
 
-    rc = get_option_value(BYTE_STRING_VALUE(name), &value, (char_u **)&strval, opt_flags);
+    rc = get_option_value(BYTE_STRING_VALUE(name), &value, (char_u **)&strval,
+                                                                   opt_flags);
     curbuf = save_curb;
     curwin = save_curw;
 
     switch (rc)
     {
-    case 1:
+    case gov_bool:
+    case gov_number:
        MZ_GC_UNREG();
        return scheme_make_integer_value(value);
-    case 0:
+    case gov_string:
        rval = scheme_make_byte_string(strval);
        MZ_GC_CHECK();
        vim_free(strval);
        MZ_GC_UNREG();
        return rval;
-    case -1:
-    case -2:
+    case gov_hidden_bool:
+    case gov_hidden_number:
+    case gov_hidden_string:
        MZ_GC_UNREG();
        raise_vim_exn(_("hidden option"));
        //NOTREACHED
-    case -3:
+    case gov_unknown:
        MZ_GC_UNREG();
        raise_vim_exn(_("unknown option"));
        //NOTREACHED
index 3751025a1e3c08de734687126c82ad3c6cbf0ff2..9e58902141cdaf639ed26ad401b9086fbb7b145f 100644 (file)
@@ -865,13 +865,11 @@ ex_ruby(exarg_T *eap)
 vim_str2rb_enc_str(const char *s)
 {
 #if RUBY_VERSION >= 19
-    int isnum;
     long lval;
     char_u *sval;
     rb_encoding *enc;
 
-    isnum = get_option_value((char_u *)"enc", &lval, &sval, 0);
-    if (isnum == 0)
+    if (get_option_value((char_u *)"enc", &lval, &sval, 0) == gov_string)
     {
        enc = rb_enc_find((char *)sval);
        vim_free(sval);
@@ -886,14 +884,12 @@ vim_str2rb_enc_str(const char *s)
 eval_enc_string_protect(const char *str, int *state)
 {
 #if RUBY_VERSION >= 19
-    int isnum;
     long lval;
     char_u *sval;
     rb_encoding *enc;
     VALUE v;
 
-    isnum = get_option_value((char_u *)"enc", &lval, &sval, 0);
-    if (isnum == 0)
+    if (get_option_value((char_u *)"enc", &lval, &sval, 0) == gov_string)
     {
        enc = rb_enc_find((char *)sval);
        vim_free(sval);
index dd09e0e764c70572cda30155abb8d68a1f2ddb75..ca6fadb5041ad2e34f3eb75f109757cbcd0d1537 100644 (file)
@@ -3834,13 +3834,15 @@ findoption(char_u *arg)
  * Get the value for an option.
  *
  * Returns:
- * Number or Toggle option: 1, *numval gets value.
- *          String option: 0, *stringval gets allocated string.
- * Hidden Number or Toggle option: -1.
- *          hidden String option: -2.
- *                unknown option: -3.
+ * Number option: gov_number, *numval gets value.
+ * Tottle option: gov_bool,   *numval gets value.
+ * String option: gov_string, *stringval gets allocated string.
+ * Hidden Number option: gov_hidden_number.
+ * Hidden Toggle option: gov_hidden_bool.
+ * Hidden String option: gov_hidden_string.
+ * Unknown option: gov_unknown.
  */
-    int
+    getoption_T
 get_option_value(
     char_u     *name,
     long       *numval,
@@ -3851,16 +3853,17 @@ get_option_value(
     char_u     *varp;
 
     opt_idx = findoption(name);
-    if (opt_idx < 0)               // unknown option
+    if (opt_idx < 0)               // option not in the table
     {
        int key;
 
        if (STRLEN(name) == 4 && name[0] == 't' && name[1] == '_'
-               && (key = find_key_option(name, FALSE)) != 0)
+                                 && (key = find_key_option(name, FALSE)) != 0)
        {
            char_u key_name[2];
            char_u *p;
 
+           // check for a terminal option
            if (key < 0)
            {
                key_name[0] = KEY2TERMCAP0(key);
@@ -3876,10 +3879,10 @@ get_option_value(
            {
                if (stringval != NULL)
                    *stringval = vim_strsave(p);
-               return 0;
+               return gov_string;
            }
        }
-       return -3;
+       return gov_unknown;
     }
 
     varp = get_varp_scope(&(options[opt_idx]), opt_flags);
@@ -3887,7 +3890,7 @@ get_option_value(
     if (options[opt_idx].flags & P_STRING)
     {
        if (varp == NULL)                   // hidden option
-           return -2;
+           return gov_hidden_string;
        if (stringval != NULL)
        {
 #ifdef FEAT_CRYPT
@@ -3899,11 +3902,12 @@ get_option_value(
 #endif
                *stringval = vim_strsave(*(char_u **)(varp));
        }
-       return 0;
+       return gov_string;
     }
 
     if (varp == NULL)              // hidden option
-       return -1;
+       return (options[opt_idx].flags & P_NUM)
+                                        ? gov_hidden_number : gov_hidden_bool;
     if (options[opt_idx].flags & P_NUM)
        *numval = *(long *)varp;
     else
@@ -3915,7 +3919,7 @@ get_option_value(
        else
            *numval = (long) *(int *)varp;
     }
-    return 1;
+    return (options[opt_idx].flags & P_NUM) ? gov_number : gov_bool;
 }
 #endif
 
index 421ee7acdd230b9658bcc06caa27c7703bd2047b..4bc189ca73da52f52c571c839f7321ca9edb0a26 100644 (file)
 #define P_RWINONLY   0x10000000L // only redraw current window
 #define P_MLE       0x20000000L // under control of 'modelineexpr'
 
+// Returned by get_option_value().
+typedef enum {
+    gov_unknown,
+    gov_bool,
+    gov_number,
+    gov_string,
+    gov_hidden_bool,
+    gov_hidden_number,
+    gov_hidden_string
+} getoption_T;
+
 /*
  * Default values for 'errorformat'.
  * The "%f|%l| %m" one is used for when the contents of the quickfix window is
index 1c7c3b2052d53e56f4b90551e3ffe51b5ff238f9..8d672aac0504a4a6b566986855fe3735c0dc45ec 100644 (file)
@@ -24,7 +24,7 @@ void set_option_sctx_idx(int opt_idx, int opt_flags, sctx_T script_ctx);
 void set_term_option_sctx_idx(char *name, int opt_idx);
 void check_redraw(long_u flags);
 int findoption(char_u *arg);
-int get_option_value(char_u *name, long *numval, char_u **stringval, int opt_flags);
+getoption_T get_option_value(char_u *name, long *numval, char_u **stringval, int opt_flags);
 int get_option_value_strict(char_u *name, long *numval, char_u **stringval, int opt_type, void *from);
 char_u *option_iter_next(void **option, int opt_type);
 long_u get_option_flags(int opt_idx);
index b474a38b3c2e2f0093125314bb0246152e99d052..d43056660e67d00f1349af90efc9c1acff99b335 100644 (file)
@@ -3813,7 +3813,7 @@ ex_spelldump(exarg_T *eap)
 
     if (no_spell_checking(curwin))
        return;
-    get_option_value((char_u*)"spl", &dummy, &spl, OPT_LOCAL);
+    (void)get_option_value((char_u*)"spl", &dummy, &spl, OPT_LOCAL);
 
     // Create a new empty buffer in a new window.
     do_cmdline_cmd((char_u *)"new");
index ea344fe631f2883260c01b8b6a4c1a518e9e71b4..3e14b58f81fec88b2f0e522856ce7dad0419bd3b 100644 (file)
@@ -45,6 +45,9 @@ def Test_assignment_bool()
     assert_equal(true, flag)
     flag = 1 && false
     assert_equal(false, flag)
+
+    var cp: bool = &cp
+    var fen: bool = &l:fen
   END
   CheckScriptSuccess(lines)
   CheckDefAndScriptFailure(['var x: bool = 2'], 'E1012:')
@@ -118,6 +121,8 @@ def Test_assignment()
   assert_equal('new', s:newVar)
 
   set ts=7
+  var ts: number = &ts
+  assert_equal(7, ts)
   &ts += 1
   assert_equal(8, &ts)
   &ts -= 3
index ed0c7dda30380f269e7e22b1c64b97abee5b311b..20178468432fe88cfd1ae9ed1968514621d62150 100644 (file)
@@ -590,7 +590,7 @@ def Test_command_modifier_other()
   unlet g:readFile
 
   noswapfile edit XnoSwap
-  assert_equal(0, &l:swapfile)
+  assert_equal(false, &l:swapfile)
   bwipe!
 
   var caught = false
index df3bc92a4ca919f1514cc4d8e856ecb81ab995bc..421e62a37c69410326e7c11cfbc0c0b1839d3c8f 100644 (file)
@@ -1083,7 +1083,7 @@ eval_option(
     char_u     *option_end;
     long       numval;
     char_u     *stringval;
-    int                opt_type;
+    getoption_T        opt_type;
     int                c;
     int                working = (**arg == '+');    // has("+option")
     int                ret = OK;
@@ -1109,7 +1109,7 @@ eval_option(
     opt_type = get_option_value(*arg, &numval,
                               rettv == NULL ? NULL : &stringval, opt_flags);
 
-    if (opt_type == -3)                        // invalid name
+    if (opt_type == gov_unknown)
     {
        if (rettv != NULL)
            semsg(_(e_unknown_option), *arg);
@@ -1117,20 +1117,29 @@ eval_option(
     }
     else if (rettv != NULL)
     {
-       if (opt_type == -2)             // hidden string option
+       if (opt_type == gov_hidden_string)
        {
            rettv->v_type = VAR_STRING;
            rettv->vval.v_string = NULL;
        }
-       else if (opt_type == -1)        // hidden number option
+       else if (opt_type == gov_hidden_bool || opt_type == gov_hidden_number)
        {
-           rettv->v_type = VAR_NUMBER;
+           rettv->v_type = in_vim9script() && opt_type == gov_hidden_bool
+                                                      ? VAR_BOOL : VAR_NUMBER;
            rettv->vval.v_number = 0;
        }
-       else if (opt_type == 1)         // number option
+       else if (opt_type == gov_bool || opt_type == gov_number)
        {
-           rettv->v_type = VAR_NUMBER;
-           rettv->vval.v_number = numval;
+           if (in_vim9script() && opt_type == gov_bool)
+           {
+               rettv->v_type = VAR_BOOL;
+               rettv->vval.v_number = numval ? VVAL_TRUE : VVAL_FALSE;
+           }
+           else
+           {
+               rettv->v_type = VAR_NUMBER;
+               rettv->vval.v_number = numval;
+           }
        }
        else                            // string option
        {
@@ -1138,7 +1147,9 @@ eval_option(
            rettv->vval.v_string = stringval;
        }
     }
-    else if (working && (opt_type == -2 || opt_type == -1))
+    else if (working && (opt_type == gov_hidden_bool
+                       || opt_type == gov_hidden_number
+                       || opt_type == gov_hidden_string))
        ret = FAIL;
 
     *option_end = c;               // put back for error messages
index a8e1a892965bbd004be23b590fce3f19e539f3f3..d23afb2da82d2114e2f7d8cc18d20239cc621cb4 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2254,
 /**/
     2253,
 /**/
index 5602ff592ae39d72b29cb993533e62666e114139..c2c3fc90dfede421fc39487637c093b5663db291 100644 (file)
@@ -5191,9 +5191,9 @@ get_var_dest(
 
     if (*name == '&')
     {
-       int     cc;
-       long    numval;
-       int     opt_type;
+       int             cc;
+       long            numval;
+       getoption_T     opt_type;
 
        *dest = dest_option;
        if (cmdidx == CMD_final || cmdidx == CMD_const)
@@ -5214,15 +5214,24 @@ get_var_dest(
        opt_type = get_option_value(skip_option_env_lead(name),
                                                    &numval, NULL, *opt_flags);
        *p = cc;
-       if (opt_type == -3)
+       switch (opt_type)
        {
-           semsg(_(e_unknown_option), name);
-           return FAIL;
+           case gov_unknown:
+                   semsg(_(e_unknown_option), name);
+                   return FAIL;
+           case gov_string:
+           case gov_hidden_string:
+                   *type = &t_string;
+                   break;
+           case gov_bool:
+           case gov_hidden_bool:
+                   *type = &t_bool;
+                   break;
+           case gov_number:
+           case gov_hidden_number:
+                   *type = &t_number;
+                   break;
        }
-       if (opt_type == -2 || opt_type == 0)
-           *type = &t_string;
-       else
-           *type = &t_number;  // both number and boolean option
     }
     else if (*name == '$')
     {