Mercurial > vim
comparison src/eval.c @ 12722:7749260f261c v8.0.1239
patch 8.0.1239: cannot use a lambda for the skip argument to searchpair()
commit https://github.com/vim/vim/commit/48570488f17e397183ea7d5c7ca67d6e4ffb013d
Author: Bram Moolenaar <Bram@vim.org>
Date: Mon Oct 30 21:48:41 2017 +0100
patch 8.0.1239: cannot use a lambda for the skip argument to searchpair()
Problem: Cannot use a lambda for the skip argument to searchpair().
Solution: Evaluate a partial, funcref and lambda. (LemonBoy, closes https://github.com/vim/vim/issues/1454,
closes #2265)
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Mon, 30 Oct 2017 22:00:05 +0100 |
parents | e769c912fcd9 |
children | 9c1659761fc3 |
comparison
equal
deleted
inserted
replaced
12721:e6b964b3856d | 12722:7749260f261c |
---|---|
694 --emsg_skip; | 694 --emsg_skip; |
695 | 695 |
696 return (int)retval; | 696 return (int)retval; |
697 } | 697 } |
698 | 698 |
699 static int | |
700 eval_expr_typval(typval_T *expr, typval_T *argv, int argc, typval_T *rettv) | |
701 { | |
702 char_u *s; | |
703 int dummy; | |
704 char_u buf[NUMBUFLEN]; | |
705 | |
706 if (expr->v_type == VAR_FUNC) | |
707 { | |
708 s = expr->vval.v_string; | |
709 if (s == NULL || *s == NUL) | |
710 return FAIL; | |
711 if (call_func(s, (int)STRLEN(s), rettv, argc, argv, NULL, | |
712 0L, 0L, &dummy, TRUE, NULL, NULL) == FAIL) | |
713 return FAIL; | |
714 } | |
715 else if (expr->v_type == VAR_PARTIAL) | |
716 { | |
717 partial_T *partial = expr->vval.v_partial; | |
718 | |
719 s = partial_name(partial); | |
720 if (s == NULL || *s == NUL) | |
721 return FAIL; | |
722 if (call_func(s, (int)STRLEN(s), rettv, argc, argv, NULL, | |
723 0L, 0L, &dummy, TRUE, partial, NULL) == FAIL) | |
724 return FAIL; | |
725 } | |
726 else | |
727 { | |
728 s = get_tv_string_buf_chk(expr, buf); | |
729 if (s == NULL) | |
730 return FAIL; | |
731 s = skipwhite(s); | |
732 if (eval1(&s, rettv, TRUE) == FAIL) | |
733 return FAIL; | |
734 if (*s != NUL) /* check for trailing chars after expr */ | |
735 { | |
736 EMSG2(_(e_invexpr2), s); | |
737 return FAIL; | |
738 } | |
739 } | |
740 return OK; | |
741 } | |
742 | |
743 /* | |
744 * Like eval_to_bool() but using a typval_T instead of a string. | |
745 * Works for string, funcref and partial. | |
746 */ | |
747 int | |
748 eval_expr_to_bool(typval_T *expr, int *error) | |
749 { | |
750 typval_T rettv; | |
751 int res; | |
752 | |
753 if (eval_expr_typval(expr, NULL, 0, &rettv) == FAIL) | |
754 { | |
755 *error = TRUE; | |
756 return FALSE; | |
757 } | |
758 res = (get_tv_number_chk(&rettv, error) != 0); | |
759 clear_tv(&rettv); | |
760 return res; | |
761 } | |
762 | |
699 /* | 763 /* |
700 * Top level evaluation function, returning a string. If "skip" is TRUE, | 764 * Top level evaluation function, returning a string. If "skip" is TRUE, |
701 * only parsing to "nextcmd" is done, without reporting errors. Return | 765 * only parsing to "nextcmd" is done, without reporting errors. Return |
702 * pointer to allocated memory, or NULL for failure or when "skip" is TRUE. | 766 * pointer to allocated memory, or NULL for failure or when "skip" is TRUE. |
703 */ | 767 */ |
9969 static int | 10033 static int |
9970 filter_map_one(typval_T *tv, typval_T *expr, int map, int *remp) | 10034 filter_map_one(typval_T *tv, typval_T *expr, int map, int *remp) |
9971 { | 10035 { |
9972 typval_T rettv; | 10036 typval_T rettv; |
9973 typval_T argv[3]; | 10037 typval_T argv[3]; |
9974 char_u buf[NUMBUFLEN]; | |
9975 char_u *s; | |
9976 int retval = FAIL; | 10038 int retval = FAIL; |
9977 int dummy; | |
9978 | 10039 |
9979 copy_tv(tv, &vimvars[VV_VAL].vv_tv); | 10040 copy_tv(tv, &vimvars[VV_VAL].vv_tv); |
9980 argv[0] = vimvars[VV_KEY].vv_tv; | 10041 argv[0] = vimvars[VV_KEY].vv_tv; |
9981 argv[1] = vimvars[VV_VAL].vv_tv; | 10042 argv[1] = vimvars[VV_VAL].vv_tv; |
9982 if (expr->v_type == VAR_FUNC) | 10043 if (eval_expr_typval(expr, argv, 2, &rettv) == FAIL) |
9983 { | 10044 goto theend; |
9984 s = expr->vval.v_string; | |
9985 if (call_func(s, (int)STRLEN(s), &rettv, 2, argv, NULL, | |
9986 0L, 0L, &dummy, TRUE, NULL, NULL) == FAIL) | |
9987 goto theend; | |
9988 } | |
9989 else if (expr->v_type == VAR_PARTIAL) | |
9990 { | |
9991 partial_T *partial = expr->vval.v_partial; | |
9992 | |
9993 s = partial_name(partial); | |
9994 if (call_func(s, (int)STRLEN(s), &rettv, 2, argv, NULL, | |
9995 0L, 0L, &dummy, TRUE, partial, NULL) == FAIL) | |
9996 goto theend; | |
9997 } | |
9998 else | |
9999 { | |
10000 s = get_tv_string_buf_chk(expr, buf); | |
10001 if (s == NULL) | |
10002 goto theend; | |
10003 s = skipwhite(s); | |
10004 if (eval1(&s, &rettv, TRUE) == FAIL) | |
10005 goto theend; | |
10006 if (*s != NUL) /* check for trailing chars after expr */ | |
10007 { | |
10008 EMSG2(_(e_invexpr2), s); | |
10009 goto theend; | |
10010 } | |
10011 } | |
10012 if (map) | 10045 if (map) |
10013 { | 10046 { |
10014 /* map(): replace the list item value */ | 10047 /* map(): replace the list item value */ |
10015 clear_tv(tv); | 10048 clear_tv(tv); |
10016 rettv.v_lock = 0; | 10049 rettv.v_lock = 0; |