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;