mirror of
https://github.com/vim/vim.git
synced 2025-09-24 03:44:06 -04:00
patch 8.1.1687: the evalfunc.c file is too big
Problem: The evalfunc.c file is too big. Solution: Move testing support to a separate file.
This commit is contained in:
506
src/eval.c
506
src/eval.c
@@ -3621,7 +3621,7 @@ get_user_var_name(expand_T *xp, int idx)
|
||||
* Return TRUE if "pat" matches "text".
|
||||
* Does not use 'cpo' and always uses 'magic'.
|
||||
*/
|
||||
static int
|
||||
int
|
||||
pattern_match(char_u *pat, char_u *text, int ic)
|
||||
{
|
||||
int matches = FALSE;
|
||||
@@ -6989,6 +6989,15 @@ set_vim_var_nr(int idx, varnumber_T val)
|
||||
vimvars[idx].vv_nr = val;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get typval_T v: variable value.
|
||||
*/
|
||||
typval_T *
|
||||
get_vim_var_tv(int idx)
|
||||
{
|
||||
return &vimvars[idx].vv_tv;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get number v: variable value.
|
||||
*/
|
||||
@@ -9591,30 +9600,6 @@ reset_v_option_vars(void)
|
||||
set_vim_var_string(VV_OPTION_COMMAND, NULL, -1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare "gap" for an assert error and add the sourcing position.
|
||||
*/
|
||||
void
|
||||
prepare_assert_error(garray_T *gap)
|
||||
{
|
||||
char buf[NUMBUFLEN];
|
||||
|
||||
ga_init2(gap, 1, 100);
|
||||
if (sourcing_name != NULL)
|
||||
{
|
||||
ga_concat(gap, sourcing_name);
|
||||
if (sourcing_lnum > 0)
|
||||
ga_concat(gap, (char_u *)" ");
|
||||
}
|
||||
if (sourcing_lnum > 0)
|
||||
{
|
||||
sprintf(buf, "line %ld", (long)sourcing_lnum);
|
||||
ga_concat(gap, (char_u *)buf);
|
||||
}
|
||||
if (sourcing_name != NULL || sourcing_lnum > 0)
|
||||
ga_concat(gap, (char_u *)": ");
|
||||
}
|
||||
|
||||
/*
|
||||
* Add an assert error to v:errors.
|
||||
*/
|
||||
@@ -9628,477 +9613,6 @@ assert_error(garray_T *gap)
|
||||
set_vim_var_list(VV_ERRORS, list_alloc());
|
||||
list_append_string(vimvars[VV_ERRORS].vv_list, gap->ga_data, gap->ga_len);
|
||||
}
|
||||
|
||||
int
|
||||
assert_equal_common(typval_T *argvars, assert_type_T atype)
|
||||
{
|
||||
garray_T ga;
|
||||
|
||||
if (tv_equal(&argvars[0], &argvars[1], FALSE, FALSE)
|
||||
!= (atype == ASSERT_EQUAL))
|
||||
{
|
||||
prepare_assert_error(&ga);
|
||||
fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1],
|
||||
atype);
|
||||
assert_error(&ga);
|
||||
ga_clear(&ga);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
assert_equalfile(typval_T *argvars)
|
||||
{
|
||||
char_u buf1[NUMBUFLEN];
|
||||
char_u buf2[NUMBUFLEN];
|
||||
char_u *fname1 = tv_get_string_buf_chk(&argvars[0], buf1);
|
||||
char_u *fname2 = tv_get_string_buf_chk(&argvars[1], buf2);
|
||||
garray_T ga;
|
||||
FILE *fd1;
|
||||
FILE *fd2;
|
||||
|
||||
if (fname1 == NULL || fname2 == NULL)
|
||||
return 0;
|
||||
|
||||
IObuff[0] = NUL;
|
||||
fd1 = mch_fopen((char *)fname1, READBIN);
|
||||
if (fd1 == NULL)
|
||||
{
|
||||
vim_snprintf((char *)IObuff, IOSIZE, (char *)e_notread, fname1);
|
||||
}
|
||||
else
|
||||
{
|
||||
fd2 = mch_fopen((char *)fname2, READBIN);
|
||||
if (fd2 == NULL)
|
||||
{
|
||||
fclose(fd1);
|
||||
vim_snprintf((char *)IObuff, IOSIZE, (char *)e_notread, fname2);
|
||||
}
|
||||
else
|
||||
{
|
||||
int c1, c2;
|
||||
long count = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
c1 = fgetc(fd1);
|
||||
c2 = fgetc(fd2);
|
||||
if (c1 == EOF)
|
||||
{
|
||||
if (c2 != EOF)
|
||||
STRCPY(IObuff, "first file is shorter");
|
||||
break;
|
||||
}
|
||||
else if (c2 == EOF)
|
||||
{
|
||||
STRCPY(IObuff, "second file is shorter");
|
||||
break;
|
||||
}
|
||||
else if (c1 != c2)
|
||||
{
|
||||
vim_snprintf((char *)IObuff, IOSIZE,
|
||||
"difference at byte %ld", count);
|
||||
break;
|
||||
}
|
||||
++count;
|
||||
}
|
||||
fclose(fd1);
|
||||
fclose(fd2);
|
||||
}
|
||||
}
|
||||
if (IObuff[0] != NUL)
|
||||
{
|
||||
prepare_assert_error(&ga);
|
||||
ga_concat(&ga, IObuff);
|
||||
assert_error(&ga);
|
||||
ga_clear(&ga);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
assert_match_common(typval_T *argvars, assert_type_T atype)
|
||||
{
|
||||
garray_T ga;
|
||||
char_u buf1[NUMBUFLEN];
|
||||
char_u buf2[NUMBUFLEN];
|
||||
char_u *pat = tv_get_string_buf_chk(&argvars[0], buf1);
|
||||
char_u *text = tv_get_string_buf_chk(&argvars[1], buf2);
|
||||
|
||||
if (pat == NULL || text == NULL)
|
||||
emsg(_(e_invarg));
|
||||
else if (pattern_match(pat, text, FALSE) != (atype == ASSERT_MATCH))
|
||||
{
|
||||
prepare_assert_error(&ga);
|
||||
fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1],
|
||||
atype);
|
||||
assert_error(&ga);
|
||||
ga_clear(&ga);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
assert_inrange(typval_T *argvars)
|
||||
{
|
||||
garray_T ga;
|
||||
int error = FALSE;
|
||||
char_u *tofree;
|
||||
char msg[200];
|
||||
char_u numbuf[NUMBUFLEN];
|
||||
|
||||
#ifdef FEAT_FLOAT
|
||||
if (argvars[0].v_type == VAR_FLOAT
|
||||
|| argvars[1].v_type == VAR_FLOAT
|
||||
|| argvars[2].v_type == VAR_FLOAT)
|
||||
{
|
||||
float_T flower = tv_get_float(&argvars[0]);
|
||||
float_T fupper = tv_get_float(&argvars[1]);
|
||||
float_T factual = tv_get_float(&argvars[2]);
|
||||
|
||||
if (factual < flower || factual > fupper)
|
||||
{
|
||||
prepare_assert_error(&ga);
|
||||
if (argvars[3].v_type != VAR_UNKNOWN)
|
||||
{
|
||||
ga_concat(&ga, tv2string(&argvars[3], &tofree, numbuf, 0));
|
||||
vim_free(tofree);
|
||||
}
|
||||
else
|
||||
{
|
||||
vim_snprintf(msg, 200, "Expected range %g - %g, but got %g",
|
||||
flower, fupper, factual);
|
||||
ga_concat(&ga, (char_u *)msg);
|
||||
}
|
||||
assert_error(&ga);
|
||||
ga_clear(&ga);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
varnumber_T lower = tv_get_number_chk(&argvars[0], &error);
|
||||
varnumber_T upper = tv_get_number_chk(&argvars[1], &error);
|
||||
varnumber_T actual = tv_get_number_chk(&argvars[2], &error);
|
||||
|
||||
if (error)
|
||||
return 0;
|
||||
if (actual < lower || actual > upper)
|
||||
{
|
||||
prepare_assert_error(&ga);
|
||||
if (argvars[3].v_type != VAR_UNKNOWN)
|
||||
{
|
||||
ga_concat(&ga, tv2string(&argvars[3], &tofree, numbuf, 0));
|
||||
vim_free(tofree);
|
||||
}
|
||||
else
|
||||
{
|
||||
vim_snprintf(msg, 200, "Expected range %ld - %ld, but got %ld",
|
||||
(long)lower, (long)upper, (long)actual);
|
||||
ga_concat(&ga, (char_u *)msg);
|
||||
}
|
||||
assert_error(&ga);
|
||||
ga_clear(&ga);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Common for assert_true() and assert_false().
|
||||
* Return non-zero for failure.
|
||||
*/
|
||||
int
|
||||
assert_bool(typval_T *argvars, int isTrue)
|
||||
{
|
||||
int error = FALSE;
|
||||
garray_T ga;
|
||||
|
||||
if (argvars[0].v_type == VAR_SPECIAL
|
||||
&& argvars[0].vval.v_number == (isTrue ? VVAL_TRUE : VVAL_FALSE))
|
||||
return 0;
|
||||
if (argvars[0].v_type != VAR_NUMBER
|
||||
|| (tv_get_number_chk(&argvars[0], &error) == 0) == isTrue
|
||||
|| error)
|
||||
{
|
||||
prepare_assert_error(&ga);
|
||||
fill_assert_error(&ga, &argvars[1],
|
||||
(char_u *)(isTrue ? "True" : "False"),
|
||||
NULL, &argvars[0], ASSERT_OTHER);
|
||||
assert_error(&ga);
|
||||
ga_clear(&ga);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
assert_report(typval_T *argvars)
|
||||
{
|
||||
garray_T ga;
|
||||
|
||||
prepare_assert_error(&ga);
|
||||
ga_concat(&ga, tv_get_string(&argvars[0]));
|
||||
assert_error(&ga);
|
||||
ga_clear(&ga);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
assert_exception(typval_T *argvars)
|
||||
{
|
||||
garray_T ga;
|
||||
char_u *error = tv_get_string_chk(&argvars[0]);
|
||||
|
||||
if (vimvars[VV_EXCEPTION].vv_str == NULL)
|
||||
{
|
||||
prepare_assert_error(&ga);
|
||||
ga_concat(&ga, (char_u *)"v:exception is not set");
|
||||
assert_error(&ga);
|
||||
ga_clear(&ga);
|
||||
return 1;
|
||||
}
|
||||
else if (error != NULL
|
||||
&& strstr((char *)vimvars[VV_EXCEPTION].vv_str, (char *)error) == NULL)
|
||||
{
|
||||
prepare_assert_error(&ga);
|
||||
fill_assert_error(&ga, &argvars[1], NULL, &argvars[0],
|
||||
&vimvars[VV_EXCEPTION].vv_tv, ASSERT_OTHER);
|
||||
assert_error(&ga);
|
||||
ga_clear(&ga);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
assert_beeps(typval_T *argvars)
|
||||
{
|
||||
char_u *cmd = tv_get_string_chk(&argvars[0]);
|
||||
garray_T ga;
|
||||
int ret = 0;
|
||||
|
||||
called_vim_beep = FALSE;
|
||||
suppress_errthrow = TRUE;
|
||||
emsg_silent = FALSE;
|
||||
do_cmdline_cmd(cmd);
|
||||
if (!called_vim_beep)
|
||||
{
|
||||
prepare_assert_error(&ga);
|
||||
ga_concat(&ga, (char_u *)"command did not beep: ");
|
||||
ga_concat(&ga, cmd);
|
||||
assert_error(&ga);
|
||||
ga_clear(&ga);
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
suppress_errthrow = FALSE;
|
||||
emsg_on_display = FALSE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
assert_append_cmd_or_arg(garray_T *gap, typval_T *argvars, char_u *cmd)
|
||||
{
|
||||
char_u *tofree;
|
||||
char_u numbuf[NUMBUFLEN];
|
||||
|
||||
if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN)
|
||||
{
|
||||
ga_concat(gap, echo_string(&argvars[2], &tofree, numbuf, 0));
|
||||
vim_free(tofree);
|
||||
}
|
||||
else
|
||||
ga_concat(gap, cmd);
|
||||
}
|
||||
|
||||
int
|
||||
assert_fails(typval_T *argvars)
|
||||
{
|
||||
char_u *cmd = tv_get_string_chk(&argvars[0]);
|
||||
garray_T ga;
|
||||
int ret = 0;
|
||||
int save_trylevel = trylevel;
|
||||
|
||||
// trylevel must be zero for a ":throw" command to be considered failed
|
||||
trylevel = 0;
|
||||
called_emsg = FALSE;
|
||||
suppress_errthrow = TRUE;
|
||||
emsg_silent = TRUE;
|
||||
|
||||
do_cmdline_cmd(cmd);
|
||||
if (!called_emsg)
|
||||
{
|
||||
prepare_assert_error(&ga);
|
||||
ga_concat(&ga, (char_u *)"command did not fail: ");
|
||||
assert_append_cmd_or_arg(&ga, argvars, cmd);
|
||||
assert_error(&ga);
|
||||
ga_clear(&ga);
|
||||
ret = 1;
|
||||
}
|
||||
else if (argvars[1].v_type != VAR_UNKNOWN)
|
||||
{
|
||||
char_u buf[NUMBUFLEN];
|
||||
char *error = (char *)tv_get_string_buf_chk(&argvars[1], buf);
|
||||
|
||||
if (error == NULL
|
||||
|| strstr((char *)vimvars[VV_ERRMSG].vv_str, error) == NULL)
|
||||
{
|
||||
prepare_assert_error(&ga);
|
||||
fill_assert_error(&ga, &argvars[2], NULL, &argvars[1],
|
||||
&vimvars[VV_ERRMSG].vv_tv, ASSERT_OTHER);
|
||||
ga_concat(&ga, (char_u *)": ");
|
||||
assert_append_cmd_or_arg(&ga, argvars, cmd);
|
||||
assert_error(&ga);
|
||||
ga_clear(&ga);
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
|
||||
trylevel = save_trylevel;
|
||||
called_emsg = FALSE;
|
||||
suppress_errthrow = FALSE;
|
||||
emsg_silent = FALSE;
|
||||
emsg_on_display = FALSE;
|
||||
set_vim_var_string(VV_ERRMSG, NULL, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Append "p[clen]" to "gap", escaping unprintable characters.
|
||||
* Changes NL to \n, CR to \r, etc.
|
||||
*/
|
||||
static void
|
||||
ga_concat_esc(garray_T *gap, char_u *p, int clen)
|
||||
{
|
||||
char_u buf[NUMBUFLEN];
|
||||
|
||||
if (clen > 1)
|
||||
{
|
||||
mch_memmove(buf, p, clen);
|
||||
buf[clen] = NUL;
|
||||
ga_concat(gap, buf);
|
||||
}
|
||||
else switch (*p)
|
||||
{
|
||||
case BS: ga_concat(gap, (char_u *)"\\b"); break;
|
||||
case ESC: ga_concat(gap, (char_u *)"\\e"); break;
|
||||
case FF: ga_concat(gap, (char_u *)"\\f"); break;
|
||||
case NL: ga_concat(gap, (char_u *)"\\n"); break;
|
||||
case TAB: ga_concat(gap, (char_u *)"\\t"); break;
|
||||
case CAR: ga_concat(gap, (char_u *)"\\r"); break;
|
||||
case '\\': ga_concat(gap, (char_u *)"\\\\"); break;
|
||||
default:
|
||||
if (*p < ' ')
|
||||
{
|
||||
vim_snprintf((char *)buf, NUMBUFLEN, "\\x%02x", *p);
|
||||
ga_concat(gap, buf);
|
||||
}
|
||||
else
|
||||
ga_append(gap, *p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Append "str" to "gap", escaping unprintable characters.
|
||||
* Changes NL to \n, CR to \r, etc.
|
||||
*/
|
||||
static void
|
||||
ga_concat_shorten_esc(garray_T *gap, char_u *str)
|
||||
{
|
||||
char_u *p;
|
||||
char_u *s;
|
||||
int c;
|
||||
int clen;
|
||||
char_u buf[NUMBUFLEN];
|
||||
int same_len;
|
||||
|
||||
if (str == NULL)
|
||||
{
|
||||
ga_concat(gap, (char_u *)"NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
for (p = str; *p != NUL; ++p)
|
||||
{
|
||||
same_len = 1;
|
||||
s = p;
|
||||
c = mb_ptr2char_adv(&s);
|
||||
clen = s - p;
|
||||
while (*s != NUL && c == mb_ptr2char(s))
|
||||
{
|
||||
++same_len;
|
||||
s += clen;
|
||||
}
|
||||
if (same_len > 20)
|
||||
{
|
||||
ga_concat(gap, (char_u *)"\\[");
|
||||
ga_concat_esc(gap, p, clen);
|
||||
ga_concat(gap, (char_u *)" occurs ");
|
||||
vim_snprintf((char *)buf, NUMBUFLEN, "%d", same_len);
|
||||
ga_concat(gap, buf);
|
||||
ga_concat(gap, (char_u *)" times]");
|
||||
p = s - 1;
|
||||
}
|
||||
else
|
||||
ga_concat_esc(gap, p, clen);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill "gap" with information about an assert error.
|
||||
*/
|
||||
void
|
||||
fill_assert_error(
|
||||
garray_T *gap,
|
||||
typval_T *opt_msg_tv,
|
||||
char_u *exp_str,
|
||||
typval_T *exp_tv,
|
||||
typval_T *got_tv,
|
||||
assert_type_T atype)
|
||||
{
|
||||
char_u numbuf[NUMBUFLEN];
|
||||
char_u *tofree;
|
||||
|
||||
if (opt_msg_tv->v_type != VAR_UNKNOWN)
|
||||
{
|
||||
ga_concat(gap, echo_string(opt_msg_tv, &tofree, numbuf, 0));
|
||||
vim_free(tofree);
|
||||
ga_concat(gap, (char_u *)": ");
|
||||
}
|
||||
|
||||
if (atype == ASSERT_MATCH || atype == ASSERT_NOTMATCH)
|
||||
ga_concat(gap, (char_u *)"Pattern ");
|
||||
else if (atype == ASSERT_NOTEQUAL)
|
||||
ga_concat(gap, (char_u *)"Expected not equal to ");
|
||||
else
|
||||
ga_concat(gap, (char_u *)"Expected ");
|
||||
if (exp_str == NULL)
|
||||
{
|
||||
ga_concat_shorten_esc(gap, tv2string(exp_tv, &tofree, numbuf, 0));
|
||||
vim_free(tofree);
|
||||
}
|
||||
else
|
||||
ga_concat_shorten_esc(gap, exp_str);
|
||||
if (atype != ASSERT_NOTEQUAL)
|
||||
{
|
||||
if (atype == ASSERT_MATCH)
|
||||
ga_concat(gap, (char_u *)" does not match ");
|
||||
else if (atype == ASSERT_NOTMATCH)
|
||||
ga_concat(gap, (char_u *)" does match ");
|
||||
else
|
||||
ga_concat(gap, (char_u *)" but got ");
|
||||
ga_concat_shorten_esc(gap, tv2string(got_tv, &tofree, numbuf, 0));
|
||||
vim_free(tofree);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare "typ1" and "typ2". Put the result in "typ1".
|
||||
*/
|
||||
|
Reference in New Issue
Block a user