Patch 8.1.1978

7 views
Skip to first unread message

Bram Moolenaar

unread,
Sep 4, 2019, 8:41:45 AM9/4/19
to vim...@googlegroups.com

Patch 8.1.1978
Problem: The eval.c file is too big.
Solution: Move filter() and map() to list.c.
Files: src/eval.c, src/proto/eval.pro, src/list.c, src/proto/list.pro,
src/evalfunc.c


*** ../vim-8.1.1977/src/eval.c 2019-09-02 20:44:02.688728142 +0200
--- src/eval.c 2019-09-04 14:35:07.071893489 +0200
***************
*** 7135,7333 ****
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) */
--- 7135,7138 ----
*** ../vim-8.1.1977/src/proto/eval.pro 2019-09-01 16:01:25.584754569 +0200
--- src/proto/eval.pro 2019-09-04 14:37:30.955327616 +0200
***************
*** 11,18 ****
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);
--- 11,16 ----
***************
*** 78,82 ****
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 : */
--- 76,79 ----
*** ../vim-8.1.1977/src/list.c 2019-08-20 20:13:40.326821952 +0200
--- src/list.c 2019-09-04 14:39:21.402891499 +0200
***************
*** 1547,1550 ****
do_sort_uniq(argvars, rettv, FALSE);
}

! #endif /* defined(FEAT_EVAL) */
--- 1547,1766 ----
do_sort_uniq(argvars, rettv, FALSE);
}

! /*
! * 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)
*** ../vim-8.1.1977/src/proto/list.pro 2019-08-20 20:13:40.330821936 +0200
--- src/proto/list.pro 2019-09-04 14:37:57.215224019 +0200
***************
*** 41,44 ****
--- 41,46 ----
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 : */
*** ../vim-8.1.1977/src/evalfunc.c 2019-09-04 13:21:22.602256970 +0200
--- src/evalfunc.c 2019-09-04 14:37:27.939339509 +0200
***************
*** 106,112 ****
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
--- 106,111 ----
***************
*** 192,198 ****
#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);
--- 191,196 ----
***************
*** 3511,3525 ****
}

/*
- * "filter()" function
- */
- static void
- f_filter(typval_T *argvars, typval_T *rettv)
- {
- filter_map(argvars, rettv, FALSE);
- }
-
- /*
* "finddir({fname}[, {path}[, {count}]])" function
*/
static void
--- 3509,3514 ----
***************
*** 6801,6815 ****
#endif

/*
- * "map()" function
- */
- static void
- f_map(typval_T *argvars, typval_T *rettv)
- {
- filter_map(argvars, rettv, TRUE);
- }
-
- /*
* "maparg()" function
*/
static void
--- 6790,6795 ----
*** ../vim-8.1.1977/src/version.c 2019-09-04 14:24:01.910445794 +0200
--- src/version.c 2019-09-04 14:40:20.918656024 +0200
***************
*** 763,764 ****
--- 763,766 ----
{ /* Add new patch number below this line */
+ /**/
+ 1978,
/**/

--
hundred-and-one symptoms of being an internet addict:
176. You lie, even to user-friends, about how long you were online yesterday.

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
Reply all
Reply to author
Forward
0 new messages