diff options
Diffstat (limited to 'src/nvim/eval.c')
-rw-r--r-- | src/nvim/eval.c | 77 |
1 files changed, 56 insertions, 21 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c index a43a389478..7a2ac65ce1 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -3297,6 +3297,26 @@ char_u *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 pattern_match(char_u *pat, char_u *text, int ic) +{ + int matches = 0; + regmatch_T regmatch; + + // avoid 'l' flag in 'cpoptions' + char_u *save_cpo = p_cpo; + p_cpo = (char_u *)""; + regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); + if (regmatch.regprog != NULL) { + regmatch.rm_ic = ic; + matches = vim_regexec_nl(®match, text, (colnr_T)0); + vim_regfree(regmatch.regprog); + } + p_cpo = save_cpo; + return matches; +} + /* * types for expressions. */ @@ -3572,9 +3592,7 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate) long n1, n2; char_u *s1, *s2; char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; - regmatch_T regmatch; int ic; - char_u *save_cpo; /* * Get the first variable. @@ -3783,19 +3801,10 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate) case TYPE_MATCH: case TYPE_NOMATCH: - /* avoid 'l' flag in 'cpoptions' */ - save_cpo = p_cpo; - p_cpo = (char_u *)""; - regmatch.regprog = vim_regcomp(s2, - RE_MAGIC + RE_STRING); - regmatch.rm_ic = ic; - if (regmatch.regprog != NULL) { - n1 = vim_regexec_nl(®match, s1, (colnr_T)0); - vim_regfree(regmatch.regprog); - if (type == TYPE_NOMATCH) - n1 = !n1; + n1 = pattern_match(s2, s1, ic); + if (type == TYPE_NOMATCH) { + n1 = !n1; } - p_cpo = save_cpo; break; case TYPE_UNKNOWN: break; /* avoid gcc warning */ @@ -6697,6 +6706,7 @@ static struct fst { { "assert_exception", 1, 2, f_assert_exception }, { "assert_fails", 1, 2, f_assert_fails }, { "assert_false", 1, 2, f_assert_false }, + { "assert_match", 2, 3, f_assert_match }, { "assert_true", 1, 2, f_assert_true }, { "atan", 1, 1, f_atan }, { "atan2", 2, 2, f_atan2 }, @@ -7606,7 +7616,7 @@ static void prepare_assert_error(garray_T *gap) // Fill "gap" with information about an assert error. static void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv, char_u *exp_str, typval_T *exp_tv, - typval_T *got_tv) + typval_T *got_tv, bool is_match) { char_u *tofree; @@ -7615,7 +7625,11 @@ static void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv, ga_concat(gap, tofree); xfree(tofree); } else { - ga_concat(gap, (char_u *)"Expected "); + if (is_match) { + ga_concat(gap, (char_u *)"Pattern "); + } else { + ga_concat(gap, (char_u *)"Expected "); + } if (exp_str == NULL) { tofree = (char_u *) encode_tv2string(exp_tv, NULL); ga_concat(gap, tofree); @@ -7624,7 +7638,11 @@ static void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv, ga_concat(gap, exp_str); } tofree = (char_u *) encode_tv2string(got_tv, NULL); - ga_concat(gap, (char_u *)" but got "); + if (is_match) { + ga_concat(gap, (char_u *)" does not match "); + } else { + ga_concat(gap, (char_u *)" but got "); + } ga_concat(gap, tofree); xfree(tofree); } @@ -7651,7 +7669,7 @@ static void f_assert_equal(typval_T *argvars, typval_T *rettv) if (!tv_equal(&argvars[0], &argvars[1], false, false)) { prepare_assert_error(&ga); fill_assert_error(&ga, &argvars[2], NULL, - &argvars[0], &argvars[1]); + &argvars[0], &argvars[1], false); assert_error(&ga); ga_clear(&ga); } @@ -7672,7 +7690,7 @@ static void f_assert_exception(typval_T *argvars, typval_T *rettv) && strstr((char *)vimvars[VV_EXCEPTION].vv_str, error) == NULL) { prepare_assert_error(&ga); fill_assert_error(&ga, &argvars[1], NULL, &argvars[0], - &vimvars[VV_EXCEPTION].vv_tv); + &vimvars[VV_EXCEPTION].vv_tv, false); assert_error(&ga); ga_clear(&ga); } @@ -7702,7 +7720,7 @@ static void f_assert_fails(typval_T *argvars, typval_T *rettv) || 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); + &vimvars[VV_ERRMSG].vv_tv, false); assert_error(&ga); ga_clear(&ga); } @@ -7732,7 +7750,7 @@ static void assert_bool(typval_T *argvars, bool is_true) prepare_assert_error(&ga); fill_assert_error(&ga, &argvars[1], (char_u *)(is_true ? "True" : "False"), - NULL, &argvars[0]); + NULL, &argvars[0], false); assert_error(&ga); ga_clear(&ga); } @@ -7744,6 +7762,23 @@ static void f_assert_false(typval_T *argvars, typval_T *rettv) assert_bool(argvars, false); } +/// "assert_match(pattern, actual[, msg])" function +static void f_assert_match(typval_T *argvars, typval_T *rettv) +{ + char_u buf1[NUMBUFLEN]; + char_u buf2[NUMBUFLEN]; + char_u *pat = get_tv_string_buf_chk(&argvars[0], buf1); + char_u *text = get_tv_string_buf_chk(&argvars[1], buf2); + + if (!pattern_match(pat, text, false)) { + garray_T ga; + prepare_assert_error(&ga); + fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1], true); + assert_error(&ga); + ga_clear(&ga); + } +} + // "assert_true(actual[, msg])" function static void f_assert_true(typval_T *argvars, typval_T *rettv) { |