Mercurial > vim
comparison src/eval.c @ 13262:69278c25429d v8.0.1505
patch 8.0.1505: debugger can't break on a condition
commit https://github.com/vim/vim/commit/c6f9f739d32084923c3031cbf6f581f8c8bf7fd2
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Feb 11 19:06:26 2018 +0100
patch 8.0.1505: debugger can't break on a condition
Problem: Debugger can't break on a condition. (Charles Campbell)
Solution: Add ":breakadd expr". (Christian Brabandt, closes https://github.com/vim/vim/issues/859)
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Sun, 11 Feb 2018 19:15:05 +0100 |
parents | ac42c4b11dbc |
children | abaebba89fd4 |
comparison
equal
deleted
inserted
replaced
13261:fa53b212be26 | 13262:69278c25429d |
---|---|
3235 p_cpo = save_cpo; | 3235 p_cpo = save_cpo; |
3236 return matches; | 3236 return matches; |
3237 } | 3237 } |
3238 | 3238 |
3239 /* | 3239 /* |
3240 * types for expressions. | |
3241 */ | |
3242 typedef enum | |
3243 { | |
3244 TYPE_UNKNOWN = 0 | |
3245 , TYPE_EQUAL /* == */ | |
3246 , TYPE_NEQUAL /* != */ | |
3247 , TYPE_GREATER /* > */ | |
3248 , TYPE_GEQUAL /* >= */ | |
3249 , TYPE_SMALLER /* < */ | |
3250 , TYPE_SEQUAL /* <= */ | |
3251 , TYPE_MATCH /* =~ */ | |
3252 , TYPE_NOMATCH /* !~ */ | |
3253 } exptype_T; | |
3254 | |
3255 /* | |
3256 * The "evaluate" argument: When FALSE, the argument is only parsed but not | 3240 * The "evaluate" argument: When FALSE, the argument is only parsed but not |
3257 * executed. The function may return OK, but the rettv will be of type | 3241 * executed. The function may return OK, but the rettv will be of type |
3258 * VAR_UNKNOWN. The function still returns FAIL for a syntax error. | 3242 * VAR_UNKNOWN. The function still returns FAIL for a syntax error. |
3259 */ | 3243 */ |
3260 | 3244 |
3529 char_u *p; | 3513 char_u *p; |
3530 int i; | 3514 int i; |
3531 exptype_T type = TYPE_UNKNOWN; | 3515 exptype_T type = TYPE_UNKNOWN; |
3532 int type_is = FALSE; /* TRUE for "is" and "isnot" */ | 3516 int type_is = FALSE; /* TRUE for "is" and "isnot" */ |
3533 int len = 2; | 3517 int len = 2; |
3534 varnumber_T n1, n2; | |
3535 char_u *s1, *s2; | |
3536 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; | |
3537 int ic; | 3518 int ic; |
3538 | 3519 |
3539 /* | 3520 /* |
3540 * Get the first variable. | 3521 * Get the first variable. |
3541 */ | 3522 */ |
3613 if (eval5(arg, &var2, evaluate) == FAIL) | 3594 if (eval5(arg, &var2, evaluate) == FAIL) |
3614 { | 3595 { |
3615 clear_tv(rettv); | 3596 clear_tv(rettv); |
3616 return FAIL; | 3597 return FAIL; |
3617 } | 3598 } |
3618 | 3599 return typval_compare(rettv, &var2, type, type_is, ic, evaluate); |
3619 if (evaluate) | |
3620 { | |
3621 if (type_is && rettv->v_type != var2.v_type) | |
3622 { | |
3623 /* For "is" a different type always means FALSE, for "notis" | |
3624 * it means TRUE. */ | |
3625 n1 = (type == TYPE_NEQUAL); | |
3626 } | |
3627 else if (rettv->v_type == VAR_LIST || var2.v_type == VAR_LIST) | |
3628 { | |
3629 if (type_is) | |
3630 { | |
3631 n1 = (rettv->v_type == var2.v_type | |
3632 && rettv->vval.v_list == var2.vval.v_list); | |
3633 if (type == TYPE_NEQUAL) | |
3634 n1 = !n1; | |
3635 } | |
3636 else if (rettv->v_type != var2.v_type | |
3637 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) | |
3638 { | |
3639 if (rettv->v_type != var2.v_type) | |
3640 EMSG(_("E691: Can only compare List with List")); | |
3641 else | |
3642 EMSG(_("E692: Invalid operation for List")); | |
3643 clear_tv(rettv); | |
3644 clear_tv(&var2); | |
3645 return FAIL; | |
3646 } | |
3647 else | |
3648 { | |
3649 /* Compare two Lists for being equal or unequal. */ | |
3650 n1 = list_equal(rettv->vval.v_list, var2.vval.v_list, | |
3651 ic, FALSE); | |
3652 if (type == TYPE_NEQUAL) | |
3653 n1 = !n1; | |
3654 } | |
3655 } | |
3656 | |
3657 else if (rettv->v_type == VAR_DICT || var2.v_type == VAR_DICT) | |
3658 { | |
3659 if (type_is) | |
3660 { | |
3661 n1 = (rettv->v_type == var2.v_type | |
3662 && rettv->vval.v_dict == var2.vval.v_dict); | |
3663 if (type == TYPE_NEQUAL) | |
3664 n1 = !n1; | |
3665 } | |
3666 else if (rettv->v_type != var2.v_type | |
3667 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) | |
3668 { | |
3669 if (rettv->v_type != var2.v_type) | |
3670 EMSG(_("E735: Can only compare Dictionary with Dictionary")); | |
3671 else | |
3672 EMSG(_("E736: Invalid operation for Dictionary")); | |
3673 clear_tv(rettv); | |
3674 clear_tv(&var2); | |
3675 return FAIL; | |
3676 } | |
3677 else | |
3678 { | |
3679 /* Compare two Dictionaries for being equal or unequal. */ | |
3680 n1 = dict_equal(rettv->vval.v_dict, var2.vval.v_dict, | |
3681 ic, FALSE); | |
3682 if (type == TYPE_NEQUAL) | |
3683 n1 = !n1; | |
3684 } | |
3685 } | |
3686 | |
3687 else if (rettv->v_type == VAR_FUNC || var2.v_type == VAR_FUNC | |
3688 || rettv->v_type == VAR_PARTIAL || var2.v_type == VAR_PARTIAL) | |
3689 { | |
3690 if (type != TYPE_EQUAL && type != TYPE_NEQUAL) | |
3691 { | |
3692 EMSG(_("E694: Invalid operation for Funcrefs")); | |
3693 clear_tv(rettv); | |
3694 clear_tv(&var2); | |
3695 return FAIL; | |
3696 } | |
3697 if ((rettv->v_type == VAR_PARTIAL | |
3698 && rettv->vval.v_partial == NULL) | |
3699 || (var2.v_type == VAR_PARTIAL | |
3700 && var2.vval.v_partial == NULL)) | |
3701 /* when a partial is NULL assume not equal */ | |
3702 n1 = FALSE; | |
3703 else if (type_is) | |
3704 { | |
3705 if (rettv->v_type == VAR_FUNC && var2.v_type == VAR_FUNC) | |
3706 /* strings are considered the same if their value is | |
3707 * the same */ | |
3708 n1 = tv_equal(rettv, &var2, ic, FALSE); | |
3709 else if (rettv->v_type == VAR_PARTIAL | |
3710 && var2.v_type == VAR_PARTIAL) | |
3711 n1 = (rettv->vval.v_partial == var2.vval.v_partial); | |
3712 else | |
3713 n1 = FALSE; | |
3714 } | |
3715 else | |
3716 n1 = tv_equal(rettv, &var2, ic, FALSE); | |
3717 if (type == TYPE_NEQUAL) | |
3718 n1 = !n1; | |
3719 } | |
3720 | |
3721 #ifdef FEAT_FLOAT | |
3722 /* | |
3723 * If one of the two variables is a float, compare as a float. | |
3724 * When using "=~" or "!~", always compare as string. | |
3725 */ | |
3726 else if ((rettv->v_type == VAR_FLOAT || var2.v_type == VAR_FLOAT) | |
3727 && type != TYPE_MATCH && type != TYPE_NOMATCH) | |
3728 { | |
3729 float_T f1, f2; | |
3730 | |
3731 if (rettv->v_type == VAR_FLOAT) | |
3732 f1 = rettv->vval.v_float; | |
3733 else | |
3734 f1 = get_tv_number(rettv); | |
3735 if (var2.v_type == VAR_FLOAT) | |
3736 f2 = var2.vval.v_float; | |
3737 else | |
3738 f2 = get_tv_number(&var2); | |
3739 n1 = FALSE; | |
3740 switch (type) | |
3741 { | |
3742 case TYPE_EQUAL: n1 = (f1 == f2); break; | |
3743 case TYPE_NEQUAL: n1 = (f1 != f2); break; | |
3744 case TYPE_GREATER: n1 = (f1 > f2); break; | |
3745 case TYPE_GEQUAL: n1 = (f1 >= f2); break; | |
3746 case TYPE_SMALLER: n1 = (f1 < f2); break; | |
3747 case TYPE_SEQUAL: n1 = (f1 <= f2); break; | |
3748 case TYPE_UNKNOWN: | |
3749 case TYPE_MATCH: | |
3750 case TYPE_NOMATCH: break; /* avoid gcc warning */ | |
3751 } | |
3752 } | |
3753 #endif | |
3754 | |
3755 /* | |
3756 * If one of the two variables is a number, compare as a number. | |
3757 * When using "=~" or "!~", always compare as string. | |
3758 */ | |
3759 else if ((rettv->v_type == VAR_NUMBER || var2.v_type == VAR_NUMBER) | |
3760 && type != TYPE_MATCH && type != TYPE_NOMATCH) | |
3761 { | |
3762 n1 = get_tv_number(rettv); | |
3763 n2 = get_tv_number(&var2); | |
3764 switch (type) | |
3765 { | |
3766 case TYPE_EQUAL: n1 = (n1 == n2); break; | |
3767 case TYPE_NEQUAL: n1 = (n1 != n2); break; | |
3768 case TYPE_GREATER: n1 = (n1 > n2); break; | |
3769 case TYPE_GEQUAL: n1 = (n1 >= n2); break; | |
3770 case TYPE_SMALLER: n1 = (n1 < n2); break; | |
3771 case TYPE_SEQUAL: n1 = (n1 <= n2); break; | |
3772 case TYPE_UNKNOWN: | |
3773 case TYPE_MATCH: | |
3774 case TYPE_NOMATCH: break; /* avoid gcc warning */ | |
3775 } | |
3776 } | |
3777 else | |
3778 { | |
3779 s1 = get_tv_string_buf(rettv, buf1); | |
3780 s2 = get_tv_string_buf(&var2, buf2); | |
3781 if (type != TYPE_MATCH && type != TYPE_NOMATCH) | |
3782 i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2); | |
3783 else | |
3784 i = 0; | |
3785 n1 = FALSE; | |
3786 switch (type) | |
3787 { | |
3788 case TYPE_EQUAL: n1 = (i == 0); break; | |
3789 case TYPE_NEQUAL: n1 = (i != 0); break; | |
3790 case TYPE_GREATER: n1 = (i > 0); break; | |
3791 case TYPE_GEQUAL: n1 = (i >= 0); break; | |
3792 case TYPE_SMALLER: n1 = (i < 0); break; | |
3793 case TYPE_SEQUAL: n1 = (i <= 0); break; | |
3794 | |
3795 case TYPE_MATCH: | |
3796 case TYPE_NOMATCH: | |
3797 n1 = pattern_match(s2, s1, ic); | |
3798 if (type == TYPE_NOMATCH) | |
3799 n1 = !n1; | |
3800 break; | |
3801 | |
3802 case TYPE_UNKNOWN: break; /* avoid gcc warning */ | |
3803 } | |
3804 } | |
3805 clear_tv(rettv); | |
3806 clear_tv(&var2); | |
3807 rettv->v_type = VAR_NUMBER; | |
3808 rettv->vval.v_number = n1; | |
3809 } | |
3810 } | 3600 } |
3811 | 3601 |
3812 return OK; | 3602 return OK; |
3813 } | 3603 } |
3814 | 3604 |
6838 } | 6628 } |
6839 #endif | 6629 #endif |
6840 | 6630 |
6841 /* | 6631 /* |
6842 * Get the value of internal variable "name". | 6632 * Get the value of internal variable "name". |
6843 * Return OK or FAIL. | 6633 * Return OK or FAIL. If OK is returned "rettv" must be cleared. |
6844 */ | 6634 */ |
6845 int | 6635 int |
6846 get_var_tv( | 6636 get_var_tv( |
6847 char_u *name, | 6637 char_u *name, |
6848 int len, /* length of "name" */ | 6638 int len, /* length of "name" */ |
8417 * Find window specified by "vp" in tabpage "tp". | 8207 * Find window specified by "vp" in tabpage "tp". |
8418 */ | 8208 */ |
8419 win_T * | 8209 win_T * |
8420 find_win_by_nr( | 8210 find_win_by_nr( |
8421 typval_T *vp, | 8211 typval_T *vp, |
8422 tabpage_T *tp UNUSED) /* NULL for current tab page */ | 8212 tabpage_T *tp) /* NULL for current tab page */ |
8423 { | 8213 { |
8424 win_T *wp; | 8214 win_T *wp; |
8425 int nr; | 8215 int nr; |
8426 | 8216 |
8427 nr = (int)get_tv_number_chk(vp, NULL); | 8217 nr = (int)get_tv_number_chk(vp, NULL); |
9276 ga_concat_esc(gap, tv2string(got_tv, &tofree, numbuf, 0)); | 9066 ga_concat_esc(gap, tv2string(got_tv, &tofree, numbuf, 0)); |
9277 vim_free(tofree); | 9067 vim_free(tofree); |
9278 } | 9068 } |
9279 } | 9069 } |
9280 | 9070 |
9071 | |
9072 int | |
9073 typval_compare( | |
9074 typval_T *typ1, /* first operand */ | |
9075 typval_T *typ2, /* second operand */ | |
9076 exptype_T type, /* operator */ | |
9077 int type_is, /* TRUE for "is" and "isnot" */ | |
9078 int ic, /* ignore case */ | |
9079 int evaluate) | |
9080 { | |
9081 int i; | |
9082 varnumber_T n1, n2; | |
9083 char_u *s1, *s2; | |
9084 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; | |
9085 | |
9086 if (evaluate) | |
9087 { | |
9088 if (type_is && typ1->v_type != typ2->v_type) | |
9089 { | |
9090 /* For "is" a different type always means FALSE, for "notis" | |
9091 * it means TRUE. */ | |
9092 n1 = (type == TYPE_NEQUAL); | |
9093 } | |
9094 else if (typ1->v_type == VAR_LIST || typ2->v_type == VAR_LIST) | |
9095 { | |
9096 if (type_is) | |
9097 { | |
9098 n1 = (typ1->v_type == typ2->v_type | |
9099 && typ1->vval.v_list == typ2->vval.v_list); | |
9100 if (type == TYPE_NEQUAL) | |
9101 n1 = !n1; | |
9102 } | |
9103 else if (typ1->v_type != typ2->v_type | |
9104 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) | |
9105 { | |
9106 if (typ1->v_type != typ2->v_type) | |
9107 EMSG(_("E691: Can only compare List with List")); | |
9108 else | |
9109 EMSG(_("E692: Invalid operation for List")); | |
9110 clear_tv(typ1); | |
9111 clear_tv(typ2); | |
9112 return FAIL; | |
9113 } | |
9114 else | |
9115 { | |
9116 /* Compare two Lists for being equal or unequal. */ | |
9117 n1 = list_equal(typ1->vval.v_list, typ2->vval.v_list, | |
9118 ic, FALSE); | |
9119 if (type == TYPE_NEQUAL) | |
9120 n1 = !n1; | |
9121 } | |
9122 } | |
9123 | |
9124 else if (typ1->v_type == VAR_DICT || typ2->v_type == VAR_DICT) | |
9125 { | |
9126 if (type_is) | |
9127 { | |
9128 n1 = (typ1->v_type == typ2->v_type | |
9129 && typ1->vval.v_dict == typ2->vval.v_dict); | |
9130 if (type == TYPE_NEQUAL) | |
9131 n1 = !n1; | |
9132 } | |
9133 else if (typ1->v_type != typ2->v_type | |
9134 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) | |
9135 { | |
9136 if (typ1->v_type != typ2->v_type) | |
9137 EMSG(_("E735: Can only compare Dictionary with Dictionary")); | |
9138 else | |
9139 EMSG(_("E736: Invalid operation for Dictionary")); | |
9140 clear_tv(typ1); | |
9141 clear_tv(typ2); | |
9142 return FAIL; | |
9143 } | |
9144 else | |
9145 { | |
9146 /* Compare two Dictionaries for being equal or unequal. */ | |
9147 n1 = dict_equal(typ1->vval.v_dict, typ2->vval.v_dict, | |
9148 ic, FALSE); | |
9149 if (type == TYPE_NEQUAL) | |
9150 n1 = !n1; | |
9151 } | |
9152 } | |
9153 | |
9154 else if (typ1->v_type == VAR_FUNC || typ2->v_type == VAR_FUNC | |
9155 || typ1->v_type == VAR_PARTIAL || typ2->v_type == VAR_PARTIAL) | |
9156 { | |
9157 if (type != TYPE_EQUAL && type != TYPE_NEQUAL) | |
9158 { | |
9159 EMSG(_("E694: Invalid operation for Funcrefs")); | |
9160 clear_tv(typ1); | |
9161 clear_tv(typ2); | |
9162 return FAIL; | |
9163 } | |
9164 if ((typ1->v_type == VAR_PARTIAL | |
9165 && typ1->vval.v_partial == NULL) | |
9166 || (typ2->v_type == VAR_PARTIAL | |
9167 && typ2->vval.v_partial == NULL)) | |
9168 /* when a partial is NULL assume not equal */ | |
9169 n1 = FALSE; | |
9170 else if (type_is) | |
9171 { | |
9172 if (typ1->v_type == VAR_FUNC && typ2->v_type == VAR_FUNC) | |
9173 /* strings are considered the same if their value is | |
9174 * the same */ | |
9175 n1 = tv_equal(typ1, typ2, ic, FALSE); | |
9176 else if (typ1->v_type == VAR_PARTIAL | |
9177 && typ2->v_type == VAR_PARTIAL) | |
9178 n1 = (typ1->vval.v_partial == typ2->vval.v_partial); | |
9179 else | |
9180 n1 = FALSE; | |
9181 } | |
9182 else | |
9183 n1 = tv_equal(typ1, typ2, ic, FALSE); | |
9184 if (type == TYPE_NEQUAL) | |
9185 n1 = !n1; | |
9186 } | |
9187 | |
9188 #ifdef FEAT_FLOAT | |
9189 /* | |
9190 * If one of the two variables is a float, compare as a float. | |
9191 * When using "=~" or "!~", always compare as string. | |
9192 */ | |
9193 else if ((typ1->v_type == VAR_FLOAT || typ2->v_type == VAR_FLOAT) | |
9194 && type != TYPE_MATCH && type != TYPE_NOMATCH) | |
9195 { | |
9196 float_T f1, f2; | |
9197 | |
9198 if (typ1->v_type == VAR_FLOAT) | |
9199 f1 = typ1->vval.v_float; | |
9200 else | |
9201 f1 = get_tv_number(typ1); | |
9202 if (typ2->v_type == VAR_FLOAT) | |
9203 f2 = typ2->vval.v_float; | |
9204 else | |
9205 f2 = get_tv_number(typ2); | |
9206 n1 = FALSE; | |
9207 switch (type) | |
9208 { | |
9209 case TYPE_EQUAL: n1 = (f1 == f2); break; | |
9210 case TYPE_NEQUAL: n1 = (f1 != f2); break; | |
9211 case TYPE_GREATER: n1 = (f1 > f2); break; | |
9212 case TYPE_GEQUAL: n1 = (f1 >= f2); break; | |
9213 case TYPE_SMALLER: n1 = (f1 < f2); break; | |
9214 case TYPE_SEQUAL: n1 = (f1 <= f2); break; | |
9215 case TYPE_UNKNOWN: | |
9216 case TYPE_MATCH: | |
9217 case TYPE_NOMATCH: break; /* avoid gcc warning */ | |
9218 } | |
9219 } | |
9220 #endif | |
9221 | |
9222 /* | |
9223 * If one of the two variables is a number, compare as a number. | |
9224 * When using "=~" or "!~", always compare as string. | |
9225 */ | |
9226 else if ((typ1->v_type == VAR_NUMBER || typ2->v_type == VAR_NUMBER) | |
9227 && type != TYPE_MATCH && type != TYPE_NOMATCH) | |
9228 { | |
9229 n1 = get_tv_number(typ1); | |
9230 n2 = get_tv_number(typ2); | |
9231 switch (type) | |
9232 { | |
9233 case TYPE_EQUAL: n1 = (n1 == n2); break; | |
9234 case TYPE_NEQUAL: n1 = (n1 != n2); break; | |
9235 case TYPE_GREATER: n1 = (n1 > n2); break; | |
9236 case TYPE_GEQUAL: n1 = (n1 >= n2); break; | |
9237 case TYPE_SMALLER: n1 = (n1 < n2); break; | |
9238 case TYPE_SEQUAL: n1 = (n1 <= n2); break; | |
9239 case TYPE_UNKNOWN: | |
9240 case TYPE_MATCH: | |
9241 case TYPE_NOMATCH: break; /* avoid gcc warning */ | |
9242 } | |
9243 } | |
9244 else | |
9245 { | |
9246 s1 = get_tv_string_buf(typ1, buf1); | |
9247 s2 = get_tv_string_buf(typ2, buf2); | |
9248 if (type != TYPE_MATCH && type != TYPE_NOMATCH) | |
9249 i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2); | |
9250 else | |
9251 i = 0; | |
9252 n1 = FALSE; | |
9253 switch (type) | |
9254 { | |
9255 case TYPE_EQUAL: n1 = (i == 0); break; | |
9256 case TYPE_NEQUAL: n1 = (i != 0); break; | |
9257 case TYPE_GREATER: n1 = (i > 0); break; | |
9258 case TYPE_GEQUAL: n1 = (i >= 0); break; | |
9259 case TYPE_SMALLER: n1 = (i < 0); break; | |
9260 case TYPE_SEQUAL: n1 = (i <= 0); break; | |
9261 | |
9262 case TYPE_MATCH: | |
9263 case TYPE_NOMATCH: | |
9264 n1 = pattern_match(s2, s1, ic); | |
9265 if (type == TYPE_NOMATCH) | |
9266 n1 = !n1; | |
9267 break; | |
9268 | |
9269 case TYPE_UNKNOWN: break; /* avoid gcc warning */ | |
9270 } | |
9271 } | |
9272 clear_tv(typ1); | |
9273 clear_tv(typ2); | |
9274 typ1->v_type = VAR_NUMBER; | |
9275 typ1->vval.v_number = n1; | |
9276 } | |
9277 return OK; | |
9278 } | |
9279 | |
9280 int | |
9281 typval_copy(typ1, typ2) | |
9282 typval_T *typ1; | |
9283 typval_T *typ2; | |
9284 { | |
9285 if (typ2 == NULL) | |
9286 rettv_list_alloc(typ2); | |
9287 | |
9288 if (typ1 != NULL && typ2 != NULL) | |
9289 return item_copy(typ1, typ2, TRUE, 0); | |
9290 | |
9291 return FAIL; | |
9292 } | |
9293 | |
9294 char_u * | |
9295 typval_tostring(arg) | |
9296 typval_T *arg; | |
9297 { | |
9298 char_u *tofree; | |
9299 char_u numbuf[NUMBUFLEN]; | |
9300 char_u *ret = NULL; | |
9301 | |
9302 if (arg == NULL) | |
9303 return vim_strsave((char_u *)"(does not exist)"); | |
9304 ret = tv2string(arg, &tofree, numbuf, 0); | |
9305 /* Make a copy if we have a value but it's not in allocated memory. */ | |
9306 if (ret != NULL && tofree == NULL) | |
9307 ret = vim_strsave(ret); | |
9308 return ret; | |
9309 } | |
9310 | |
9311 int | |
9312 var_exists(char_u *var) | |
9313 { | |
9314 char_u *name; | |
9315 char_u *tofree; | |
9316 typval_T tv; | |
9317 int len = 0; | |
9318 int n = FALSE; | |
9319 | |
9320 /* get_name_len() takes care of expanding curly braces */ | |
9321 name = var; | |
9322 len = get_name_len(&var, &tofree, TRUE, FALSE); | |
9323 if (len > 0) | |
9324 { | |
9325 if (tofree != NULL) | |
9326 name = tofree; | |
9327 n = (get_var_tv(name, len, &tv, NULL, FALSE, TRUE) == OK); | |
9328 if (n) | |
9329 { | |
9330 /* handle d.key, l[idx], f(expr) */ | |
9331 n = (handle_subscript(&var, &tv, TRUE, FALSE) == OK); | |
9332 if (n) | |
9333 clear_tv(&tv); | |
9334 } | |
9335 } | |
9336 if (*var != NUL) | |
9337 n = FALSE; | |
9338 | |
9339 vim_free(tofree); | |
9340 return n; | |
9341 } | |
9281 | 9342 |
9282 #endif /* FEAT_EVAL */ | 9343 #endif /* FEAT_EVAL */ |
9283 | 9344 |
9284 | 9345 |
9285 #if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) || defined(PROTO) | 9346 #if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) || defined(PROTO) |