summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2005-01-27 14:44:31 +0000
committerBram Moolenaar <Bram@vim.org>2005-01-27 14:44:31 +0000
commit532c780ef0691152a20d0e2e176d1c0ef624cbde (patch)
treef543b7744b3fd8eae3e70de80268d2f3b496d759 /src
parentb2956cd2182352ede0cc5dc4508d0c9ffbe7e721 (diff)
updated for version 7.0045v7.0045
Diffstat (limited to 'src')
-rw-r--r--src/eval.c69
1 files changed, 54 insertions, 15 deletions
diff --git a/src/eval.c b/src/eval.c
index 1ef824b152..3a7d245309 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -116,6 +116,12 @@ static dictitem_T globvars_var;
#define globvarht globvardict.dv_hashtab
/*
+ * Old Vim variables such as "v:version" are also available without the "v:".
+ * Also in functions. We need a special hashtable for them.
+ */
+hashtab_T compat_hashtab;
+
+/*
* Array to hold the hashtab with variables local to each sourced script.
* Each item holds a variable (nameless) that points to the dict_T.
*/
@@ -213,7 +219,7 @@ typedef struct
typedef struct
{
dict_T *fd_dict; /* Dictionary used */
- char_u *fd_newkey; /* new key in "dict" */
+ char_u *fd_newkey; /* new key in "dict" in allocated memory */
dictitem_T *fd_di; /* Dictionary item used */
} funcdict_T;
@@ -599,6 +605,7 @@ eval_init()
init_var_dict(&globvardict, &globvars_var);
init_var_dict(&vimvardict, &vimvars_var);
+ hash_init(&compat_hashtab);
for (i = 0; i < VV_LEN; ++i)
{
@@ -613,8 +620,8 @@ eval_init()
/* add to v: scope dict */
hash_add(&vimvarht, p->vv_di.di_key);
if (p->vv_flags & VV_COMPAT)
- /* add to g: scope dict */
- hash_add(&globvardict.dv_hashtab, p->vv_di.di_key);
+ /* add to compat scope dict */
+ hash_add(&compat_hashtab, p->vv_di.di_key);
}
}
@@ -2548,7 +2555,9 @@ ex_call(eap)
len = STRLEN(tofree);
name = deref_func_name(tofree, &len);
- startarg = arg;
+ /* Skip white space to allow ":call func ()". Not good, but required for
+ * backward compatibility. */
+ startarg = skipwhite(arg);
rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */
if (*startarg != '(')
@@ -2815,12 +2824,12 @@ get_user_var_name(xp, idx)
expand_T *xp;
int idx;
{
- static int gdone;
- static int bdone;
- static int wdone;
- static int vidx;
- static hashitem_T *hi;
- hashtab_T *ht;
+ static long_u gdone;
+ static long_u bdone;
+ static long_u wdone;
+ static int vidx;
+ static hashitem_T *hi;
+ hashtab_T *ht;
if (idx == 0)
gdone = bdone = wdone = vidx = 0;
@@ -2830,6 +2839,8 @@ get_user_var_name(xp, idx)
{
if (gdone++ == 0)
hi = globvarht.ht_array;
+ else
+ ++hi;
while (HASHITEM_EMPTY(hi))
++hi;
if (STRNCMP("g:", xp->xp_pattern, 2) == 0)
@@ -2843,6 +2854,8 @@ get_user_var_name(xp, idx)
{
if (bdone++ == 0)
hi = ht->ht_array;
+ else
+ ++hi;
while (HASHITEM_EMPTY(hi))
++hi;
return cat_prefix_varname('b', hi->hi_key);
@@ -2859,6 +2872,8 @@ get_user_var_name(xp, idx)
{
if (bdone++ == 0)
hi = ht->ht_array;
+ else
+ ++hi;
while (HASHITEM_EMPTY(hi))
++hi;
return cat_prefix_varname('w', hi->hi_key);
@@ -5717,7 +5732,7 @@ static struct fst
{"string", 1, 1, f_string},
{"strlen", 1, 1, f_strlen},
{"strpart", 2, 3, f_strpart},
- {"strridx", 2, 2, f_strridx},
+ {"strridx", 2, 3, f_strridx},
{"strtrans", 1, 1, f_strtrans},
{"submatch", 1, 1, f_submatch},
{"substitute", 4, 4, f_substitute},
@@ -11791,9 +11806,10 @@ f_stridx(argvars, rettv)
if (argvars[2].v_type != VAR_UNKNOWN)
{
start_idx = get_tv_number(&argvars[2]);
- if (start_idx < 0 || start_idx >= (int)STRLEN(haystack))
+ if (start_idx >= (int)STRLEN(haystack))
return;
- haystack += start_idx;
+ if (start_idx >= 0)
+ haystack += start_idx;
}
pos = (char_u *)strstr((char *)haystack, (char *)needle);
@@ -11885,20 +11901,38 @@ f_strridx(argvars, rettv)
char_u *haystack;
char_u *rest;
char_u *lastmatch = NULL;
+ int haystack_len, end_idx;
needle = get_tv_string(&argvars[1]);
haystack = get_tv_string_buf(&argvars[0], buf);
+ haystack_len = STRLEN(haystack);
if (*needle == NUL)
/* Empty string matches past the end. */
- lastmatch = haystack + STRLEN(haystack);
+ lastmatch = haystack + haystack_len;
else
+ {
+ if (argvars[2].v_type != VAR_UNKNOWN)
+ {
+ /* Third argument: upper limit for index */
+ end_idx = get_tv_number(&argvars[2]);
+ if (end_idx < 0)
+ {
+ /* can never find a match */
+ rettv->vval.v_number = -1;
+ return;
+ }
+ }
+ else
+ end_idx = haystack_len;
+
for (rest = haystack; *rest != '\0'; ++rest)
{
rest = (char_u *)strstr((char *)rest, (char *)needle);
- if (rest == NULL)
+ if (rest == NULL || rest > haystack + end_idx)
break;
lastmatch = rest;
}
+ }
if (lastmatch == NULL)
rettv->vval.v_number = -1;
@@ -13408,6 +13442,11 @@ find_var_ht(name, varname)
if (vim_strchr(name, ':') != NULL)
return NULL;
*varname = name;
+
+ /* "version" is "v:version" in all scopes */
+ if (!HASHITEM_EMPTY(hash_find(&compat_hashtab, name)))
+ return &compat_hashtab;
+
if (current_funccal == NULL)
return &globvarht; /* global variable */
return &current_funccal->l_vars.dv_hashtab; /* l: variable */