Mercurial > vim
comparison src/eval.c @ 17964:6d4d3bce365d v8.1.1978
patch 8.1.1978: the eval.c file is too big
Commit: https://github.com/vim/vim/commit/1e1d30048e722906a13665bd6c3c24c87eb2fe25
Author: Bram Moolenaar <Bram@vim.org>
Date: Wed Sep 4 14:41:14 2019 +0200
patch 8.1.1978: the eval.c file is too big
Problem: The eval.c file is too big.
Solution: Move filter() and map() to list.c.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Wed, 04 Sep 2019 14:45:04 +0200 |
parents | 7f3283683d97 |
children | 46f95606b9ec |
comparison
equal
deleted
inserted
replaced
17963:5de9b5831cd4 | 17964:6d4d3bce365d |
---|---|
7133 free_string_option(save_cpo); | 7133 free_string_option(save_cpo); |
7134 | 7134 |
7135 return ret; | 7135 return ret; |
7136 } | 7136 } |
7137 | 7137 |
7138 static int | |
7139 filter_map_one(typval_T *tv, typval_T *expr, int map, int *remp) | |
7140 { | |
7141 typval_T rettv; | |
7142 typval_T argv[3]; | |
7143 int retval = FAIL; | |
7144 | |
7145 copy_tv(tv, get_vim_var_tv(VV_VAL)); | |
7146 argv[0] = *get_vim_var_tv(VV_KEY); | |
7147 argv[1] = *get_vim_var_tv(VV_VAL); | |
7148 if (eval_expr_typval(expr, argv, 2, &rettv) == FAIL) | |
7149 goto theend; | |
7150 if (map) | |
7151 { | |
7152 /* map(): replace the list item value */ | |
7153 clear_tv(tv); | |
7154 rettv.v_lock = 0; | |
7155 *tv = rettv; | |
7156 } | |
7157 else | |
7158 { | |
7159 int error = FALSE; | |
7160 | |
7161 /* filter(): when expr is zero remove the item */ | |
7162 *remp = (tv_get_number_chk(&rettv, &error) == 0); | |
7163 clear_tv(&rettv); | |
7164 /* On type error, nothing has been removed; return FAIL to stop the | |
7165 * loop. The error message was given by tv_get_number_chk(). */ | |
7166 if (error) | |
7167 goto theend; | |
7168 } | |
7169 retval = OK; | |
7170 theend: | |
7171 clear_tv(get_vim_var_tv(VV_VAL)); | |
7172 return retval; | |
7173 } | |
7174 | |
7175 /* | |
7176 * Implementation of map() and filter(). | |
7177 */ | |
7178 void | |
7179 filter_map(typval_T *argvars, typval_T *rettv, int map) | |
7180 { | |
7181 typval_T *expr; | |
7182 listitem_T *li, *nli; | |
7183 list_T *l = NULL; | |
7184 dictitem_T *di; | |
7185 hashtab_T *ht; | |
7186 hashitem_T *hi; | |
7187 dict_T *d = NULL; | |
7188 blob_T *b = NULL; | |
7189 int rem; | |
7190 int todo; | |
7191 char_u *ermsg = (char_u *)(map ? "map()" : "filter()"); | |
7192 char_u *arg_errmsg = (char_u *)(map ? N_("map() argument") | |
7193 : N_("filter() argument")); | |
7194 int save_did_emsg; | |
7195 int idx = 0; | |
7196 | |
7197 if (argvars[0].v_type == VAR_BLOB) | |
7198 { | |
7199 if ((b = argvars[0].vval.v_blob) == NULL) | |
7200 return; | |
7201 } | |
7202 else if (argvars[0].v_type == VAR_LIST) | |
7203 { | |
7204 if ((l = argvars[0].vval.v_list) == NULL | |
7205 || (!map && var_check_lock(l->lv_lock, arg_errmsg, TRUE))) | |
7206 return; | |
7207 } | |
7208 else if (argvars[0].v_type == VAR_DICT) | |
7209 { | |
7210 if ((d = argvars[0].vval.v_dict) == NULL | |
7211 || (!map && var_check_lock(d->dv_lock, arg_errmsg, TRUE))) | |
7212 return; | |
7213 } | |
7214 else | |
7215 { | |
7216 semsg(_(e_listdictarg), ermsg); | |
7217 return; | |
7218 } | |
7219 | |
7220 expr = &argvars[1]; | |
7221 /* On type errors, the preceding call has already displayed an error | |
7222 * message. Avoid a misleading error message for an empty string that | |
7223 * was not passed as argument. */ | |
7224 if (expr->v_type != VAR_UNKNOWN) | |
7225 { | |
7226 typval_T save_val; | |
7227 typval_T save_key; | |
7228 | |
7229 prepare_vimvar(VV_VAL, &save_val); | |
7230 prepare_vimvar(VV_KEY, &save_key); | |
7231 | |
7232 // We reset "did_emsg" to be able to detect whether an error | |
7233 // occurred during evaluation of the expression. | |
7234 save_did_emsg = did_emsg; | |
7235 did_emsg = FALSE; | |
7236 | |
7237 if (argvars[0].v_type == VAR_DICT) | |
7238 { | |
7239 ht = &d->dv_hashtab; | |
7240 hash_lock(ht); | |
7241 todo = (int)ht->ht_used; | |
7242 for (hi = ht->ht_array; todo > 0; ++hi) | |
7243 { | |
7244 if (!HASHITEM_EMPTY(hi)) | |
7245 { | |
7246 int r; | |
7247 | |
7248 --todo; | |
7249 di = HI2DI(hi); | |
7250 if (map && (var_check_lock(di->di_tv.v_lock, | |
7251 arg_errmsg, TRUE) | |
7252 || var_check_ro(di->di_flags, | |
7253 arg_errmsg, TRUE))) | |
7254 break; | |
7255 set_vim_var_string(VV_KEY, di->di_key, -1); | |
7256 r = filter_map_one(&di->di_tv, expr, map, &rem); | |
7257 clear_tv(get_vim_var_tv(VV_KEY)); | |
7258 if (r == FAIL || did_emsg) | |
7259 break; | |
7260 if (!map && rem) | |
7261 { | |
7262 if (var_check_fixed(di->di_flags, arg_errmsg, TRUE) | |
7263 || var_check_ro(di->di_flags, arg_errmsg, TRUE)) | |
7264 break; | |
7265 dictitem_remove(d, di); | |
7266 } | |
7267 } | |
7268 } | |
7269 hash_unlock(ht); | |
7270 } | |
7271 else if (argvars[0].v_type == VAR_BLOB) | |
7272 { | |
7273 int i; | |
7274 typval_T tv; | |
7275 | |
7276 // set_vim_var_nr() doesn't set the type | |
7277 set_vim_var_type(VV_KEY, VAR_NUMBER); | |
7278 | |
7279 for (i = 0; i < b->bv_ga.ga_len; i++) | |
7280 { | |
7281 tv.v_type = VAR_NUMBER; | |
7282 tv.vval.v_number = blob_get(b, i); | |
7283 set_vim_var_nr(VV_KEY, idx); | |
7284 if (filter_map_one(&tv, expr, map, &rem) == FAIL || did_emsg) | |
7285 break; | |
7286 if (tv.v_type != VAR_NUMBER) | |
7287 { | |
7288 emsg(_(e_invalblob)); | |
7289 break; | |
7290 } | |
7291 tv.v_type = VAR_NUMBER; | |
7292 blob_set(b, i, tv.vval.v_number); | |
7293 if (!map && rem) | |
7294 { | |
7295 char_u *p = (char_u *)argvars[0].vval.v_blob->bv_ga.ga_data; | |
7296 | |
7297 mch_memmove(p + idx, p + i + 1, | |
7298 (size_t)b->bv_ga.ga_len - i - 1); | |
7299 --b->bv_ga.ga_len; | |
7300 --i; | |
7301 } | |
7302 } | |
7303 } | |
7304 else // argvars[0].v_type == VAR_LIST | |
7305 { | |
7306 // set_vim_var_nr() doesn't set the type | |
7307 set_vim_var_type(VV_KEY, VAR_NUMBER); | |
7308 | |
7309 for (li = l->lv_first; li != NULL; li = nli) | |
7310 { | |
7311 if (map && var_check_lock(li->li_tv.v_lock, arg_errmsg, TRUE)) | |
7312 break; | |
7313 nli = li->li_next; | |
7314 set_vim_var_nr(VV_KEY, idx); | |
7315 if (filter_map_one(&li->li_tv, expr, map, &rem) == FAIL | |
7316 || did_emsg) | |
7317 break; | |
7318 if (!map && rem) | |
7319 listitem_remove(l, li); | |
7320 ++idx; | |
7321 } | |
7322 } | |
7323 | |
7324 restore_vimvar(VV_KEY, &save_key); | |
7325 restore_vimvar(VV_VAL, &save_val); | |
7326 | |
7327 did_emsg |= save_did_emsg; | |
7328 } | |
7329 | |
7330 copy_tv(&argvars[0], rettv); | |
7331 } | |
7332 | |
7333 #endif /* defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) */ | 7138 #endif /* defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) */ |