summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2019-09-04 14:41:14 +0200
committerBram Moolenaar <Bram@vim.org>2019-09-04 14:41:14 +0200
commit1e1d30048e722906a13665bd6c3c24c87eb2fe25 (patch)
treefd5236bfbab6ad7cd51d758a91f1c41f02d15b51 /src
parent19c8fe1925f4f7ffa1cc46e64d8bb8b1665ac437 (diff)
patch 8.1.1978: the eval.c file is too bigv8.1.1978
Problem: The eval.c file is too big. Solution: Move filter() and map() to list.c.
Diffstat (limited to 'src')
-rw-r--r--src/eval.c195
-rw-r--r--src/evalfunc.c20
-rw-r--r--src/list.c218
-rw-r--r--src/proto/eval.pro3
-rw-r--r--src/proto/list.pro2
-rw-r--r--src/version.c2
6 files changed, 221 insertions, 219 deletions
diff --git a/src/eval.c b/src/eval.c
index 8da8205d50..f4db363828 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -7135,199 +7135,4 @@ do_string_sub(
return ret;
}
- static int
-filter_map_one(typval_T *tv, typval_T *expr, int map, int *remp)
-{
- typval_T rettv;
- typval_T argv[3];
- int retval = FAIL;
-
- copy_tv(tv, get_vim_var_tv(VV_VAL));
- argv[0] = *get_vim_var_tv(VV_KEY);
- argv[1] = *get_vim_var_tv(VV_VAL);
- if (eval_expr_typval(expr, argv, 2, &rettv) == FAIL)
- goto theend;
- if (map)
- {
- /* map(): replace the list item value */
- clear_tv(tv);
- rettv.v_lock = 0;
- *tv = rettv;
- }
- else
- {
- int error = FALSE;
-
- /* filter(): when expr is zero remove the item */
- *remp = (tv_get_number_chk(&rettv, &error) == 0);
- clear_tv(&rettv);
- /* On type error, nothing has been removed; return FAIL to stop the
- * loop. The error message was given by tv_get_number_chk(). */
- if (error)
- goto theend;
- }
- retval = OK;
-theend:
- clear_tv(get_vim_var_tv(VV_VAL));
- return retval;
-}
-
-/*
- * Implementation of map() and filter().
- */
- void
-filter_map(typval_T *argvars, typval_T *rettv, int map)
-{
- typval_T *expr;
- listitem_T *li, *nli;
- list_T *l = NULL;
- dictitem_T *di;
- hashtab_T *ht;
- hashitem_T *hi;
- dict_T *d = NULL;
- blob_T *b = NULL;
- int rem;
- int todo;
- char_u *ermsg = (char_u *)(map ? "map()" : "filter()");
- char_u *arg_errmsg = (char_u *)(map ? N_("map() argument")
- : N_("filter() argument"));
- int save_did_emsg;
- int idx = 0;
-
- if (argvars[0].v_type == VAR_BLOB)
- {
- if ((b = argvars[0].vval.v_blob) == NULL)
- return;
- }
- else if (argvars[0].v_type == VAR_LIST)
- {
- if ((l = argvars[0].vval.v_list) == NULL
- || (!map && var_check_lock(l->lv_lock, arg_errmsg, TRUE)))
- return;
- }
- else if (argvars[0].v_type == VAR_DICT)
- {
- if ((d = argvars[0].vval.v_dict) == NULL
- || (!map && var_check_lock(d->dv_lock, arg_errmsg, TRUE)))
- return;
- }
- else
- {
- semsg(_(e_listdictarg), ermsg);
- return;
- }
-
- expr = &argvars[1];
- /* 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->v_type != VAR_UNKNOWN)
- {
- typval_T save_val;
- typval_T save_key;
-
- prepare_vimvar(VV_VAL, &save_val);
- prepare_vimvar(VV_KEY, &save_key);
-
- // We reset "did_emsg" to be able to detect whether an error
- // occurred during evaluation of the expression.
- save_did_emsg = did_emsg;
- did_emsg = FALSE;
-
- if (argvars[0].v_type == VAR_DICT)
- {
- ht = &d->dv_hashtab;
- hash_lock(ht);
- todo = (int)ht->ht_used;
- for (hi = ht->ht_array; todo > 0; ++hi)
- {
- if (!HASHITEM_EMPTY(hi))
- {
- int r;
-
- --todo;
- di = HI2DI(hi);
- if (map && (var_check_lock(di->di_tv.v_lock,
- arg_errmsg, TRUE)
- || var_check_ro(di->di_flags,
- arg_errmsg, TRUE)))
- break;
- set_vim_var_string(VV_KEY, di->di_key, -1);
- r = filter_map_one(&di->di_tv, expr, map, &rem);
- clear_tv(get_vim_var_tv(VV_KEY));
- if (r == FAIL || did_emsg)
- break;
- if (!map && rem)
- {
- if (var_check_fixed(di->di_flags, arg_errmsg, TRUE)
- || var_check_ro(di->di_flags, arg_errmsg, TRUE))
- break;
- dictitem_remove(d, di);
- }
- }
- }
- hash_unlock(ht);
- }
- else if (argvars[0].v_type == VAR_BLOB)
- {
- int i;
- typval_T tv;
-
- // set_vim_var_nr() doesn't set the type
- set_vim_var_type(VV_KEY, VAR_NUMBER);
-
- for (i = 0; i < b->bv_ga.ga_len; i++)
- {
- tv.v_type = VAR_NUMBER;
- tv.vval.v_number = blob_get(b, i);
- set_vim_var_nr(VV_KEY, idx);
- if (filter_map_one(&tv, expr, map, &rem) == FAIL || did_emsg)
- break;
- if (tv.v_type != VAR_NUMBER)
- {
- emsg(_(e_invalblob));
- break;
- }
- tv.v_type = VAR_NUMBER;
- blob_set(b, i, tv.vval.v_number);
- if (!map && rem)
- {
- char_u *p = (char_u *)argvars[0].vval.v_blob->bv_ga.ga_data;
-
- mch_memmove(p + idx, p + i + 1,
- (size_t)b->bv_ga.ga_len - i - 1);
- --b->bv_ga.ga_len;
- --i;
- }
- }
- }
- else // argvars[0].v_type == VAR_LIST
- {
- // set_vim_var_nr() doesn't set the type
- set_vim_var_type(VV_KEY, VAR_NUMBER);
-
- for (li = l->lv_first; li != NULL; li = nli)
- {
- if (map && var_check_lock(li->li_tv.v_lock, arg_errmsg, TRUE))
- break;
- nli = li->li_next;
- set_vim_var_nr(VV_KEY, idx);
- if (filter_map_one(&li->li_tv, expr, map, &rem) == FAIL
- || did_emsg)
- break;
- if (!map && rem)
- listitem_remove(l, li);
- ++idx;
- }
- }
-
- restore_vimvar(VV_KEY, &save_key);
- restore_vimvar(VV_VAL, &save_val);
-
- did_emsg |= save_did_emsg;
- }
-
- copy_tv(&argvars[0], rettv);
-}
-
#endif /* defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) */
diff --git a/src/evalfunc.c b/src/evalfunc.c
index bf4bb8eb9b..eac37ed27e 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -106,7 +106,6 @@ static void f_extend(typval_T *argvars, typval_T *rettv);
static void f_feedkeys(typval_T *argvars, typval_T *rettv);
static void f_filereadable(typval_T *argvars, typval_T *rettv);
static void f_filewritable(typval_T *argvars, typval_T *rettv);
-static void f_filter(typval_T *argvars, typval_T *rettv);
static void f_finddir(typval_T *argvars, typval_T *rettv);
static void f_findfile(typval_T *argvars, typval_T *rettv);
#ifdef FEAT_FLOAT
@@ -192,7 +191,6 @@ static void f_log10(typval_T *argvars, typval_T *rettv);
#ifdef FEAT_LUA
static void f_luaeval(typval_T *argvars, typval_T *rettv);
#endif
-static void f_map(typval_T *argvars, typval_T *rettv);
static void f_maparg(typval_T *argvars, typval_T *rettv);
static void f_mapcheck(typval_T *argvars, typval_T *rettv);
static void f_match(typval_T *argvars, typval_T *rettv);
@@ -3511,15 +3509,6 @@ findfilendir(
}
/*
- * "filter()" function
- */
- static void
-f_filter(typval_T *argvars, typval_T *rettv)
-{
- filter_map(argvars, rettv, FALSE);
-}
-
-/*
* "finddir({fname}[, {path}[, {count}]])" function
*/
static void
@@ -6801,15 +6790,6 @@ f_luaeval(typval_T *argvars, typval_T *rettv)
#endif
/*
- * "map()" function
- */
- static void
-f_map(typval_T *argvars, typval_T *rettv)
-{
- filter_map(argvars, rettv, TRUE);
-}
-
-/*
* "maparg()" function
*/
static void
diff --git a/src/list.c b/src/list.c
index a0c710df66..040c5799bb 100644
--- a/src/list.c
+++ b/src/list.c
@@ -1547,4 +1547,220 @@ f_uniq(typval_T *argvars, typval_T *rettv)
do_sort_uniq(argvars, rettv, FALSE);
}
-#endif /* defined(FEAT_EVAL) */
+/*
+ * Handle one item for map() and filter().
+ */
+ static int
+filter_map_one(typval_T *tv, typval_T *expr, int map, int *remp)
+{
+ typval_T rettv;
+ typval_T argv[3];
+ int retval = FAIL;
+
+ copy_tv(tv, get_vim_var_tv(VV_VAL));
+ argv[0] = *get_vim_var_tv(VV_KEY);
+ argv[1] = *get_vim_var_tv(VV_VAL);
+ if (eval_expr_typval(expr, argv, 2, &rettv) == FAIL)
+ goto theend;
+ if (map)
+ {
+ // map(): replace the list item value
+ clear_tv(tv);
+ rettv.v_lock = 0;
+ *tv = rettv;
+ }
+ else
+ {
+ int error = FALSE;
+
+ // filter(): when expr is zero remove the item
+ *remp = (tv_get_number_chk(&rettv, &error) == 0);
+ clear_tv(&rettv);
+ // On type error, nothing has been removed; return FAIL to stop the
+ // loop. The error message was given by tv_get_number_chk().
+ if (error)
+ goto theend;
+ }
+ retval = OK;
+theend:
+ clear_tv(get_vim_var_tv(VV_VAL));
+ return retval;
+}
+
+/*
+ * Implementation of map() and filter().
+ */
+ static void
+filter_map(typval_T *argvars, typval_T *rettv, int map)
+{
+ typval_T *expr;
+ listitem_T *li, *nli;
+ list_T *l = NULL;
+ dictitem_T *di;
+ hashtab_T *ht;
+ hashitem_T *hi;
+ dict_T *d = NULL;
+ blob_T *b = NULL;
+ int rem;
+ int todo;
+ char_u *ermsg = (char_u *)(map ? "map()" : "filter()");
+ char_u *arg_errmsg = (char_u *)(map ? N_("map() argument")
+ : N_("filter() argument"));
+ int save_did_emsg;
+ int idx = 0;
+
+ if (argvars[0].v_type == VAR_BLOB)
+ {
+ if ((b = argvars[0].vval.v_blob) == NULL)
+ return;
+ }
+ else if (argvars[0].v_type == VAR_LIST)
+ {
+ if ((l = argvars[0].vval.v_list) == NULL
+ || (!map && var_check_lock(l->lv_lock, arg_errmsg, TRUE)))
+ return;
+ }
+ else if (argvars[0].v_type == VAR_DICT)
+ {
+ if ((d = argvars[0].vval.v_dict) == NULL
+ || (!map && var_check_lock(d->dv_lock, arg_errmsg, TRUE)))
+ return;
+ }
+ else
+ {
+ semsg(_(e_listdictarg), ermsg);
+ return;
+ }
+
+ expr = &argvars[1];
+ // 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->v_type != VAR_UNKNOWN)
+ {
+ typval_T save_val;
+ typval_T save_key;
+
+ prepare_vimvar(VV_VAL, &save_val);
+ prepare_vimvar(VV_KEY, &save_key);
+
+ // We reset "did_emsg" to be able to detect whether an error
+ // occurred during evaluation of the expression.
+ save_did_emsg = did_emsg;
+ did_emsg = FALSE;
+
+ if (argvars[0].v_type == VAR_DICT)
+ {
+ ht = &d->dv_hashtab;
+ hash_lock(ht);
+ todo = (int)ht->ht_used;
+ for (hi = ht->ht_array; todo > 0; ++hi)
+ {
+ if (!HASHITEM_EMPTY(hi))
+ {
+ int r;
+
+ --todo;
+ di = HI2DI(hi);
+ if (map && (var_check_lock(di->di_tv.v_lock,
+ arg_errmsg, TRUE)
+ || var_check_ro(di->di_flags,
+ arg_errmsg, TRUE)))
+ break;
+ set_vim_var_string(VV_KEY, di->di_key, -1);
+ r = filter_map_one(&di->di_tv, expr, map, &rem);
+ clear_tv(get_vim_var_tv(VV_KEY));
+ if (r == FAIL || did_emsg)
+ break;
+ if (!map && rem)
+ {
+ if (var_check_fixed(di->di_flags, arg_errmsg, TRUE)
+ || var_check_ro(di->di_flags, arg_errmsg, TRUE))
+ break;
+ dictitem_remove(d, di);
+ }
+ }
+ }
+ hash_unlock(ht);
+ }
+ else if (argvars[0].v_type == VAR_BLOB)
+ {
+ int i;
+ typval_T tv;
+
+ // set_vim_var_nr() doesn't set the type
+ set_vim_var_type(VV_KEY, VAR_NUMBER);
+
+ for (i = 0; i < b->bv_ga.ga_len; i++)
+ {
+ tv.v_type = VAR_NUMBER;
+ tv.vval.v_number = blob_get(b, i);
+ set_vim_var_nr(VV_KEY, idx);
+ if (filter_map_one(&tv, expr, map, &rem) == FAIL || did_emsg)
+ break;
+ if (tv.v_type != VAR_NUMBER)
+ {
+ emsg(_(e_invalblob));
+ break;
+ }
+ tv.v_type = VAR_NUMBER;
+ blob_set(b, i, tv.vval.v_number);
+ if (!map && rem)
+ {
+ char_u *p = (char_u *)argvars[0].vval.v_blob->bv_ga.ga_data;
+
+ mch_memmove(p + idx, p + i + 1,
+ (size_t)b->bv_ga.ga_len - i - 1);
+ --b->bv_ga.ga_len;
+ --i;
+ }
+ }
+ }
+ else // argvars[0].v_type == VAR_LIST
+ {
+ // set_vim_var_nr() doesn't set the type
+ set_vim_var_type(VV_KEY, VAR_NUMBER);
+
+ for (li = l->lv_first; li != NULL; li = nli)
+ {
+ if (map && var_check_lock(li->li_tv.v_lock, arg_errmsg, TRUE))
+ break;
+ nli = li->li_next;
+ set_vim_var_nr(VV_KEY, idx);
+ if (filter_map_one(&li->li_tv, expr, map, &rem) == FAIL
+ || did_emsg)
+ break;
+ if (!map && rem)
+ listitem_remove(l, li);
+ ++idx;
+ }
+ }
+
+ restore_vimvar(VV_KEY, &save_key);
+ restore_vimvar(VV_VAL, &save_val);
+
+ did_emsg |= save_did_emsg;
+ }
+
+ copy_tv(&argvars[0], rettv);
+}
+
+/*
+ * "filter()" function
+ */
+ void
+f_filter(typval_T *argvars, typval_T *rettv)
+{
+ filter_map(argvars, rettv, FALSE);
+}
+
+/*
+ * "map()" function
+ */
+ void
+f_map(typval_T *argvars, typval_T *rettv)
+{
+ filter_map(argvars, rettv, TRUE);
+}
+
+#endif // defined(FEAT_EVAL)
diff --git a/src/proto/eval.pro b/src/proto/eval.pro
index b91774b540..9ab1ade71c 100644
--- a/src/proto/eval.pro
+++ b/src/proto/eval.pro
@@ -11,8 +11,6 @@ int skip_expr(char_u **pp);
char_u *eval_to_string(char_u *arg, char_u **nextcmd, int convert);
char_u *eval_to_string_safe(char_u *arg, char_u **nextcmd, int use_sandbox);
varnumber_T eval_to_number(char_u *expr);
-list_T *eval_spell_expr(char_u *badword, char_u *expr);
-int get_spellword(list_T *list, char_u **pp);
typval_T *eval_expr(char_u *arg, char_u **nextcmd);
int call_vim_function(char_u *func, int argc, typval_T *argv, typval_T *rettv);
varnumber_T call_func_retnr(char_u *func, int argc, typval_T *argv);
@@ -78,5 +76,4 @@ int typval_compare(typval_T *typ1, typval_T *typ2, exptype_T type, int type_is,
char_u *typval_tostring(typval_T *arg);
int modify_fname(char_u *src, int tilde_file, int *usedlen, char_u **fnamep, char_u **bufp, int *fnamelen);
char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub, typval_T *expr, char_u *flags);
-void filter_map(typval_T *argvars, typval_T *rettv, int map);
/* vim: set ft=c : */
diff --git a/src/proto/list.pro b/src/proto/list.pro
index 3102bb288d..7a1ce7ac30 100644
--- a/src/proto/list.pro
+++ b/src/proto/list.pro
@@ -41,4 +41,6 @@ void f_list2str(typval_T *argvars, typval_T *rettv);
void list_remove(typval_T *argvars, typval_T *rettv, char_u *arg_errmsg);
void f_sort(typval_T *argvars, typval_T *rettv);
void f_uniq(typval_T *argvars, typval_T *rettv);
+void f_filter(typval_T *argvars, typval_T *rettv);
+void f_map(typval_T *argvars, typval_T *rettv);
/* vim: set ft=c : */
diff --git a/src/version.c b/src/version.c
index 9481a3d6b6..3e06f92d24 100644
--- a/src/version.c
+++ b/src/version.c
@@ -762,6 +762,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1978,
+/**/
1977,
/**/
1976,