diff options
Diffstat (limited to 'src/eval.c')
-rw-r--r-- | src/eval.c | 506 |
1 files changed, 10 insertions, 496 deletions
diff --git a/src/eval.c b/src/eval.c index 8c065f26e..ae89f7e2b 100644 --- a/src/eval.c +++ b/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; @@ -6990,6 +6990,15 @@ set_vim_var_nr(int idx, varnumber_T 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. */ varnumber_T @@ -9592,30 +9601,6 @@ reset_v_option_vars(void) } /* - * 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. */ void @@ -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". */ |