eval: port tv_get_buf_from_arg()

Cherry-picked from v8.2.1562, but uses Nvim's tv_check_str_or_nr().
Required for v8.2.1588.

It isn't used for f_bufnr() to avoid a double error message if the first
argument isn't a number or string similiar to what's seen in Vim.
This commit is contained in:
Sean Dewar
2021-04-20 16:39:03 +01:00
parent 26bd5a58df
commit 60870d1531

View File

@@ -602,12 +602,7 @@ static void f_bufname(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (argvars[0].v_type == VAR_UNKNOWN) { if (argvars[0].v_type == VAR_UNKNOWN) {
buf = curbuf; buf = curbuf;
} else { } else {
if (!tv_check_str_or_nr(&argvars[0])) { buf = tv_get_buf_from_arg(&argvars[0]);
return;
}
emsg_off++;
buf = tv_get_buf(&argvars[0], false);
emsg_off--;
} }
if (buf != NULL && buf->b_fname != NULL) { if (buf != NULL && buf->b_fname != NULL) {
rettv->vval.v_string = (char_u *)xstrdup((char *)buf->b_fname); rettv->vval.v_string = (char_u *)xstrdup((char *)buf->b_fname);
@@ -627,6 +622,9 @@ static void f_bufnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (argvars[0].v_type == VAR_UNKNOWN) { if (argvars[0].v_type == VAR_UNKNOWN) {
buf = curbuf; buf = curbuf;
} else { } else {
// Don't use tv_get_buf_from_arg(); we continue if the buffer wasn't found
// and the second argument isn't zero, but we want to return early if the
// first argument isn't a string or number so only one error is shown.
if (!tv_check_str_or_nr(&argvars[0])) { if (!tv_check_str_or_nr(&argvars[0])) {
return; return;
} }
@@ -653,18 +651,12 @@ static void f_bufnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void buf_win_common(typval_T *argvars, typval_T *rettv, bool get_nr) static void buf_win_common(typval_T *argvars, typval_T *rettv, bool get_nr)
{ {
if (!tv_check_str_or_nr(&argvars[0])) { const buf_T *const buf = tv_get_buf_from_arg(&argvars[0]);
if (buf == NULL) { // no need to search if invalid arg or buffer not found
rettv->vval.v_number = -1; rettv->vval.v_number = -1;
return; return;
} }
emsg_off++;
buf_T *buf = tv_get_buf(&argvars[0], true);
if (buf == NULL) { // no need to search if buffer was not found
rettv->vval.v_number = -1;
goto end;
}
int winnr = 0; int winnr = 0;
int winid; int winid;
bool found_buf = false; bool found_buf = false;
@@ -677,8 +669,6 @@ static void buf_win_common(typval_T *argvars, typval_T *rettv, bool get_nr)
} }
} }
rettv->vval.v_number = (found_buf ? (get_nr ? winnr : winid) : -1); rettv->vval.v_number = (found_buf ? (get_nr ? winnr : winid) : -1);
end:
emsg_off--;
} }
/// "bufwinid(nr)" function /// "bufwinid(nr)" function
@@ -731,6 +721,18 @@ buf_T *tv_get_buf(typval_T *tv, int curtab_only)
return buf; return buf;
} }
/// Like tv_get_buf() but give an error message if the type is wrong.
buf_T *tv_get_buf_from_arg(typval_T *const tv) FUNC_ATTR_NONNULL_ALL
{
if (!tv_check_str_or_nr(tv)) {
return NULL;
}
emsg_off++;
buf_T *const buf = tv_get_buf(tv, false);
emsg_off--;
return buf;
}
/// Get the buffer from "arg" and give an error and return NULL if it is not /// Get the buffer from "arg" and give an error and return NULL if it is not
/// valid. /// valid.
buf_T * get_buf_arg(typval_T *arg) buf_T * get_buf_arg(typval_T *arg)
@@ -2799,13 +2801,9 @@ static void f_getbufinfo(typval_T *argvars, typval_T *rettv, FunPtr fptr)
} }
} else if (argvars[0].v_type != VAR_UNKNOWN) { } else if (argvars[0].v_type != VAR_UNKNOWN) {
// Information about one buffer. Argument specifies the buffer // Information about one buffer. Argument specifies the buffer
if (tv_check_num(&argvars[0])) { // issue errmsg if type error argbuf = tv_get_buf_from_arg(&argvars[0]);
emsg_off++; if (argbuf == NULL) {
argbuf = tv_get_buf(&argvars[0], false); return;
emsg_off--;
if (argbuf == NULL) {
return;
}
} }
} }
@@ -2875,13 +2873,7 @@ static void get_buffer_lines(buf_T *buf,
*/ */
static void f_getbufline(typval_T *argvars, typval_T *rettv, FunPtr fptr) static void f_getbufline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{ {
buf_T *buf = NULL; buf_T *const buf = tv_get_buf_from_arg(&argvars[0]);
if (tv_check_str_or_nr(&argvars[0])) {
emsg_off++;
buf = tv_get_buf(&argvars[0], false);
emsg_off--;
}
const linenr_T lnum = tv_get_lnum_buf(&argvars[1], buf); const linenr_T lnum = tv_get_lnum_buf(&argvars[1], buf);
const linenr_T end = (argvars[2].v_type == VAR_UNKNOWN const linenr_T end = (argvars[2].v_type == VAR_UNKNOWN