summaryrefslogtreecommitdiffstats
path: root/src/eval.c
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/eval.c
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/eval.c')
-rw-r--r--src/eval.c195
1 files changed, 0 insertions, 195 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) */