summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2020-12-31 17:41:01 +0100
committerBram Moolenaar <Bram@vim.org>2020-12-31 17:41:01 +0100
commitdd1f426bd617ac6a775f2e7795ff0b159e3fa315 (patch)
tree4ff4b05181d01272e12a482a91dec6a6ef5095bc
parentca2f7e7af32d51c2be378a5298bc85958c877653 (diff)
patch 8.2.2254: Vim9: bool option type is numberv8.2.2254
Problem: Vim9: bool option type is number. Solution: Have get_option_value() return a different value for bool and number options. (closes #7583)
-rw-r--r--src/evalvars.c21
-rw-r--r--src/if_mzsch.c17
-rw-r--r--src/if_ruby.c8
-rw-r--r--src/option.c32
-rw-r--r--src/option.h11
-rw-r--r--src/proto/option.pro2
-rw-r--r--src/spell.c2
-rw-r--r--src/testdir/test_vim9_assign.vim5
-rw-r--r--src/testdir/test_vim9_cmd.vim2
-rw-r--r--src/typval.c29
-rw-r--r--src/version.c2
-rw-r--r--src/vim9compile.c29
12 files changed, 104 insertions, 56 deletions
diff --git a/src/evalvars.c b/src/evalvars.c
index f7982f7f99..f9b3c486cb 100644
--- a/src/evalvars.c
+++ b/src/evalvars.c
@@ -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;
diff --git a/src/if_mzsch.c b/src/if_mzsch.c
index 7b52936709..58b169231b 100644
--- a/src/if_mzsch.c
+++ b/src/if_mzsch.c
@@ -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
diff --git a/src/if_ruby.c b/src/if_ruby.c
index 3751025a1e..9e58902141 100644
--- a/src/if_ruby.c
+++ b/src/if_ruby.c
@@ -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);
diff --git a/src/option.c b/src/option.c
index dd09e0e764..ca6fadb504 100644
--- a/src/option.c
+++ b/src/option.c
@@ -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
diff --git a/src/option.h b/src/option.h
index 421ee7acdd..4bc189ca73 100644
--- a/src/option.h
+++ b/src/option.h
@@ -60,6 +60,17 @@
#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
diff --git a/src/proto/option.pro b/src/proto/option.pro
index 1c7c3b2052..8d672aac05 100644
--- a/src/proto/option.pro
+++ b/src/proto/option.pro
@@ -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);
diff --git a/src/spell.c b/src/spell.c
index b474a38b3c..d43056660e 100644
--- a/src/spell.c
+++ b/src/spell.c
@@ -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");
diff --git a/src/testdir/test_vim9_assign.vim b/src/testdir/test_vim9_assign.vim
index ea344fe631..3e14b58f81 100644
--- a/src/testdir/test_vim9_assign.vim
+++ b/src/testdir/test_vim9_assign.vim
@@ -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
diff --git a/src/testdir/test_vim9_cmd.vim b/src/testdir/test_vim9_cmd.vim
index ed0c7dda30..2017846843 100644
--- a/src/testdir/test_vim9_cmd.vim
+++ b/src/testdir/test_vim9_cmd.vim
@@ -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
diff --git a/src/typval.c b/src/typval.c
index df3bc92a4c..421e62a37c 100644
--- a/src/typval.c
+++ b/src/typval.c
@@ -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
diff --git a/src/version.c b/src/version.c
index a8e1a89296..d23afb2da8 100644
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 2254,
+/**/
2253,
/**/
2252,
diff --git a/src/vim9compile.c b/src/vim9compile.c
index 5602ff592a..c2c3fc90df 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -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 == '$')
{