summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2005-06-13 22:28:56 +0000
committerBram Moolenaar <Bram@vim.org>2005-06-13 22:28:56 +0000
commit9ba0eb850c0f4c94df3b7f7461610bf0b073f712 (patch)
tree11638af8ad8ecdfd337a6db15914b2e2cdff3aea /src
parentbac97eb8ae6b067466cab0481cac2f25b335ffe7 (diff)
updated for version 7.0084v7.0084
Diffstat (limited to 'src')
-rw-r--r--src/Make_mvc.mak15
-rw-r--r--src/eval.c1108
-rw-r--r--src/ex_cmds.c4
-rw-r--r--src/ex_docmd.c1
-rw-r--r--src/ex_getln.c8
-rw-r--r--src/gui_w32.c13
-rw-r--r--src/gui_w48.c23
-rw-r--r--src/if_cscope.c2
-rw-r--r--src/if_python.c38
-rw-r--r--src/misc1.c21
-rw-r--r--src/misc2.c102
-rw-r--r--src/normal.c7
-rw-r--r--src/option.c30
-rw-r--r--src/os_mswin.c18
-rw-r--r--src/os_w32exe.c1
-rw-r--r--src/os_win32.c14
-rw-r--r--src/proto/misc1.pro1
-rw-r--r--src/proto/misc2.pro1
-rw-r--r--src/proto/spell.pro3
-rw-r--r--src/spell.c2291
-rw-r--r--src/tag.c11
-rw-r--r--src/ui.c1
-rw-r--r--src/version.h4
23 files changed, 3156 insertions, 561 deletions
diff --git a/src/Make_mvc.mak b/src/Make_mvc.mak
index 4d4ea225e3..eb5aa7e9e7 100644
--- a/src/Make_mvc.mak
+++ b/src/Make_mvc.mak
@@ -110,7 +110,8 @@
TARGETOS = BOTH
-# Select one of eight object code directories, depends on GUI, OLE and DEBUG.
+# Select one of eight object code directories, depends on GUI, OLE, DEBUG and
+# interfaces.
# If you change something else, do "make clean" first!
!if "$(GUI)" == "yes"
OBJDIR = .\ObjG
@@ -120,6 +121,18 @@ OBJDIR = .\ObjC
!if "$(OLE)" == "yes"
OBJDIR = $(OBJDIR)O
!endif
+!ifdef PERL
+OBJDIR = $(OBJDIR)L
+!endif
+!ifdef PYTHON
+OBJDIR = $(OBJDIR)Y
+!endif
+!ifdef TCL
+OBJDIR = $(OBJDIR)T
+!endif
+!ifdef RUBY
+OBJDIR = $(OBJDIR)R
+!endif
!ifdef MZSCHEME
OBJDIR = $(OBJDIR)Z
!endif
diff --git a/src/eval.c b/src/eval.c
index aa3935034a..913f8ed0f2 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -264,12 +264,11 @@ typedef struct
#define VV_RO 2 /* read-only */
#define VV_RO_SBX 4 /* read-only in the sandbox */
-#define VV_NAME(s, t) s, sizeof(s) - 1, {{t}}, {0}
+#define VV_NAME(s, t) s, {{t}}, {0}
static struct vimvar
{
char *vv_name; /* name of variable, without v: */
- int vv_len; /* length of name */
dictitem_T vv_di; /* value and name for key */
char vv_filler[16]; /* space for LONGEST name below!!! */
char vv_flags; /* VV_COMPAT, VV_RO, VV_RO_SBX */
@@ -594,9 +593,12 @@ static void free_tv __ARGS((typval_T *varp));
static void clear_tv __ARGS((typval_T *varp));
static void init_tv __ARGS((typval_T *varp));
static long get_tv_number __ARGS((typval_T *varp));
+static long get_tv_number_chk __ARGS((typval_T *varp, int *denote));
static linenr_T get_tv_lnum __ARGS((typval_T *argvars));
static char_u *get_tv_string __ARGS((typval_T *varp));
+static char_u *get_tv_string_chk __ARGS((typval_T *varp));
static char_u *get_tv_string_buf __ARGS((typval_T *varp, char_u *buf));
+static char_u *get_tv_string_buf_chk __ARGS((typval_T *varp, char_u *buf));
static dictitem_T *find_var __ARGS((char_u *name, hashtab_T **htp));
static dictitem_T *find_var_in_ht __ARGS((hashtab_T *ht, char_u *varname, int writing));
static hashtab_T *find_var_ht __ARGS((char_u *name, char_u **varname));
@@ -1023,7 +1025,7 @@ eval_to_bool(arg, error, nextcmd, skip)
*error = FALSE;
if (!skip)
{
- retval = (get_tv_number(&tv) != 0);
+ retval = (get_tv_number_chk(&tv, error) != 0);
clear_tv(&tv);
}
}
@@ -1137,7 +1139,7 @@ eval_to_number(expr)
retval = -1;
else
{
- retval = get_tv_number(&rettv);
+ retval = get_tv_number_chk(&rettv, NULL);
clear_tv(&rettv);
}
--emsg_off;
@@ -1775,8 +1777,8 @@ ex_let_one(arg, tv, copy, endchars, op)
{
c1 = name[len];
name[len] = NUL;
- p = get_tv_string(tv);
- if (op != NULL && *op == '.')
+ p = get_tv_string_chk(tv);
+ if (p != NULL && op != NULL && *op == '.')
{
int mustfree = FALSE;
char_u *s = vim_getenv(name, &mustfree);
@@ -1789,15 +1791,18 @@ ex_let_one(arg, tv, copy, endchars, op)
}
}
if (p != NULL)
+ {
vim_setenv(name, p);
- if (STRICMP(name, "HOME") == 0)
- init_homedir();
- else if (didset_vim && STRICMP(name, "VIM") == 0)
- didset_vim = FALSE;
- else if (didset_vimruntime && STRICMP(name, "VIMRUNTIME") == 0)
- didset_vimruntime = FALSE;
+ if (STRICMP(name, "HOME") == 0)
+ init_homedir();
+ else if (didset_vim && STRICMP(name, "VIM") == 0)
+ didset_vim = FALSE;
+ else if (didset_vimruntime
+ && STRICMP(name, "VIMRUNTIME") == 0)
+ didset_vimruntime = FALSE;
+ arg_end = arg;
+ }
name[len] = c1;
- arg_end = arg;
vim_free(tofree);
}
}
@@ -1827,8 +1832,8 @@ ex_let_one(arg, tv, copy, endchars, op)
*p = NUL;
n = get_tv_number(tv);
- s = get_tv_string(tv);
- if (op != NULL && *op != '=')
+ s = get_tv_string_chk(tv); /* != NULL if number or string */
+ if (s != NULL && op != NULL && *op != '=')
{
opt_type = get_option_value(arg, &numval,
&stringval, opt_flags);
@@ -1852,9 +1857,12 @@ ex_let_one(arg, tv, copy, endchars, op)
}
}
}
- set_option_value(arg, n, s, opt_flags);
+ if (s != NULL)
+ {
+ set_option_value(arg, n, s, opt_flags);
+ arg_end = p;
+ }
*p = c1;
- arg_end = p;
vim_free(stringval);
}
}
@@ -1875,8 +1883,8 @@ ex_let_one(arg, tv, copy, endchars, op)
char_u *tofree = NULL;
char_u *s;
- p = get_tv_string(tv);
- if (op != NULL && *op == '.')
+ p = get_tv_string_chk(tv);
+ if (p != NULL && op != NULL && *op == '.')
{
s = get_reg_contents(*arg == '@' ? '"' : *arg, FALSE, FALSE);
if (s != NULL)
@@ -1886,8 +1894,10 @@ ex_let_one(arg, tv, copy, endchars, op)
}
}
if (p != NULL)
+ {
write_reg_contents(*arg == '@' ? '"' : *arg, p, -1, FALSE);
- arg_end = arg + 1;
+ arg_end = arg + 1;
+ }
vim_free(tofree);
}
}
@@ -2070,6 +2080,12 @@ get_lval(name, rettv, lp, unlet, skip, quiet, fne_flags)
empty1 = FALSE;
if (eval1(&p, &var1, TRUE) == FAIL) /* recursive! */
return NULL;
+ if (get_tv_string_chk(&var1) == NULL)
+ {
+ /* not a number or string */
+ clear_tv(&var1);
+ return NULL;
+ }
}
/* Optionally get the second index [ :expr]. */
@@ -2104,6 +2120,14 @@ get_lval(name, rettv, lp, unlet, skip, quiet, fne_flags)
clear_tv(&var1);
return NULL;
}
+ if (get_tv_string_chk(&var2) == NULL)
+ {
+ /* not a number or string */
+ if (!empty1)
+ clear_tv(&var1);
+ clear_tv(&var2);
+ return NULL;
+ }
}
lp->ll_range = TRUE;
}
@@ -2130,7 +2154,7 @@ get_lval(name, rettv, lp, unlet, skip, quiet, fne_flags)
if (len == -1)
{
/* "[key]": get key from "var1" */
- key = get_tv_string(&var1);
+ key = get_tv_string(&var1); /* is number or string */
if (*key == NUL)
{
if (!quiet)
@@ -2176,7 +2200,7 @@ get_lval(name, rettv, lp, unlet, skip, quiet, fne_flags)
lp->ll_n1 = 0;
else
{
- lp->ll_n1 = get_tv_number(&var1);
+ lp->ll_n1 = get_tv_number(&var1); /* is number or string */
clear_tv(&var1);
}
lp->ll_dict = NULL;
@@ -2199,7 +2223,7 @@ get_lval(name, rettv, lp, unlet, skip, quiet, fne_flags)
*/
if (lp->ll_range && !lp->ll_empty2)
{
- lp->ll_n2 = get_tv_number(&var2);
+ lp->ll_n2 = get_tv_number(&var2); /* is number or string */
clear_tv(&var2);
if (lp->ll_n2 < 0)
{
@@ -3340,9 +3364,13 @@ eval1(arg, rettv, evaluate)
result = FALSE;
if (evaluate)
{
- if (get_tv_number(rettv) != 0)
+ int error = FALSE;
+
+ if (get_tv_number_chk(rettv, &error) != 0)
result = TRUE;
clear_tv(rettv);
+ if (error)
+ return FAIL;
}
/*
@@ -3398,6 +3426,7 @@ eval2(arg, rettv, evaluate)
typval_T var2;
long result;
int first;
+ int error = FALSE;
/*
* Get the first variable.
@@ -3414,9 +3443,11 @@ eval2(arg, rettv, evaluate)
{
if (evaluate && first)
{
- if (get_tv_number(rettv) != 0)
+ if (get_tv_number_chk(rettv, &error) != 0)
result = TRUE;
clear_tv(rettv);
+ if (error)
+ return FAIL;
first = FALSE;
}
@@ -3432,9 +3463,11 @@ eval2(arg, rettv, evaluate)
*/
if (evaluate && !result)
{
- if (get_tv_number(&var2) != 0)
+ if (get_tv_number_chk(&var2, &error) != 0)
result = TRUE;
clear_tv(&var2);
+ if (error)
+ return FAIL;
}
if (evaluate)
{
@@ -3464,6 +3497,7 @@ eval3(arg, rettv, evaluate)
typval_T var2;
long result;
int first;
+ int error = FALSE;
/*
* Get the first variable.
@@ -3480,9 +3514,11 @@ eval3(arg, rettv, evaluate)
{
if (evaluate && first)
{
- if (get_tv_number(rettv) == 0)
+ if (get_tv_number_chk(rettv, &error) == 0)
result = FALSE;
clear_tv(rettv);
+ if (error)
+ return FAIL;
first = FALSE;
}
@@ -3498,9 +3534,11 @@ eval3(arg, rettv, evaluate)
*/
if (evaluate && result)
{
- if (get_tv_number(&var2) == 0)
+ if (get_tv_number_chk(&var2, &error) == 0)
result = FALSE;
clear_tv(&var2);
+ if (error)
+ return FAIL;
}
if (evaluate)
{
@@ -3832,6 +3870,22 @@ eval5(arg, rettv, evaluate)
if (op != '+' && op != '-' && op != '.')
break;
+ if (op != '+' || rettv->v_type != VAR_LIST)
+ {
+ /* For "list + ...", an illegal use of the first operand as
+ * a number cannot be determined before evaluating the 2nd
+ * operand: if this is also a list, all is ok.
+ * For "something . ...", "something - ..." or "non-list + ...",
+ * we know that the first operand needs to be a string or number
+ * without evaluating the 2nd operand. So check before to avoid
+ * side effects after an error. */
+ if (evaluate && get_tv_string_chk(rettv) == NULL)
+ {
+ clear_tv(rettv);
+ return FAIL;
+ }
+ }
+
/*
* Get the second variable.
*/
@@ -3849,8 +3903,14 @@ eval5(arg, rettv, evaluate)
*/
if (op == '.')
{
- s1 = get_tv_string_buf(rettv, buf1);
- s2 = get_tv_string_buf(&var2, buf2);
+ s1 = get_tv_string_buf(rettv, buf1); /* already checked */
+ s2 = get_tv_string_buf_chk(&var2, buf2);
+ if (s2 == NULL) /* type error ? */
+ {
+ clear_tv(rettv);
+ clear_tv(&var2);
+ return FAIL;
+ }
p = concat_str(s1, s2);
clear_tv(rettv);
rettv->v_type = VAR_STRING;
@@ -3872,8 +3932,24 @@ eval5(arg, rettv, evaluate)
}
else
{
- n1 = get_tv_number(rettv);
- n2 = get_tv_number(&var2);
+ int error = FALSE;
+
+ n1 = get_tv_number_chk(rettv, &error);
+ if (error)
+ {
+ /* This can only happen for "list + non-list".
+ * For "non-list + ..." or "something - ...", we returned
+ * before evaluating the 2nd operand. */
+ clear_tv(rettv);
+ return FAIL;
+ }
+ n2 = get_tv_number_chk(&var2, &error);
+ if (error)
+ {
+ clear_tv(rettv);
+ clear_tv(&var2);
+ return FAIL;
+ }
clear_tv(rettv);
if (op == '+')
n1 = n1 + n2;
@@ -3908,6 +3984,7 @@ eval6(arg, rettv, evaluate)
typval_T var2;
int op;
long n1, n2;
+ int error = FALSE;
/*
* Get the first variable.
@@ -3926,8 +4003,10 @@ eval6(arg, rettv, evaluate)
if (evaluate)
{
- n1 = get_tv_number(rettv);
+ n1 = get_tv_number_chk(rettv, &error);
clear_tv(rettv);
+ if (error)
+ return FAIL;
}
else
n1 = 0;
@@ -3941,8 +4020,10 @@ eval6(arg, rettv, evaluate)
if (evaluate)
{
- n2 = get_tv_number(&var2);
+ n2 = get_tv_number_chk(&var2, &error);
clear_tv(&var2);
+ if (error)
+ return FAIL;
/*
* Compute the result.
@@ -4175,18 +4256,28 @@ eval7(arg, rettv, evaluate)
*/
if (ret == OK && evaluate && end_leader > start_leader)
{
- val = get_tv_number(rettv);
- while (end_leader > start_leader)
+ int error = FALSE;
+
+ val = get_tv_number_chk(rettv, &error);
+ if (error)
{
- --end_leader;
- if (*end_leader == '!')
- val = !val;
- else if (*end_leader == '-')
- val = -val;
+ clear_tv(rettv);
+ ret = FAIL;
+ }
+ else
+ {
+ while (end_leader > start_leader)
+ {
+ --end_leader;
+ if (*end_leader == '!')
+ val = !val;
+ else if (*end_leader == '-')
+ val = -val;
+ }
+ clear_tv(rettv);
+ rettv->v_type = VAR_NUMBER;
+ rettv->vval.v_number = val;
}
- clear_tv(rettv);
- rettv->v_type = VAR_NUMBER;
- rettv->vval.v_number = val;
}
return ret;
@@ -4243,6 +4334,12 @@ eval_index(arg, rettv, evaluate, verbose)
empty1 = TRUE;
else if (eval1(arg, &var1, evaluate) == FAIL) /* recursive! */
return FAIL;
+ else if (evaluate && get_tv_string_chk(&var1) == NULL)
+ {
+ /* not a number or string */
+ clear_tv(&var1);
+ return FAIL;
+ }
/*
* Get the second variable from inside the [:].
@@ -4255,7 +4352,16 @@ eval_index(arg, rettv, evaluate, verbose)
empty2 = TRUE;
else if (eval1(arg, &var2, evaluate) == FAIL) /* recursive! */
{
- clear_tv(&var1);
+ if (!empty1)
+ clear_tv(&var1);
+ return FAIL;
+ }
+ else if (evaluate && get_tv_string_chk(&var2) == NULL)
+ {
+ /* not a number or string */
+ if (!empty1)
+ clear_tv(&var1);
+ clear_tv(&var2);
return FAIL;
}
}
@@ -4928,6 +5034,7 @@ tv_equal(tv1, tv2, ic)
int ic; /* ignore case */
{
char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
+ char_u *s1, *s2;
if (tv1->v_type == VAR_LIST || tv2->v_type == VAR_LIST)
{
@@ -4963,12 +5070,13 @@ tv_equal(tv1, tv2, ic)
if (get_tv_number(tv1) != get_tv_number(tv2))
return FALSE;
}
- else if (!ic && STRCMP(get_tv_string_buf(tv1, buf1),
- get_tv_string_buf(tv2, buf2)) != 0)
- return FALSE;
- else if (ic && STRICMP(get_tv_string_buf(tv1, buf1),
- get_tv_string_buf(tv2, buf2)) != 0)
- return FALSE;
+ else
+ {
+ s1 = get_tv_string_buf(tv1, buf1);
+ s2 = get_tv_string_buf(tv2, buf2);
+ if ((ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2)) != 0)
+ return FALSE;
+ }
return TRUE;
}
@@ -5828,10 +5936,12 @@ get_dict_tv(arg, rettv, evaluate)
clear_tv(&tvkey);
goto failret;
}
- key = get_tv_string_buf(&tvkey, buf);
- if (*key == NUL)
+ key = get_tv_string_buf_chk(&tvkey, buf);
+ if (key == NULL || *key == NUL)
{
- EMSG(_(e_emptykey));
+ /* "key" is NULL when get_tv_string_buf_chk() gave an errmsg */
+ if (key != NULL)
+ EMSG(_(e_emptykey));
clear_tv(&tvkey);
goto failret;
}
@@ -6731,12 +6841,12 @@ f_append(argvars, rettv)
typval_T *rettv;
{
long lnum;
+ char_u *line;
list_T *l = NULL;
listitem_T *li = NULL;
typval_T *tv;
long added = 0;
- rettv->vval.v_number = 1; /* Default: Failed */
lnum = get_tv_lnum(argvars);
if (lnum >= 0
&& lnum <= curbuf->b_ml.ml_line_count
@@ -6749,6 +6859,7 @@ f_append(argvars, rettv)
return;
li = l->lv_first;
}
+ rettv->vval.v_number = 0; /* Default: Success */
for (;;)
{
if (l == NULL)
@@ -6757,7 +6868,13 @@ f_append(argvars, rettv)
break; /* end of list */
else
tv = &li->li_tv; /* append item from list */
- ml_append(lnum + added, get_tv_string(tv), (colnr_T)0, FALSE);
+ line = get_tv_string_chk(tv);
+ if (line == NULL) /* type error */
+ {
+ rettv->vval.v_number = 1; /* Failed */
+ break;
+ }
+ ml_append(lnum + added, line, (colnr_T)0, FALSE);
++added;
if (l == NULL)
break;
@@ -6767,8 +6884,9 @@ f_append(argvars, rettv)
appended_lines_mark(lnum, added);
if (curwin->w_cursor.lnum > lnum)
curwin->w_cursor.lnum += added;
- rettv->vval.v_number = 0; /* Success */
}
+ else
+ rettv->vval.v_number = 1; /* Failed */
}
/*
@@ -6805,7 +6923,7 @@ f_argv(argvars, rettv)
{
int idx;
- idx = get_tv_number(&argvars[0]);
+ idx = get_tv_number_chk(&argvars[0], NULL);
if (idx >= 0 && idx < ARGCOUNT)
rettv->vval.v_string = vim_strsave(alist_name(&ARGLIST[idx]));
else
@@ -6829,13 +6947,17 @@ f_browse(argvars, rettv)
char_u *defname;
char_u buf[NUMBUFLEN];
char_u buf2[NUMBUFLEN];
+ int error = FALSE;
- save = get_tv_number(&argvars[0]);
- title = get_tv_string(&argvars[1]);
- initdir = get_tv_string_buf(&argvars[2], buf);
- defname = get_tv_string_buf(&argvars[3], buf2);
+ save = get_tv_number_chk(&argvars[0], &error);
+ title = get_tv_string_chk(&argvars[1]);
+ initdir = get_tv_string_buf_chk(&argvars[2], buf);
+ defname = get_tv_string_buf_chk(&argvars[3], buf2);
- rettv->vval.v_string =
+ if (error || title == NULL || initdir == NULL || defname == NULL)
+ rettv->vval.v_string = NULL;
+ else
+ rettv->vval.v_string =
do_browse(save ? BROWSE_SAVE : 0,
title, defname, NULL, initdir, NULL, curbuf);
#else
@@ -6858,10 +6980,13 @@ f_browsedir(argvars, rettv)
char_u *initdir;
char_u buf[NUMBUFLEN];
- title = get_tv_string(&argvars[0]);
- initdir = get_tv_string_buf(&argvars[1], buf);
+ title = get_tv_string_chk(&argvars[0]);
+ initdir = get_tv_string_buf_chk(&argvars[1], buf);
- rettv->vval.v_string = do_browse(BROWSE_DIR,
+ if (title == NULL || initdir == NULL)
+ rettv->vval.v_string = NULL;
+ else
+ rettv->vval.v_string = do_browse(BROWSE_DIR,
title, NULL, NULL, initdir, NULL, curbuf);
#else
rettv->vval.v_string = NULL;
@@ -6994,6 +7119,7 @@ f_bufname(argvars, rettv)
{
buf_T *buf;
+ (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */
++emsg_off;
buf = get_buf_tv(&argvars[0]);
rettv->v_type = VAR_STRING;
@@ -7014,6 +7140,7 @@ f_bufnr(argvars, rettv)
{
buf_T *buf;
+ (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */
++emsg_off;
buf = get_buf_tv(&argvars[0]);
if (buf != NULL)
@@ -7037,6 +7164,7 @@ f_bufwinnr(argvars, rettv)
#endif
buf_T *buf;
+ (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */
++emsg_off;
buf = get_buf_tv(&argvars[0]);
#ifdef FEAT_WINDOWS
@@ -7067,7 +7195,7 @@ f_byte2line(argvars, rettv)
#else
long boff = 0;
- boff = get_tv_number(&argvars[0]) - 1;
+ boff = get_tv_number(&argvars[0]) - 1; /* boff gets -1 on type error */
if (boff < 0)
rettv->vval.v_number = -1;
else
@@ -7091,10 +7219,10 @@ f_byteidx(argvars, rettv)
char_u *str;
long idx;
- str = get_tv_string(&argvars[0]);
- idx = get_tv_number(&argvars[1]);
+ str = get_tv_string_chk(&argvars[0]);
+ idx = get_tv_number_chk(&argvars[1], NULL);
rettv->vval.v_number = -1;
- if (idx < 0)
+ if (str == NULL || idx < 0)
return;
#ifdef FEAT_MBYTE
@@ -7140,6 +7268,8 @@ f_call(argvars, rettv)
func = argvars[0].vval.v_string;
else
func = get_tv_string(&argvars[0]);
+ if (*func == NUL)
+ return; /* type error or empty name */
if (argvars[2].v_type != VAR_UNKNOWN)
{
@@ -7185,8 +7315,7 @@ f_char2nr(argvars, rettv)
{
#ifdef FEAT_MBYTE
if (has_mbyte)
- rettv->vval.v_number =
- (*mb_ptr2char)(get_tv_string(&argvars[0]));
+ rettv->vval.v_number = (*mb_ptr2char)(get_tv_string(&argvars[0]));
else
#endif
rettv->vval.v_number = get_tv_string(&argvars[0])[0];
@@ -7285,26 +7414,35 @@ f_confirm(argvars, rettv)
char_u buf2[NUMBUFLEN];
int def = 1;
int type = VIM_GENERIC;
- int c;
+ char_u *typestr;
+ int error = FALSE;
- message = get_tv_string(&argvars[0]);
+ message = get_tv_string_chk(&argvars[0]);
+ if (message == NULL)
+ error = TRUE;
if (argvars[1].v_type != VAR_UNKNOWN)
{
- buttons = get_tv_string_buf(&argvars[1], buf);
+ buttons = get_tv_string_buf_chk(&argvars[1], buf);
+ if (buttons == NULL)
+ error = TRUE;
if (argvars[2].v_type != VAR_UNKNOWN)
{
- def = get_tv_number(&argvars[2]);
+ def = get_tv_number_chk(&argvars[2], &error);
if (argvars[3].v_type != VAR_UNKNOWN)
{
- /* avoid that TOUPPER_ASC calls get_tv_string_buf() twice */
- c = *get_tv_string_buf(&argvars[3], buf2);
- switch (TOUPPER_ASC(c))
+ typestr = get_tv_string_buf_chk(&argvars[3], buf2);
+ if (typestr == NULL)
+ error = TRUE;
+ else
{
- case 'E': type = VIM_ERROR; break;
- case 'Q': type = VIM_QUESTION; break;
- case 'I': type = VIM_INFO; break;
- case 'W': type = VIM_WARNING; break;
- case 'G': type = VIM_GENERIC; break;
+ switch (TOUPPER_ASC(*typestr))
+ {
+ case 'E': type = VIM_ERROR; break;
+ case 'Q': type = VIM_QUESTION; break;
+ case 'I': type = VIM_INFO; break;
+ case 'W': type = VIM_WARNING; break;
+ case 'G': type = VIM_GENERIC; break;
+ }
}
}
}
@@ -7313,7 +7451,10 @@ f_confirm(argvars, rettv)
if (buttons == NULL || *buttons == NUL)
buttons = (char_u *)_("&Ok");
- rettv->vval.v_number = do_dialog(type, NULL, message, buttons,
+ if (error)
+ rettv->vval.v_number = 0;
+ else
+ rettv->vval.v_number = do_dialog(type, NULL, message, buttons,
def, NULL);
#else
rettv->vval.v_number = 0;
@@ -7353,14 +7494,21 @@ f_count(argvars, rettv)
li = l->lv_first;
if (argvars[2].v_type != VAR_UNKNOWN)
{
- ic = get_tv_number(&argvars[2]);
+ int error = FALSE;
+
+ ic = get_tv_number_chk(&argvars[2], &error);
if (argvars[3].v_type != VAR_UNKNOWN)
{
- idx = get_tv_number(&argvars[3]);
- li = list_find(l, idx);
- if (li == NULL)
- EMSGN(_(e_listidx), idx);
+ idx = get_tv_number_chk(&argvars[3], &error);
+ if (!error)
+ {
+ li = list_find(l, idx);
+ if (li == NULL)
+ EMSGN(_(e_listidx), idx);
+ }
}
+ if (error)
+ li = NULL;
}
for ( ; li != NULL; li = li->li_next)
@@ -7376,14 +7524,16 @@ f_count(argvars, rettv)
if ((d = argvars[0].vval.v_dict) != NULL)
{
+ int error = FALSE;
+
if (argvars[2].v_type != VAR_UNKNOWN)
{
- ic = get_tv_number(&argvars[2]);
+ ic = get_tv_number_chk(&argvars[2], &error);
if (argvars[3].v_type != VAR_UNKNOWN)
EMSG(_(e_invarg));
}
- todo = d->dv_hashtab.ht_used;
+ todo = error ? 0 : d->dv_hashtab.ht_used;
for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi)
{
if (!HASHITEM_EMPTY(hi))
@@ -7446,9 +7596,11 @@ f_cursor(argvars, rettv)
long line, col;
line = get_tv_lnum(argvars);
+ col = get_tv_number_chk(&argvars[1], NULL);
+ if (line < 0 || col < 0)
+ return; /* type error; errmsg already given */
if (line > 0)
curwin->w_cursor.lnum = line;
- col = get_tv_number(&argvars[1]);
if (col > 0)
curwin->w_cursor.col = col - 1;
#ifdef FEAT_VIRTUALEDIT
@@ -7478,7 +7630,7 @@ f_deepcopy(argvars, rettv)
int noref = 0;
if (argvars[1].v_type != VAR_UNKNOWN)
- noref = get_tv_number(&argvars[1]);
+ noref = get_tv_number_chk(&argvars[1], NULL);
if (noref < 0 || noref > 1)
EMSG(_(e_invarg));
else
@@ -7549,6 +7701,8 @@ f_diff_hlID(argvars, rettv)
int filler_lines;
int col;
+ if (lnum < 0) /* ignore type error in {lnum} arg */
+ lnum = 0;
if (lnum != prev_lnum
|| changedtick != curbuf->b_changedtick
|| fnum != curbuf->b_fnum)
@@ -7578,7 +7732,7 @@ f_diff_hlID(argvars, rettv)
if (hlID == HLF_CHD || hlID == HLF_TXD)
{
- col = get_tv_number(&argvars[1]) - 1;
+ col = get_tv_number(&argvars[1]) - 1; /* ignore type error in {col} */
if (col >= change_start && col <= change_end)
hlID = HLF_TXD; /* changed text */
else
@@ -7650,11 +7804,15 @@ f_eval(argvars, rettv)
{
char_u *s;
- s = get_tv_string(&argvars[0]);
- s = skipwhite(s);
+ s = get_tv_string_chk(&argvars[0]);
+ if (s != NULL)
+ s = skipwhite(s);
- if (eval1(&s, rettv, TRUE) == FAIL)
+ if (s == NULL || eval1(&s, rettv, TRUE) == FAIL)
+ {
+ rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = 0;
+ }
else if (*s != NUL)
EMSG(_(e_trailing));
}
@@ -7772,6 +7930,7 @@ f_expand(argvars, rettv)
char_u *errormsg;
int flags = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND;
expand_T xpc;
+ int error = FALSE;
rettv->v_type = VAR_STRING;
s = get_tv_string(&argvars[0]);
@@ -7785,12 +7944,18 @@ f_expand(argvars, rettv)
{
/* When the optional second argument is non-zero, don't remove matches
* for 'suffixes' and 'wildignore' */
- if (argvars[1].v_type != VAR_UNKNOWN && get_tv_number(&argvars[1]))
+ if (argvars[1].v_type != VAR_UNKNOWN
+ && get_tv_number_chk(&argvars[1], &error))
flags |= WILD_KEEP_ALL;
- ExpandInit(&xpc);
- xpc.xp_context = EXPAND_FILES;
- rettv->vval.v_string = ExpandOne(&xpc, s, NULL, flags, WILD_ALL);
- ExpandCleanup(&xpc);
+ if (!error)
+ {
+ ExpandInit(&xpc);
+ xpc.xp_context = EXPAND_FILES;
+ rettv->vval.v_string = ExpandOne(&xpc, s, NULL, flags, WILD_ALL);
+ ExpandCleanup(&xpc);
+ }
+ else
+ rettv->vval.v_string = NULL;
}
}
@@ -7809,6 +7974,7 @@ f_extend(argvars, rettv)
list_T *l1, *l2;
listitem_T *item;
long before;
+ int error = FALSE;
l1 = argvars[0].vval.v_list;
l2 = argvars[1].vval.v_list;
@@ -7817,7 +7983,10 @@ f_extend(argvars, rettv)
{
if (argvars[2].v_type != VAR_UNKNOWN)
{
- before = get_tv_number(&argvars[2]);
+ before = get_tv_number_chk(&argvars[2], &error);
+ if (error)
+ return; /* type error; errmsg already given */
+
if (before == l1->lv_len)
item = NULL;
else
@@ -7857,7 +8026,9 @@ f_extend(argvars, rettv)
{
static char *(av[]) = {"keep", "force", "error"};
- action = get_tv_string(&argvars[2]);
+ action = get_tv_string_chk(&argvars[2]);
+ if (action == NULL)
+ return; /* type error; errmsg already given */
for (i = 0; i < 3; ++i)
if (STRCMP(action, av[i]) == 0)
break;
@@ -7963,22 +8134,30 @@ findfilendir(argvars, rettv, dir)
if (argvars[1].v_type != VAR_UNKNOWN)
{
- p = get_tv_string_buf(&argvars[1], pathbuf);
- if (*p != NUL)
- path = p;
+ p = get_tv_string_buf_chk(&argvars[1], pathbuf);
+ if (p == NULL)
+ count = -1; /* error */
+ else
+ {
+ if (*p != NUL)
+ path = p;
- if (argvars[2].v_type != VAR_UNKNOWN)
- count = get_tv_number(&argvars[2]);
+ if (argvars[2].v_type != VAR_UNKNOWN)
+ count = get_tv_number_chk(&argvars[2], NULL); /* -1: error */
+ }
}
- do
+ if (*fname != NUL && count >= 0)
{
- vim_free(fresult);
- fresult = find_file_in_path_option(first ? fname : NULL,
- first ? (int)STRLEN(fname) : 0,
- 0, first, path, dir, NULL);
- first = FALSE;
- } while (--count > 0 && fresult != NULL);
+ do
+ {
+ vim_free(fresult);
+ fresult = find_file_in_path_option(first ? fname : NULL,
+ first ? (int)STRLEN(fname) : 0,
+ 0, first, path, dir, NULL);
+ first = FALSE;
+ } while (--count > 0 && fresult != NULL);
+ }
rettv->vval.v_string = fresult;
#else
@@ -8073,53 +8252,60 @@ filter_map(argvars, rettv, map)
return;
}
- prepare_vimvar(VV_VAL, &save_val);
- expr = skipwhite(get_tv_string_buf(&argvars[1], buf));
-
- if (argvars[0].v_type == VAR_DICT)
+ expr = get_tv_string_buf_chk(&argvars[1], buf);
+ /* On type errors, the preceding call has already displayed an error
+ * message. Avoid a misleading error message for an empty string that
+ * was not passed as argument. */
+ if (expr != NULL)
{
- prepare_vimvar(VV_KEY, &save_key);
- vimvars[VV_KEY].vv_type = VAR_STRING;
+ prepare_vimvar(VV_VAL, &save_val);
+ expr = skipwhite(expr);
- ht = &d->dv_hashtab;
- hash_lock(ht);
- todo = ht->ht_used;
- for (hi = ht->ht_array; todo > 0; ++hi)
+ if (argvars[0].v_type == VAR_DICT)
{
- if (!HASHITEM_EMPTY(hi))
+ prepare_vimvar(VV_KEY, &save_key);
+ vimvars[VV_KEY].vv_type = VAR_STRING;
+
+ ht = &d->dv_hashtab;
+ hash_lock(ht);
+ todo = ht->ht_used;
+ for (hi = ht->ht_array; todo > 0; ++hi)
{
- --todo;
- di = HI2DI(hi);
- if (tv_check_lock(di->di_tv.v_lock, msg))
+ if (!HA