To: vim_dev@googlegroups.com Subject: Patch 8.1.1943 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.1.1943 Problem: More code can be moved to evalvars.c. Solution: Move it, clean up comments. Also move some window related functions to window.c. (Yegappan Lakshmanan, closes #4874) Files: src/eval.c, src/evalfunc.c, src/evalvars.c, src/proto/eval.pro, src/proto/evalvars.pro, src/proto/window.pro, src/window.c *** ../vim-8.1.1942/src/eval.c 2019-08-29 22:48:20.921069540 +0200 --- src/eval.c 2019-08-30 14:13:18.816480045 +0200 *************** *** 6514,6622 **** } /* - * Find window specified by "vp" in tabpage "tp". - */ - win_T * - find_win_by_nr( - typval_T *vp, - tabpage_T *tp) /* NULL for current tab page */ - { - win_T *wp; - int nr = (int)tv_get_number_chk(vp, NULL); - - if (nr < 0) - return NULL; - if (nr == 0) - return curwin; - - FOR_ALL_WINDOWS_IN_TAB(tp, wp) - { - if (nr >= LOWEST_WIN_ID) - { - if (wp->w_id == nr) - return wp; - } - else if (--nr <= 0) - break; - } - if (nr >= LOWEST_WIN_ID) - { - #ifdef FEAT_TEXT_PROP - // check tab-local popup windows - for (wp = tp->tp_first_popupwin; wp != NULL; wp = wp->w_next) - if (wp->w_id == nr) - return wp; - // check global popup windows - for (wp = first_popupwin; wp != NULL; wp = wp->w_next) - if (wp->w_id == nr) - return wp; - #endif - return NULL; - } - return wp; - } - - /* - * Find a window: When using a Window ID in any tab page, when using a number - * in the current tab page. - */ - win_T * - find_win_by_nr_or_id(typval_T *vp) - { - int nr = (int)tv_get_number_chk(vp, NULL); - - if (nr >= LOWEST_WIN_ID) - return win_id2wp(tv_get_number(vp)); - return find_win_by_nr(vp, NULL); - } - - /* - * Find window specified by "wvp" in tabpage "tvp". - * Returns the tab page in 'ptp' - */ - win_T * - find_tabwin( - typval_T *wvp, // VAR_UNKNOWN for current window - typval_T *tvp, // VAR_UNKNOWN for current tab page - tabpage_T **ptp) - { - win_T *wp = NULL; - tabpage_T *tp = NULL; - long n; - - if (wvp->v_type != VAR_UNKNOWN) - { - if (tvp->v_type != VAR_UNKNOWN) - { - n = (long)tv_get_number(tvp); - if (n >= 0) - tp = find_tabpage(n); - } - else - tp = curtab; - - if (tp != NULL) - { - wp = find_win_by_nr(wvp, tp); - if (wp == NULL && wvp->v_type == VAR_NUMBER - && wvp->vval.v_number != -1) - // A window with the specified number is not found - tp = NULL; - } - } - else - { - wp = curwin; - tp = curtab; - } - - if (ptp != NULL) - *ptp = tp; - - return wp; - } - - /* * Skip over the name of an option: "&option", "&g:option" or "&l:option". * "arg" points to the "&" or '+' when called, to "option" when returning. * Returns NULL when no option name found. Otherwise pointer to the char --- 6514,6519 ---- *** ../vim-8.1.1942/src/evalfunc.c 2019-08-27 22:48:12.737480696 +0200 --- src/evalfunc.c 2019-08-30 14:10:09.617713145 +0200 *************** *** 21,27 **** #endif #ifdef MACOS_X ! # include /* for time_t */ #endif static char *e_listblobarg = N_("E899: Argument of %s must be a List or Blob"); --- 21,27 ---- #endif #ifdef MACOS_X ! # include // for time_t #endif static char *e_listblobarg = N_("E899: Argument of %s must be a List or Blob"); *************** *** 129,135 **** static void f_get(typval_T *argvars, typval_T *rettv); static void f_getbufinfo(typval_T *argvars, typval_T *rettv); static void f_getbufline(typval_T *argvars, typval_T *rettv); - static void f_getbufvar(typval_T *argvars, typval_T *rettv); static void f_getchangelist(typval_T *argvars, typval_T *rettv); static void f_getchar(typval_T *argvars, typval_T *rettv); static void f_getcharmod(typval_T *argvars, typval_T *rettv); --- 129,134 ---- *************** *** 280,286 **** static void f_server2client(typval_T *argvars, typval_T *rettv); static void f_serverlist(typval_T *argvars, typval_T *rettv); static void f_setbufline(typval_T *argvars, typval_T *rettv); - static void f_setbufvar(typval_T *argvars, typval_T *rettv); static void f_setcharsearch(typval_T *argvars, typval_T *rettv); static void f_setcmdpos(typval_T *argvars, typval_T *rettv); static void f_setenv(typval_T *argvars, typval_T *rettv); --- 279,284 ---- *************** *** 4394,4466 **** } /* - * "getbufvar()" function - */ - static void - f_getbufvar(typval_T *argvars, typval_T *rettv) - { - buf_T *buf; - buf_T *save_curbuf; - char_u *varname; - dictitem_T *v; - int done = FALSE; - - (void)tv_get_number(&argvars[0]); /* issue errmsg if type error */ - varname = tv_get_string_chk(&argvars[1]); - ++emsg_off; - buf = tv_get_buf(&argvars[0], FALSE); - - rettv->v_type = VAR_STRING; - rettv->vval.v_string = NULL; - - if (buf != NULL && varname != NULL) - { - /* set curbuf to be our buf, temporarily */ - save_curbuf = curbuf; - curbuf = buf; - - if (*varname == '&') - { - if (varname[1] == NUL) - { - /* get all buffer-local options in a dict */ - dict_T *opts = get_winbuf_options(TRUE); - - if (opts != NULL) - { - rettv_dict_set(rettv, opts); - done = TRUE; - } - } - else if (get_option_tv(&varname, rettv, TRUE) == OK) - /* buffer-local-option */ - done = TRUE; - } - else - { - /* Look up the variable. */ - /* Let getbufvar({nr}, "") return the "b:" dictionary. */ - v = find_var_in_ht(&curbuf->b_vars->dv_hashtab, - 'b', varname, FALSE); - if (v != NULL) - { - copy_tv(&v->di_tv, rettv); - done = TRUE; - } - } - - /* restore previous notion of curbuf */ - curbuf = save_curbuf; - } - - if (!done && argvars[2].v_type != VAR_UNKNOWN) - /* use the default value */ - copy_tv(&argvars[2], rettv); - - --emsg_off; - } - - /* * "getchangelist()" function */ static void --- 4392,4397 ---- *************** *** 9749,9811 **** } } - /* - * "setbufvar()" function - */ - static void - f_setbufvar(typval_T *argvars, typval_T *rettv UNUSED) - { - buf_T *buf; - char_u *varname, *bufvarname; - typval_T *varp; - char_u nbuf[NUMBUFLEN]; - - if (check_secure()) - return; - (void)tv_get_number(&argvars[0]); /* issue errmsg if type error */ - varname = tv_get_string_chk(&argvars[1]); - buf = tv_get_buf(&argvars[0], FALSE); - varp = &argvars[2]; - - if (buf != NULL && varname != NULL && varp != NULL) - { - if (*varname == '&') - { - long numval; - char_u *strval; - int error = FALSE; - aco_save_T aco; - - /* set curbuf to be our buf, temporarily */ - aucmd_prepbuf(&aco, buf); - - ++varname; - numval = (long)tv_get_number_chk(varp, &error); - strval = tv_get_string_buf_chk(varp, nbuf); - if (!error && strval != NULL) - set_option_value(varname, numval, strval, OPT_LOCAL); - - /* reset notion of buffer */ - aucmd_restbuf(&aco); - } - else - { - buf_T *save_curbuf = curbuf; - - bufvarname = alloc(STRLEN(varname) + 3); - if (bufvarname != NULL) - { - curbuf = buf; - STRCPY(bufvarname, "b:"); - STRCPY(bufvarname + 2, varname); - set_var(bufvarname, varp, TRUE); - vim_free(bufvarname); - curbuf = save_curbuf; - } - } - } - } - static void f_setcharsearch(typval_T *argvars, typval_T *rettv UNUSED) { --- 9680,9685 ---- *** ../vim-8.1.1942/src/evalvars.c 2019-08-29 22:48:20.921069540 +0200 --- src/evalvars.c 2019-08-30 14:14:24.676057198 +0200 *************** *** 46,55 **** char vv_flags; // VV_COMPAT, VV_RO, VV_RO_SBX } vimvars[VV_LEN] = { ! /* ! * The order here must match the VV_ defines in vim.h! ! * Initializing a union does not work, leave tv.vval empty to get zero's. ! */ {VV_NAME("count", VAR_NUMBER), VV_COMPAT+VV_RO}, {VV_NAME("count1", VAR_NUMBER), VV_RO}, {VV_NAME("prevcount", VAR_NUMBER), VV_RO}, --- 46,53 ---- char vv_flags; // VV_COMPAT, VV_RO, VV_RO_SBX } vimvars[VV_LEN] = { ! // The order here must match the VV_ defines in vim.h! ! // Initializing a union does not work, leave tv.vval empty to get zero's. {VV_NAME("count", VAR_NUMBER), VV_COMPAT+VV_RO}, {VV_NAME("count1", VAR_NUMBER), VV_RO}, {VV_NAME("prevcount", VAR_NUMBER), VV_RO}, *************** *** 1592,1598 **** if (len > varnamebuflen) { vim_free(varnamebuf); ! len += 10; /* some additional space */ varnamebuf = alloc(len); if (varnamebuf == NULL) { --- 1590,1596 ---- if (len > varnamebuflen) { vim_free(varnamebuf); ! len += 10; // some additional space varnamebuf = alloc(len); if (varnamebuf == NULL) { *************** *** 1701,1706 **** --- 1699,1705 ---- /* * Set number v: variable to "val". + * Note that this does not set the type, use set_vim_var_type() for that. */ void set_vim_var_nr(int idx, varnumber_T val) *************** *** 2078,2084 **** if (ret != NULL) return ret; ! /* Search in parent scope for lambda */ return find_var_in_scoped_ht(name, no_autoload || htp != NULL); } --- 2077,2083 ---- if (ret != NULL) return ret; ! // Search in parent scope for lambda return find_var_in_scoped_ht(name, no_autoload || htp != NULL); } *************** *** 2222,2230 **** if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK) { ! /* Re-allocating ga_data means that an ht_array pointing to ! * ht_smallarray becomes invalid. We can recognize this: ht_mask is ! * at its init value. Also reset "v_dict", it's always the same. */ for (i = 1; i <= ga_scripts.ga_len; ++i) { ht = &SCRIPT_VARS(i); --- 2221,2229 ---- if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK) { ! // Re-allocating ga_data means that an ht_array pointing to ! // ht_smallarray becomes invalid. We can recognize this: ht_mask is ! // at its init value. Also reset "v_dict", it's always the same. for (i = 1; i <= ga_scripts.ga_len; ++i) { ht = &SCRIPT_VARS(i); *************** *** 2269,2276 **** void unref_var_dict(dict_T *dict) { ! /* Now the dict needs to be freed if no one else is using it, go back to ! * normal reference counting. */ dict->dv_refcount -= DO_NOT_FREE_CNT - 1; dict_unref(dict); } --- 2268,2275 ---- void unref_var_dict(dict_T *dict) { ! // Now the dict needs to be freed if no one else is using it, go back to ! // normal reference counting. dict->dv_refcount -= DO_NOT_FREE_CNT - 1; dict_unref(dict); } *************** *** 2817,2823 **** struct vimvar *vp = &vimvars[VV_ERRORS]; if (vp->vv_type != VAR_LIST || vimvars[VV_ERRORS].vv_list == NULL) ! /* Make sure v:errors is a list. */ set_vim_var_list(VV_ERRORS, list_alloc()); list_append_string(vimvars[VV_ERRORS].vv_list, gap->ga_data, gap->ga_len); } --- 2816,2822 ---- struct vimvar *vp = &vimvars[VV_ERRORS]; if (vp->vv_type != VAR_LIST || vimvars[VV_ERRORS].vv_list == NULL) ! // Make sure v:errors is a list. set_vim_var_list(VV_ERRORS, list_alloc()); list_append_string(vimvars[VV_ERRORS].vv_list, gap->ga_data, gap->ga_len); } *************** *** 2916,2921 **** --- 2915,2987 ---- } /* + * "getbufvar()" function + */ + void + f_getbufvar(typval_T *argvars, typval_T *rettv) + { + buf_T *buf; + buf_T *save_curbuf; + char_u *varname; + dictitem_T *v; + int done = FALSE; + + (void)tv_get_number(&argvars[0]); // issue errmsg if type error + varname = tv_get_string_chk(&argvars[1]); + ++emsg_off; + buf = tv_get_buf(&argvars[0], FALSE); + + rettv->v_type = VAR_STRING; + rettv->vval.v_string = NULL; + + if (buf != NULL && varname != NULL) + { + // set curbuf to be our buf, temporarily + save_curbuf = curbuf; + curbuf = buf; + + if (*varname == '&') + { + if (varname[1] == NUL) + { + // get all buffer-local options in a dict + dict_T *opts = get_winbuf_options(TRUE); + + if (opts != NULL) + { + rettv_dict_set(rettv, opts); + done = TRUE; + } + } + else if (get_option_tv(&varname, rettv, TRUE) == OK) + // buffer-local-option + done = TRUE; + } + else + { + // Look up the variable. + // Let getbufvar({nr}, "") return the "b:" dictionary. + v = find_var_in_ht(&curbuf->b_vars->dv_hashtab, + 'b', varname, FALSE); + if (v != NULL) + { + copy_tv(&v->di_tv, rettv); + done = TRUE; + } + } + + // restore previous notion of curbuf + curbuf = save_curbuf; + } + + if (!done && argvars[2].v_type != VAR_UNKNOWN) + // use the default value + copy_tv(&argvars[2], rettv); + + --emsg_off; + } + + /* * "settabvar()" function */ void *************** *** 2973,2976 **** --- 3039,3099 ---- setwinvar(argvars, rettv, 0); } + /* + * "setbufvar()" function + */ + void + f_setbufvar(typval_T *argvars, typval_T *rettv UNUSED) + { + buf_T *buf; + char_u *varname, *bufvarname; + typval_T *varp; + char_u nbuf[NUMBUFLEN]; + + if (check_secure()) + return; + (void)tv_get_number(&argvars[0]); // issue errmsg if type error + varname = tv_get_string_chk(&argvars[1]); + buf = tv_get_buf(&argvars[0], FALSE); + varp = &argvars[2]; + + if (buf != NULL && varname != NULL && varp != NULL) + { + if (*varname == '&') + { + long numval; + char_u *strval; + int error = FALSE; + aco_save_T aco; + + // set curbuf to be our buf, temporarily + aucmd_prepbuf(&aco, buf); + + ++varname; + numval = (long)tv_get_number_chk(varp, &error); + strval = tv_get_string_buf_chk(varp, nbuf); + if (!error && strval != NULL) + set_option_value(varname, numval, strval, OPT_LOCAL); + + // reset notion of buffer + aucmd_restbuf(&aco); + } + else + { + buf_T *save_curbuf = curbuf; + + bufvarname = alloc(STRLEN(varname) + 3); + if (bufvarname != NULL) + { + curbuf = buf; + STRCPY(bufvarname, "b:"); + STRCPY(bufvarname + 2, varname); + set_var(bufvarname, varp, TRUE); + vim_free(bufvarname); + curbuf = save_curbuf; + } + } + } + } + #endif // FEAT_EVAL *** ../vim-8.1.1942/src/proto/eval.pro 2019-08-29 22:09:42.608429189 +0200 --- src/proto/eval.pro 2019-08-30 14:10:09.617713145 +0200 *************** *** 80,88 **** void ex_echo(exarg_T *eap); void ex_echohl(exarg_T *eap); void ex_execute(exarg_T *eap); - win_T *find_win_by_nr(typval_T *vp, tabpage_T *tp); - win_T *find_win_by_nr_or_id(typval_T *vp); - win_T *find_tabwin(typval_T *wvp, typval_T *tvp, tabpage_T **ptp); char_u *find_option_end(char_u **arg, int *opt_flags); char_u *autoload_name(char_u *name); int script_autoload(char_u *name, int reload); --- 80,85 ---- *** ../vim-8.1.1942/src/proto/evalvars.pro 2019-08-29 22:48:20.921069540 +0200 --- src/proto/evalvars.pro 2019-08-30 14:10:09.617713145 +0200 *************** *** 58,64 **** --- 58,66 ---- void f_gettabvar(typval_T *argvars, typval_T *rettv); void f_gettabwinvar(typval_T *argvars, typval_T *rettv); void f_getwinvar(typval_T *argvars, typval_T *rettv); + void f_getbufvar(typval_T *argvars, typval_T *rettv); void f_settabvar(typval_T *argvars, typval_T *rettv); void f_settabwinvar(typval_T *argvars, typval_T *rettv); void f_setwinvar(typval_T *argvars, typval_T *rettv); + void f_setbufvar(typval_T *argvars, typval_T *rettv); /* vim: set ft=c : */ *** ../vim-8.1.1942/src/proto/window.pro 2019-08-20 20:13:40.334821916 +0200 --- src/proto/window.pro 2019-08-30 14:12:11.252916994 +0200 *************** *** 89,93 **** --- 89,96 ---- win_T *win_id2wp_tp(int id, tabpage_T **tpp); int win_id2win(typval_T *argvars); void win_findbuf(typval_T *argvars, list_T *list); + win_T *find_win_by_nr(typval_T *vp, tabpage_T *tp); + win_T *find_win_by_nr_or_id(typval_T *vp); + win_T *find_tabwin(typval_T *wvp, typval_T *tvp, tabpage_T **ptp); void get_framelayout(frame_T *fr, list_T *l, int outer); /* vim: set ft=c : */ *** ../vim-8.1.1942/src/window.c 2019-08-25 22:24:58.871357010 +0200 --- src/window.c 2019-08-30 14:12:07.824939257 +0200 *************** *** 6970,6975 **** --- 6970,7078 ---- } /* + * Find window specified by "vp" in tabpage "tp". + */ + win_T * + find_win_by_nr( + typval_T *vp, + tabpage_T *tp) // NULL for current tab page + { + win_T *wp; + int nr = (int)tv_get_number_chk(vp, NULL); + + if (nr < 0) + return NULL; + if (nr == 0) + return curwin; + + FOR_ALL_WINDOWS_IN_TAB(tp, wp) + { + if (nr >= LOWEST_WIN_ID) + { + if (wp->w_id == nr) + return wp; + } + else if (--nr <= 0) + break; + } + if (nr >= LOWEST_WIN_ID) + { + #ifdef FEAT_TEXT_PROP + // check tab-local popup windows + for (wp = tp->tp_first_popupwin; wp != NULL; wp = wp->w_next) + if (wp->w_id == nr) + return wp; + // check global popup windows + for (wp = first_popupwin; wp != NULL; wp = wp->w_next) + if (wp->w_id == nr) + return wp; + #endif + return NULL; + } + return wp; + } + + /* + * Find a window: When using a Window ID in any tab page, when using a number + * in the current tab page. + */ + win_T * + find_win_by_nr_or_id(typval_T *vp) + { + int nr = (int)tv_get_number_chk(vp, NULL); + + if (nr >= LOWEST_WIN_ID) + return win_id2wp(tv_get_number(vp)); + return find_win_by_nr(vp, NULL); + } + + /* + * Find window specified by "wvp" in tabpage "tvp". + * Returns the tab page in 'ptp' + */ + win_T * + find_tabwin( + typval_T *wvp, // VAR_UNKNOWN for current window + typval_T *tvp, // VAR_UNKNOWN for current tab page + tabpage_T **ptp) + { + win_T *wp = NULL; + tabpage_T *tp = NULL; + long n; + + if (wvp->v_type != VAR_UNKNOWN) + { + if (tvp->v_type != VAR_UNKNOWN) + { + n = (long)tv_get_number(tvp); + if (n >= 0) + tp = find_tabpage(n); + } + else + tp = curtab; + + if (tp != NULL) + { + wp = find_win_by_nr(wvp, tp); + if (wp == NULL && wvp->v_type == VAR_NUMBER + && wvp->vval.v_number != -1) + // A window with the specified number is not found + tp = NULL; + } + } + else + { + wp = curwin; + tp = curtab; + } + + if (ptp != NULL) + *ptp = tp; + + return wp; + } + + /* * Get the layout of the given tab page for winlayout(). */ void *** ../vim-8.1.1942/src/version.c 2019-08-30 13:59:26.446291285 +0200 --- src/version.c 2019-08-30 14:11:41.809108535 +0200 *************** *** 763,764 **** --- 763,766 ---- { /* Add new patch number below this line */ + /**/ + 1943, /**/ -- Amazing but true: If all the salmon caught in Canada in one year were laid end to end across the Sahara Desert, the smell would be absolutely awful. /// Bram Moolenaar -- Bram@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 ///