@@ -696,6 +696,70 @@ eval_to_bool(
696696 return (int )retval ;
697697}
698698
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+
699763/*
700764 * Top level evaluation function, returning a string. If "skip" is TRUE,
701765 * only parsing to "nextcmd" is done, without reporting errors. Return
@@ -9971,44 +10035,13 @@ filter_map_one(typval_T *tv, typval_T *expr, int map, int *remp)
997110035{
997210036 typval_T rettv ;
997310037 typval_T argv [3 ];
9974- char_u buf [NUMBUFLEN ];
9975- char_u * s ;
997610038 int retval = FAIL ;
9977- int dummy ;
997810039
997910040 copy_tv (tv , & vimvars [VV_VAL ].vv_tv );
998010041 argv [0 ] = vimvars [VV_KEY ].vv_tv ;
998110042 argv [1 ] = vimvars [VV_VAL ].vv_tv ;
9982- if (expr -> v_type == VAR_FUNC )
9983- {
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- }
10043+ if (eval_expr_typval (expr , argv , 2 , & rettv ) == FAIL )
10044+ goto theend ;
1001210045 if (map )
1001310046 {
1001410047 /* map(): replace the list item value */
0 commit comments