forked from aniani/vim
patch 8.2.2944: Vim9: no error when using job or channel as a string
Problem: Vim9: no error when using job or channel as a string. Solution: Be more strict about conversion to string. (closes #8312)
This commit is contained in:
@@ -5015,4 +5015,22 @@ f_ch_status(typval_T *argvars, typval_T *rettv)
|
|||||||
rettv->vval.v_string = vim_strsave((char_u *)channel_status(channel, part));
|
rettv->vval.v_string = vim_strsave((char_u *)channel_status(channel, part));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get a string with information about the channel in "varp" in "buf".
|
||||||
|
* "buf" must be at least NUMBUFLEN long.
|
||||||
|
*/
|
||||||
|
char_u *
|
||||||
|
channel_to_string_buf(typval_T *varp, char_u *buf)
|
||||||
|
{
|
||||||
|
channel_T *channel = varp->vval.v_channel;
|
||||||
|
char *status = channel_status(channel, -1);
|
||||||
|
|
||||||
|
if (channel == NULL)
|
||||||
|
vim_snprintf((char *)buf, NUMBUFLEN, "channel %s", status);
|
||||||
|
else
|
||||||
|
vim_snprintf((char *)buf, NUMBUFLEN,
|
||||||
|
"channel %d %s", channel->ch_id, status);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // FEAT_JOB_CHANNEL
|
#endif // FEAT_JOB_CHANNEL
|
||||||
|
@@ -5060,7 +5060,8 @@ echo_string_core(
|
|||||||
case VAR_JOB:
|
case VAR_JOB:
|
||||||
case VAR_CHANNEL:
|
case VAR_CHANNEL:
|
||||||
*tofree = NULL;
|
*tofree = NULL;
|
||||||
r = tv_get_string_buf(tv, numbuf);
|
r = tv->v_type == VAR_JOB ? job_to_string_buf(tv, numbuf)
|
||||||
|
: channel_to_string_buf(tv, numbuf);
|
||||||
if (composite_val)
|
if (composite_val)
|
||||||
{
|
{
|
||||||
*tofree = string_quote(r, FALSE);
|
*tofree = string_quote(r, FALSE);
|
||||||
|
30
src/job.c
30
src/job.c
@@ -1927,4 +1927,34 @@ f_job_stop(typval_T *argvars, typval_T *rettv)
|
|||||||
rettv->vval.v_number = job_stop(job, argvars, NULL);
|
rettv->vval.v_number = job_stop(job, argvars, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get a string with information about the job in "varp" in "buf".
|
||||||
|
* "buf" must be at least NUMBUFLEN long.
|
||||||
|
*/
|
||||||
|
char_u *
|
||||||
|
job_to_string_buf(typval_T *varp, char_u *buf)
|
||||||
|
{
|
||||||
|
job_T *job = varp->vval.v_job;
|
||||||
|
char *status;
|
||||||
|
|
||||||
|
if (job == NULL)
|
||||||
|
return (char_u *)"no process";
|
||||||
|
status = job->jv_status == JOB_FAILED ? "fail"
|
||||||
|
: job->jv_status >= JOB_ENDED ? "dead"
|
||||||
|
: "run";
|
||||||
|
# ifdef UNIX
|
||||||
|
vim_snprintf((char *)buf, NUMBUFLEN,
|
||||||
|
"process %ld %s", (long)job->jv_pid, status);
|
||||||
|
# elif defined(MSWIN)
|
||||||
|
vim_snprintf((char *)buf, NUMBUFLEN,
|
||||||
|
"process %ld %s",
|
||||||
|
(long)job->jv_proc_info.dwProcessId,
|
||||||
|
status);
|
||||||
|
# else
|
||||||
|
// fall-back
|
||||||
|
vim_snprintf((char *)buf, NUMBUFLEN, "process ? %s", status);
|
||||||
|
# endif
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // FEAT_JOB_CHANNEL
|
#endif // FEAT_JOB_CHANNEL
|
||||||
|
@@ -58,4 +58,5 @@ void f_ch_evalraw(typval_T *argvars, typval_T *rettv);
|
|||||||
void f_ch_sendraw(typval_T *argvars, typval_T *rettv);
|
void f_ch_sendraw(typval_T *argvars, typval_T *rettv);
|
||||||
void f_ch_setoptions(typval_T *argvars, typval_T *rettv);
|
void f_ch_setoptions(typval_T *argvars, typval_T *rettv);
|
||||||
void f_ch_status(typval_T *argvars, typval_T *rettv);
|
void f_ch_status(typval_T *argvars, typval_T *rettv);
|
||||||
|
char_u *channel_to_string_buf(typval_T *varp, char_u *buf);
|
||||||
/* vim: set ft=c : */
|
/* vim: set ft=c : */
|
||||||
|
@@ -34,4 +34,5 @@ void f_job_setoptions(typval_T *argvars, typval_T *rettv);
|
|||||||
void f_job_start(typval_T *argvars, typval_T *rettv);
|
void f_job_start(typval_T *argvars, typval_T *rettv);
|
||||||
void f_job_status(typval_T *argvars, typval_T *rettv);
|
void f_job_status(typval_T *argvars, typval_T *rettv);
|
||||||
void f_job_stop(typval_T *argvars, typval_T *rettv);
|
void f_job_stop(typval_T *argvars, typval_T *rettv);
|
||||||
|
char_u *job_to_string_buf(typval_T *varp, char_u *buf);
|
||||||
/* vim: set ft=c : */
|
/* vim: set ft=c : */
|
||||||
|
@@ -1104,7 +1104,7 @@ def Test_set_get_bufline()
|
|||||||
assert_equal([], getbufline(b, 2, 1))
|
assert_equal([], getbufline(b, 2, 1))
|
||||||
|
|
||||||
if has('job')
|
if has('job')
|
||||||
setbufline(b, 2, [function('eval'), {key: 123}, test_null_job()])
|
setbufline(b, 2, [function('eval'), {key: 123}, string(test_null_job())])
|
||||||
assert_equal(["function('eval')",
|
assert_equal(["function('eval')",
|
||||||
"{'key': 123}",
|
"{'key': 123}",
|
||||||
"no process"],
|
"no process"],
|
||||||
@@ -1250,6 +1250,16 @@ def Test_submatch()
|
|||||||
actual->assert_equal(expected)
|
actual->assert_equal(expected)
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
|
def Test_substitute()
|
||||||
|
var res = substitute('A1234', '\d', 'X', '')
|
||||||
|
assert_equal('AX234', res)
|
||||||
|
|
||||||
|
if has('job')
|
||||||
|
assert_fails('"text"->substitute(".*", () => job_start(":"), "")', 'E908: using an invalid value as a String: job')
|
||||||
|
assert_fails('"text"->substitute(".*", () => job_start(":")->job_getchannel(), "")', 'E908: using an invalid value as a String: channel')
|
||||||
|
endif
|
||||||
|
enddef
|
||||||
|
|
||||||
def Test_synID()
|
def Test_synID()
|
||||||
new
|
new
|
||||||
setline(1, "text")
|
setline(1, "text")
|
||||||
|
40
src/typval.c
40
src/typval.c
@@ -414,7 +414,7 @@ tv_get_string_strict(typval_T *varp)
|
|||||||
char_u *
|
char_u *
|
||||||
tv_get_string_buf(typval_T *varp, char_u *buf)
|
tv_get_string_buf(typval_T *varp, char_u *buf)
|
||||||
{
|
{
|
||||||
char_u *res = tv_get_string_buf_chk(varp, buf);
|
char_u *res = tv_get_string_buf_chk(varp, buf);
|
||||||
|
|
||||||
return res != NULL ? res : (char_u *)"";
|
return res != NULL ? res : (char_u *)"";
|
||||||
}
|
}
|
||||||
@@ -478,44 +478,22 @@ tv_get_string_buf_chk_strict(typval_T *varp, char_u *buf, int strict)
|
|||||||
break;
|
break;
|
||||||
case VAR_JOB:
|
case VAR_JOB:
|
||||||
#ifdef FEAT_JOB_CHANNEL
|
#ifdef FEAT_JOB_CHANNEL
|
||||||
|
if (in_vim9script())
|
||||||
{
|
{
|
||||||
job_T *job = varp->vval.v_job;
|
semsg(_(e_using_invalid_value_as_string_str), "job");
|
||||||
char *status;
|
break;
|
||||||
|
|
||||||
if (job == NULL)
|
|
||||||
return (char_u *)"no process";
|
|
||||||
status = job->jv_status == JOB_FAILED ? "fail"
|
|
||||||
: job->jv_status >= JOB_ENDED ? "dead"
|
|
||||||
: "run";
|
|
||||||
# ifdef UNIX
|
|
||||||
vim_snprintf((char *)buf, NUMBUFLEN,
|
|
||||||
"process %ld %s", (long)job->jv_pid, status);
|
|
||||||
# elif defined(MSWIN)
|
|
||||||
vim_snprintf((char *)buf, NUMBUFLEN,
|
|
||||||
"process %ld %s",
|
|
||||||
(long)job->jv_proc_info.dwProcessId,
|
|
||||||
status);
|
|
||||||
# else
|
|
||||||
// fall-back
|
|
||||||
vim_snprintf((char *)buf, NUMBUFLEN, "process ? %s", status);
|
|
||||||
# endif
|
|
||||||
return buf;
|
|
||||||
}
|
}
|
||||||
|
return job_to_string_buf(varp, buf);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case VAR_CHANNEL:
|
case VAR_CHANNEL:
|
||||||
#ifdef FEAT_JOB_CHANNEL
|
#ifdef FEAT_JOB_CHANNEL
|
||||||
|
if (in_vim9script())
|
||||||
{
|
{
|
||||||
channel_T *channel = varp->vval.v_channel;
|
semsg(_(e_using_invalid_value_as_string_str), "channel");
|
||||||
char *status = channel_status(channel, -1);
|
break;
|
||||||
|
|
||||||
if (channel == NULL)
|
|
||||||
vim_snprintf((char *)buf, NUMBUFLEN, "channel %s", status);
|
|
||||||
else
|
|
||||||
vim_snprintf((char *)buf, NUMBUFLEN,
|
|
||||||
"channel %d %s", channel->ch_id, status);
|
|
||||||
return buf;
|
|
||||||
}
|
}
|
||||||
|
return channel_to_string_buf(varp, buf);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case VAR_UNKNOWN:
|
case VAR_UNKNOWN:
|
||||||
|
@@ -750,6 +750,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
2944,
|
||||||
/**/
|
/**/
|
||||||
2943,
|
2943,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -4831,10 +4831,11 @@ list_instructions(char *pfx, isn_T *instr, int instr_count, ufunc_T *ufunc)
|
|||||||
{
|
{
|
||||||
typval_T tv;
|
typval_T tv;
|
||||||
char_u *name;
|
char_u *name;
|
||||||
|
char_u buf[NUMBUFLEN];
|
||||||
|
|
||||||
tv.v_type = VAR_JOB;
|
tv.v_type = VAR_JOB;
|
||||||
tv.vval.v_job = iptr->isn_arg.job;
|
tv.vval.v_job = iptr->isn_arg.job;
|
||||||
name = tv_get_string(&tv);
|
name = job_to_string_buf(&tv, buf);
|
||||||
smsg("%s%4d PUSHJOB \"%s\"", pfx, current, name);
|
smsg("%s%4d PUSHJOB \"%s\"", pfx, current, name);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user