forked from aniani/vim
patch 7.4.1244
Problem: The channel functions don't sort together. Solution: Use a common "ch_" prefix.
This commit is contained in:
451
src/eval.c
451
src/eval.c
@@ -499,6 +499,12 @@ static void f_call(typval_T *argvars, typval_T *rettv);
|
||||
#ifdef FEAT_FLOAT
|
||||
static void f_ceil(typval_T *argvars, typval_T *rettv);
|
||||
#endif
|
||||
#ifdef FEAT_CHANNEL
|
||||
static void f_ch_open(typval_T *argvars, typval_T *rettv);
|
||||
static void f_ch_close(typval_T *argvars, typval_T *rettv);
|
||||
static void f_ch_sendexpr(typval_T *argvars, typval_T *rettv);
|
||||
static void f_ch_sendraw(typval_T *argvars, typval_T *rettv);
|
||||
#endif
|
||||
static void f_changenr(typval_T *argvars, typval_T *rettv);
|
||||
static void f_char2nr(typval_T *argvars, typval_T *rettv);
|
||||
static void f_cindent(typval_T *argvars, typval_T *rettv);
|
||||
@@ -515,9 +521,6 @@ static void f_copy(typval_T *argvars, typval_T *rettv);
|
||||
static void f_cos(typval_T *argvars, typval_T *rettv);
|
||||
static void f_cosh(typval_T *argvars, typval_T *rettv);
|
||||
#endif
|
||||
#ifdef FEAT_CHANNEL
|
||||
static void f_connect(typval_T *argvars, typval_T *rettv);
|
||||
#endif
|
||||
static void f_count(typval_T *argvars, typval_T *rettv);
|
||||
static void f_cscope_connection(typval_T *argvars, typval_T *rettv);
|
||||
static void f_cursor(typval_T *argsvars, typval_T *rettv);
|
||||
@@ -526,9 +529,6 @@ static void f_delete(typval_T *argvars, typval_T *rettv);
|
||||
static void f_did_filetype(typval_T *argvars, typval_T *rettv);
|
||||
static void f_diff_filler(typval_T *argvars, typval_T *rettv);
|
||||
static void f_diff_hlID(typval_T *argvars, typval_T *rettv);
|
||||
#ifdef FEAT_CHANNEL
|
||||
static void f_disconnect(typval_T *argvars, typval_T *rettv);
|
||||
#endif
|
||||
static void f_empty(typval_T *argvars, typval_T *rettv);
|
||||
static void f_escape(typval_T *argvars, typval_T *rettv);
|
||||
static void f_eval(typval_T *argvars, typval_T *rettv);
|
||||
@@ -703,10 +703,6 @@ static void f_searchdecl(typval_T *argvars, typval_T *rettv);
|
||||
static void f_searchpair(typval_T *argvars, typval_T *rettv);
|
||||
static void f_searchpairpos(typval_T *argvars, typval_T *rettv);
|
||||
static void f_searchpos(typval_T *argvars, typval_T *rettv);
|
||||
#ifdef FEAT_CHANNEL
|
||||
static void f_sendexpr(typval_T *argvars, typval_T *rettv);
|
||||
static void f_sendraw(typval_T *argvars, typval_T *rettv);
|
||||
#endif
|
||||
static void f_server2client(typval_T *argvars, typval_T *rettv);
|
||||
static void f_serverlist(typval_T *argvars, typval_T *rettv);
|
||||
static void f_setbufvar(typval_T *argvars, typval_T *rettv);
|
||||
@@ -8002,6 +7998,12 @@ static struct fst
|
||||
{"call", 2, 3, f_call},
|
||||
#ifdef FEAT_FLOAT
|
||||
{"ceil", 1, 1, f_ceil},
|
||||
#endif
|
||||
#ifdef FEAT_CHANNEL
|
||||
{"ch_close", 1, 1, f_ch_close},
|
||||
{"ch_open", 2, 3, f_ch_open},
|
||||
{"ch_sendexpr", 2, 3, f_ch_sendexpr},
|
||||
{"ch_sendraw", 2, 3, f_ch_sendraw},
|
||||
#endif
|
||||
{"changenr", 0, 0, f_changenr},
|
||||
{"char2nr", 1, 2, f_char2nr},
|
||||
@@ -8014,9 +8016,6 @@ static struct fst
|
||||
{"complete_check", 0, 0, f_complete_check},
|
||||
#endif
|
||||
{"confirm", 1, 4, f_confirm},
|
||||
#ifdef FEAT_CHANNEL
|
||||
{"connect", 2, 3, f_connect},
|
||||
#endif
|
||||
{"copy", 1, 1, f_copy},
|
||||
#ifdef FEAT_FLOAT
|
||||
{"cos", 1, 1, f_cos},
|
||||
@@ -8030,9 +8029,6 @@ static struct fst
|
||||
{"did_filetype", 0, 0, f_did_filetype},
|
||||
{"diff_filler", 1, 1, f_diff_filler},
|
||||
{"diff_hlID", 2, 2, f_diff_hlID},
|
||||
#ifdef FEAT_CHANNEL
|
||||
{"disconnect", 1, 1, f_disconnect},
|
||||
#endif
|
||||
{"empty", 1, 1, f_empty},
|
||||
{"escape", 2, 2, f_escape},
|
||||
{"eval", 1, 1, f_eval},
|
||||
@@ -8211,10 +8207,6 @@ static struct fst
|
||||
{"searchpair", 3, 7, f_searchpair},
|
||||
{"searchpairpos", 3, 7, f_searchpairpos},
|
||||
{"searchpos", 1, 4, f_searchpos},
|
||||
#ifdef FEAT_CHANNEL
|
||||
{"sendexpr", 2, 3, f_sendexpr},
|
||||
{"sendraw", 2, 3, f_sendraw},
|
||||
#endif
|
||||
{"server2client", 2, 2, f_server2client},
|
||||
{"serverlist", 0, 0, f_serverlist},
|
||||
{"setbufvar", 3, 3, f_setbufvar},
|
||||
@@ -9685,6 +9677,213 @@ f_ceil(typval_T *argvars, typval_T *rettv)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_CHANNEL
|
||||
/*
|
||||
* Get the channel index from the handle argument.
|
||||
* Returns -1 if the handle is invalid or the channel is closed.
|
||||
*/
|
||||
static int
|
||||
get_channel_arg(typval_T *tv)
|
||||
{
|
||||
int ch_idx;
|
||||
|
||||
if (tv->v_type != VAR_NUMBER)
|
||||
{
|
||||
EMSG2(_(e_invarg2), get_tv_string(tv));
|
||||
return -1;
|
||||
}
|
||||
ch_idx = tv->vval.v_number;
|
||||
|
||||
if (!channel_is_open(ch_idx))
|
||||
{
|
||||
EMSGN(_("E906: not an open channel"), ch_idx);
|
||||
return -1;
|
||||
}
|
||||
return ch_idx;
|
||||
}
|
||||
|
||||
/*
|
||||
* "ch_close()" function
|
||||
*/
|
||||
static void
|
||||
f_ch_close(typval_T *argvars, typval_T *rettv UNUSED)
|
||||
{
|
||||
int ch_idx = get_channel_arg(&argvars[0]);
|
||||
|
||||
if (ch_idx >= 0)
|
||||
channel_close(ch_idx);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a callback from "arg". It can be a Funcref or a function name.
|
||||
* When "arg" is zero return an empty string.
|
||||
* Return NULL for an invalid argument.
|
||||
*/
|
||||
static char_u *
|
||||
get_callback(typval_T *arg)
|
||||
{
|
||||
if (arg->v_type == VAR_FUNC || arg->v_type == VAR_STRING)
|
||||
return arg->vval.v_string;
|
||||
if (arg->v_type == VAR_NUMBER && arg->vval.v_number == 0)
|
||||
return (char_u *)"";
|
||||
EMSG(_("E999: Invalid callback argument"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* "ch_open()" function
|
||||
*/
|
||||
static void
|
||||
f_ch_open(typval_T *argvars, typval_T *rettv)
|
||||
{
|
||||
char_u *address;
|
||||
char_u *mode;
|
||||
char_u *callback = NULL;
|
||||
char_u buf1[NUMBUFLEN];
|
||||
char_u *p;
|
||||
int port;
|
||||
int json_mode = FALSE;
|
||||
|
||||
/* default: fail */
|
||||
rettv->vval.v_number = -1;
|
||||
|
||||
address = get_tv_string(&argvars[0]);
|
||||
mode = get_tv_string_buf(&argvars[1], buf1);
|
||||
if (argvars[2].v_type != VAR_UNKNOWN)
|
||||
{
|
||||
callback = get_callback(&argvars[2]);
|
||||
if (callback == NULL)
|
||||
return;
|
||||
}
|
||||
|
||||
/* parse address */
|
||||
p = vim_strchr(address, ':');
|
||||
if (p == NULL)
|
||||
{
|
||||
EMSG2(_(e_invarg2), address);
|
||||
return;
|
||||
}
|
||||
*p++ = NUL;
|
||||
port = atoi((char *)p);
|
||||
if (*address == NUL || port <= 0)
|
||||
{
|
||||
p[-1] = ':';
|
||||
EMSG2(_(e_invarg2), address);
|
||||
return;
|
||||
}
|
||||
|
||||
/* parse mode */
|
||||
if (STRCMP(mode, "json") == 0)
|
||||
json_mode = TRUE;
|
||||
else if (STRCMP(mode, "raw") != 0)
|
||||
{
|
||||
EMSG2(_(e_invarg2), mode);
|
||||
return;
|
||||
}
|
||||
|
||||
rettv->vval.v_number = channel_open((char *)address, port, NULL);
|
||||
if (rettv->vval.v_number >= 0)
|
||||
{
|
||||
channel_set_json_mode(rettv->vval.v_number, json_mode);
|
||||
if (callback != NULL && *callback != NUL)
|
||||
channel_set_callback(rettv->vval.v_number, callback);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* common for "sendexpr()" and "sendraw()"
|
||||
* Returns the channel index if the caller should read the response.
|
||||
* Otherwise returns -1.
|
||||
*/
|
||||
static int
|
||||
send_common(typval_T *argvars, char_u *text, char *fun)
|
||||
{
|
||||
int ch_idx;
|
||||
char_u *callback = NULL;
|
||||
|
||||
ch_idx = get_channel_arg(&argvars[0]);
|
||||
if (ch_idx < 0)
|
||||
return -1;
|
||||
|
||||
if (argvars[2].v_type != VAR_UNKNOWN)
|
||||
{
|
||||
callback = get_callback(&argvars[2]);
|
||||
if (callback == NULL)
|
||||
return -1;
|
||||
}
|
||||
/* Set the callback or clear it. An empty callback means no callback and
|
||||
* not reading the response. */
|
||||
channel_set_req_callback(ch_idx,
|
||||
callback != NULL && *callback == NUL ? NULL : callback);
|
||||
|
||||
if (channel_send(ch_idx, text, fun) == OK && callback == NULL)
|
||||
return ch_idx;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* "ch_sendexpr()" function
|
||||
*/
|
||||
static void
|
||||
f_ch_sendexpr(typval_T *argvars, typval_T *rettv)
|
||||
{
|
||||
char_u *text;
|
||||
typval_T *listtv;
|
||||
int ch_idx;
|
||||
int id;
|
||||
|
||||
/* return an empty string by default */
|
||||
rettv->v_type = VAR_STRING;
|
||||
rettv->vval.v_string = NULL;
|
||||
|
||||
id = channel_get_id();
|
||||
text = json_encode_nr_expr(id, &argvars[1]);
|
||||
if (text == NULL)
|
||||
return;
|
||||
|
||||
ch_idx = send_common(argvars, text, "sendexpr");
|
||||
if (ch_idx >= 0)
|
||||
{
|
||||
if (channel_read_json_block(ch_idx, id, &listtv) == OK)
|
||||
{
|
||||
if (listtv->v_type == VAR_LIST)
|
||||
{
|
||||
list_T *list = listtv->vval.v_list;
|
||||
|
||||
if (list->lv_len == 2)
|
||||
{
|
||||
/* Move the item from the list and then change the type to
|
||||
* avoid the value being freed. */
|
||||
*rettv = list->lv_last->li_tv;
|
||||
list->lv_last->li_tv.v_type = VAR_NUMBER;
|
||||
}
|
||||
}
|
||||
clear_tv(listtv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* "ch_sendraw()" function
|
||||
*/
|
||||
static void
|
||||
f_ch_sendraw(typval_T *argvars, typval_T *rettv)
|
||||
{
|
||||
char_u buf[NUMBUFLEN];
|
||||
char_u *text;
|
||||
int ch_idx;
|
||||
|
||||
/* return an empty string by default */
|
||||
rettv->v_type = VAR_STRING;
|
||||
rettv->vval.v_string = NULL;
|
||||
|
||||
text = get_tv_string_buf(&argvars[1], buf);
|
||||
ch_idx = send_common(argvars, text, "sendraw");
|
||||
if (ch_idx >= 0)
|
||||
rettv->vval.v_string = channel_read_block(ch_idx);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* "changenr()" function
|
||||
*/
|
||||
@@ -10033,84 +10232,6 @@ f_count(typval_T *argvars, typval_T *rettv)
|
||||
rettv->vval.v_number = n;
|
||||
}
|
||||
|
||||
#ifdef FEAT_CHANNEL
|
||||
/*
|
||||
* Get a callback from "arg". It can be a Funcref or a function name.
|
||||
* When "arg" is zero return an empty string.
|
||||
* Return NULL for an invalid argument.
|
||||
*/
|
||||
static char_u *
|
||||
get_callback(typval_T *arg)
|
||||
{
|
||||
if (arg->v_type == VAR_FUNC || arg->v_type == VAR_STRING)
|
||||
return arg->vval.v_string;
|
||||
if (arg->v_type == VAR_NUMBER && arg->vval.v_number == 0)
|
||||
return (char_u *)"";
|
||||
EMSG(_("E999: Invalid callback argument"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* "connect()" function
|
||||
*/
|
||||
static void
|
||||
f_connect(typval_T *argvars, typval_T *rettv)
|
||||
{
|
||||
char_u *address;
|
||||
char_u *mode;
|
||||
char_u *callback = NULL;
|
||||
char_u buf1[NUMBUFLEN];
|
||||
char_u *p;
|
||||
int port;
|
||||
int json_mode = FALSE;
|
||||
|
||||
/* default: fail */
|
||||
rettv->vval.v_number = -1;
|
||||
|
||||
address = get_tv_string(&argvars[0]);
|
||||
mode = get_tv_string_buf(&argvars[1], buf1);
|
||||
if (argvars[2].v_type != VAR_UNKNOWN)
|
||||
{
|
||||
callback = get_callback(&argvars[2]);
|
||||
if (callback == NULL)
|
||||
return;
|
||||
}
|
||||
|
||||
/* parse address */
|
||||
p = vim_strchr(address, ':');
|
||||
if (p == NULL)
|
||||
{
|
||||
EMSG2(_(e_invarg2), address);
|
||||
return;
|
||||
}
|
||||
*p++ = NUL;
|
||||
port = atoi((char *)p);
|
||||
if (*address == NUL || port <= 0)
|
||||
{
|
||||
p[-1] = ':';
|
||||
EMSG2(_(e_invarg2), address);
|
||||
return;
|
||||
}
|
||||
|
||||
/* parse mode */
|
||||
if (STRCMP(mode, "json") == 0)
|
||||
json_mode = TRUE;
|
||||
else if (STRCMP(mode, "raw") != 0)
|
||||
{
|
||||
EMSG2(_(e_invarg2), mode);
|
||||
return;
|
||||
}
|
||||
|
||||
rettv->vval.v_number = channel_open((char *)address, port, NULL);
|
||||
if (rettv->vval.v_number >= 0)
|
||||
{
|
||||
channel_set_json_mode(rettv->vval.v_number, json_mode);
|
||||
if (callback != NULL && *callback != NUL)
|
||||
channel_set_callback(rettv->vval.v_number, callback);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* "cscope_connection([{num} , {dbpath} [, {prepend}]])" function
|
||||
*
|
||||
@@ -10349,44 +10470,6 @@ f_diff_hlID(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef FEAT_CHANNEL
|
||||
/*
|
||||
* Get the channel index from the handle argument.
|
||||
* Returns -1 if the handle is invalid or the channel is closed.
|
||||
*/
|
||||
static int
|
||||
get_channel_arg(typval_T *tv)
|
||||
{
|
||||
int ch_idx;
|
||||
|
||||
if (tv->v_type != VAR_NUMBER)
|
||||
{
|
||||
EMSG2(_(e_invarg2), get_tv_string(tv));
|
||||
return -1;
|
||||
}
|
||||
ch_idx = tv->vval.v_number;
|
||||
|
||||
if (!channel_is_open(ch_idx))
|
||||
{
|
||||
EMSGN(_("E906: not an open channel"), ch_idx);
|
||||
return -1;
|
||||
}
|
||||
return ch_idx;
|
||||
}
|
||||
|
||||
/*
|
||||
* "disconnect()" function
|
||||
*/
|
||||
static void
|
||||
f_disconnect(typval_T *argvars, typval_T *rettv UNUSED)
|
||||
{
|
||||
int ch_idx = get_channel_arg(&argvars[0]);
|
||||
|
||||
if (ch_idx >= 0)
|
||||
channel_close(ch_idx);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* "empty({expr})" function
|
||||
*/
|
||||
@@ -16860,102 +16943,6 @@ f_searchpos(typval_T *argvars, typval_T *rettv)
|
||||
list_append_number(rettv->vval.v_list, (varnumber_T)n);
|
||||
}
|
||||
|
||||
#ifdef FEAT_CHANNEL
|
||||
/*
|
||||
* common for "sendexpr()" and "sendraw()"
|
||||
* Returns the channel index if the caller should read the response.
|
||||
* Otherwise returns -1.
|
||||
*/
|
||||
static int
|
||||
send_common(typval_T *argvars, char_u *text, char *fun)
|
||||
{
|
||||
int ch_idx;
|
||||
char_u *callback = NULL;
|
||||
|
||||
ch_idx = get_channel_arg(&argvars[0]);
|
||||
if (ch_idx < 0)
|
||||
return -1;
|
||||
|
||||
if (argvars[2].v_type != VAR_UNKNOWN)
|
||||
{
|
||||
callback = get_callback(&argvars[2]);
|
||||
if (callback == NULL)
|
||||
return -1;
|
||||
}
|
||||
/* Set the callback or clear it. An empty callback means no callback and
|
||||
* not reading the response. */
|
||||
channel_set_req_callback(ch_idx,
|
||||
callback != NULL && *callback == NUL ? NULL : callback);
|
||||
|
||||
if (channel_send(ch_idx, text, fun) == OK && callback == NULL)
|
||||
return ch_idx;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* "sendexpr()" function
|
||||
*/
|
||||
static void
|
||||
f_sendexpr(typval_T *argvars, typval_T *rettv)
|
||||
{
|
||||
char_u *text;
|
||||
typval_T *listtv;
|
||||
int ch_idx;
|
||||
int id;
|
||||
|
||||
/* return an empty string by default */
|
||||
rettv->v_type = VAR_STRING;
|
||||
rettv->vval.v_string = NULL;
|
||||
|
||||
id = channel_get_id();
|
||||
text = json_encode_nr_expr(id, &argvars[1]);
|
||||
if (text == NULL)
|
||||
return;
|
||||
|
||||
ch_idx = send_common(argvars, text, "sendexpr");
|
||||
if (ch_idx >= 0)
|
||||
{
|
||||
if (channel_read_json_block(ch_idx, id, &listtv) == OK)
|
||||
{
|
||||
if (listtv->v_type == VAR_LIST)
|
||||
{
|
||||
list_T *list = listtv->vval.v_list;
|
||||
|
||||
if (list->lv_len == 2)
|
||||
{
|
||||
/* Move the item from the list and then change the type to
|
||||
* avoid the value being freed. */
|
||||
*rettv = list->lv_last->li_tv;
|
||||
list->lv_last->li_tv.v_type = VAR_NUMBER;
|
||||
}
|
||||
}
|
||||
clear_tv(listtv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* "sendraw()" function
|
||||
*/
|
||||
static void
|
||||
f_sendraw(typval_T *argvars, typval_T *rettv)
|
||||
{
|
||||
char_u buf[NUMBUFLEN];
|
||||
char_u *text;
|
||||
int ch_idx;
|
||||
|
||||
/* return an empty string by default */
|
||||
rettv->v_type = VAR_STRING;
|
||||
rettv->vval.v_string = NULL;
|
||||
|
||||
text = get_tv_string_buf(&argvars[1], buf);
|
||||
ch_idx = send_common(argvars, text, "sendraw");
|
||||
if (ch_idx >= 0)
|
||||
rettv->vval.v_string = channel_read_block(ch_idx);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
f_server2client(typval_T *argvars UNUSED, typval_T *rettv)
|
||||
{
|
||||
|
Reference in New Issue
Block a user