Mercurial > vim
comparison src/eval.c @ 13274:f4b4162264b1 v8.0.1511
patch 8.0.1511: some code for the debugger watch expression is clumsy
commit https://github.com/vim/vim/commit/3198870137df64214317151726648af8e56f1729
Author: Bram Moolenaar <Bram@vim.org>
Date: Tue Feb 13 12:57:42 2018 +0100
patch 8.0.1511: some code for the debugger watch expression is clumsy
Problem: Some code for the debugger watch expression is clumsy.
Solution: Clean up the code.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Tue, 13 Feb 2018 13:00:06 +0100 |
parents | abaebba89fd4 |
children | a88c5e12b860 |
comparison
equal
deleted
inserted
replaced
13273:0d9d7e54e506 | 13274:f4b4162264b1 |
---|---|
3594 if (eval5(arg, &var2, evaluate) == FAIL) | 3594 if (eval5(arg, &var2, evaluate) == FAIL) |
3595 { | 3595 { |
3596 clear_tv(rettv); | 3596 clear_tv(rettv); |
3597 return FAIL; | 3597 return FAIL; |
3598 } | 3598 } |
3599 return typval_compare(rettv, &var2, type, type_is, ic, evaluate); | 3599 if (evaluate) |
3600 { | |
3601 int ret = typval_compare(rettv, &var2, type, type_is, ic); | |
3602 | |
3603 clear_tv(&var2); | |
3604 return ret; | |
3605 } | |
3600 } | 3606 } |
3601 | 3607 |
3602 return OK; | 3608 return OK; |
3603 } | 3609 } |
3604 | 3610 |
9089 ga_concat_esc(gap, tv2string(got_tv, &tofree, numbuf, 0)); | 9095 ga_concat_esc(gap, tv2string(got_tv, &tofree, numbuf, 0)); |
9090 vim_free(tofree); | 9096 vim_free(tofree); |
9091 } | 9097 } |
9092 } | 9098 } |
9093 | 9099 |
9094 | 9100 /* |
9101 * Compare "typ1" and "typ2". Put the result in "typ1". | |
9102 */ | |
9095 int | 9103 int |
9096 typval_compare( | 9104 typval_compare( |
9097 typval_T *typ1, /* first operand */ | 9105 typval_T *typ1, /* first operand */ |
9098 typval_T *typ2, /* second operand */ | 9106 typval_T *typ2, /* second operand */ |
9099 exptype_T type, /* operator */ | 9107 exptype_T type, /* operator */ |
9100 int type_is, /* TRUE for "is" and "isnot" */ | 9108 int type_is, /* TRUE for "is" and "isnot" */ |
9101 int ic, /* ignore case */ | 9109 int ic) /* ignore case */ |
9102 int evaluate) | |
9103 { | 9110 { |
9104 int i; | 9111 int i; |
9105 varnumber_T n1, n2; | 9112 varnumber_T n1, n2; |
9106 char_u *s1, *s2; | 9113 char_u *s1, *s2; |
9107 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; | 9114 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; |
9108 | 9115 |
9109 if (evaluate) | 9116 if (type_is && typ1->v_type != typ2->v_type) |
9110 { | 9117 { |
9111 if (type_is && typ1->v_type != typ2->v_type) | 9118 /* For "is" a different type always means FALSE, for "notis" |
9112 { | 9119 * it means TRUE. */ |
9113 /* For "is" a different type always means FALSE, for "notis" | 9120 n1 = (type == TYPE_NEQUAL); |
9114 * it means TRUE. */ | 9121 } |
9115 n1 = (type == TYPE_NEQUAL); | 9122 else if (typ1->v_type == VAR_LIST || typ2->v_type == VAR_LIST) |
9116 } | 9123 { |
9117 else if (typ1->v_type == VAR_LIST || typ2->v_type == VAR_LIST) | 9124 if (type_is) |
9118 { | 9125 { |
9119 if (type_is) | 9126 n1 = (typ1->v_type == typ2->v_type |
9120 { | 9127 && typ1->vval.v_list == typ2->vval.v_list); |
9121 n1 = (typ1->v_type == typ2->v_type | |
9122 && typ1->vval.v_list == typ2->vval.v_list); | |
9123 if (type == TYPE_NEQUAL) | |
9124 n1 = !n1; | |
9125 } | |
9126 else if (typ1->v_type != typ2->v_type | |
9127 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) | |
9128 { | |
9129 if (typ1->v_type != typ2->v_type) | |
9130 EMSG(_("E691: Can only compare List with List")); | |
9131 else | |
9132 EMSG(_("E692: Invalid operation for List")); | |
9133 clear_tv(typ1); | |
9134 clear_tv(typ2); | |
9135 return FAIL; | |
9136 } | |
9137 else | |
9138 { | |
9139 /* Compare two Lists for being equal or unequal. */ | |
9140 n1 = list_equal(typ1->vval.v_list, typ2->vval.v_list, | |
9141 ic, FALSE); | |
9142 if (type == TYPE_NEQUAL) | |
9143 n1 = !n1; | |
9144 } | |
9145 } | |
9146 | |
9147 else if (typ1->v_type == VAR_DICT || typ2->v_type == VAR_DICT) | |
9148 { | |
9149 if (type_is) | |
9150 { | |
9151 n1 = (typ1->v_type == typ2->v_type | |
9152 && typ1->vval.v_dict == typ2->vval.v_dict); | |
9153 if (type == TYPE_NEQUAL) | |
9154 n1 = !n1; | |
9155 } | |
9156 else if (typ1->v_type != typ2->v_type | |
9157 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) | |
9158 { | |
9159 if (typ1->v_type != typ2->v_type) | |
9160 EMSG(_("E735: Can only compare Dictionary with Dictionary")); | |
9161 else | |
9162 EMSG(_("E736: Invalid operation for Dictionary")); | |
9163 clear_tv(typ1); | |
9164 clear_tv(typ2); | |
9165 return FAIL; | |
9166 } | |
9167 else | |
9168 { | |
9169 /* Compare two Dictionaries for being equal or unequal. */ | |
9170 n1 = dict_equal(typ1->vval.v_dict, typ2->vval.v_dict, | |
9171 ic, FALSE); | |
9172 if (type == TYPE_NEQUAL) | |
9173 n1 = !n1; | |
9174 } | |
9175 } | |
9176 | |
9177 else if (typ1->v_type == VAR_FUNC || typ2->v_type == VAR_FUNC | |
9178 || typ1->v_type == VAR_PARTIAL || typ2->v_type == VAR_PARTIAL) | |
9179 { | |
9180 if (type != TYPE_EQUAL && type != TYPE_NEQUAL) | |
9181 { | |
9182 EMSG(_("E694: Invalid operation for Funcrefs")); | |
9183 clear_tv(typ1); | |
9184 clear_tv(typ2); | |
9185 return FAIL; | |
9186 } | |
9187 if ((typ1->v_type == VAR_PARTIAL | |
9188 && typ1->vval.v_partial == NULL) | |
9189 || (typ2->v_type == VAR_PARTIAL | |
9190 && typ2->vval.v_partial == NULL)) | |
9191 /* when a partial is NULL assume not equal */ | |
9192 n1 = FALSE; | |
9193 else if (type_is) | |
9194 { | |
9195 if (typ1->v_type == VAR_FUNC && typ2->v_type == VAR_FUNC) | |
9196 /* strings are considered the same if their value is | |
9197 * the same */ | |
9198 n1 = tv_equal(typ1, typ2, ic, FALSE); | |
9199 else if (typ1->v_type == VAR_PARTIAL | |
9200 && typ2->v_type == VAR_PARTIAL) | |
9201 n1 = (typ1->vval.v_partial == typ2->vval.v_partial); | |
9202 else | |
9203 n1 = FALSE; | |
9204 } | |
9205 else | |
9206 n1 = tv_equal(typ1, typ2, ic, FALSE); | |
9207 if (type == TYPE_NEQUAL) | 9128 if (type == TYPE_NEQUAL) |
9208 n1 = !n1; | 9129 n1 = !n1; |
9209 } | 9130 } |
9131 else if (typ1->v_type != typ2->v_type | |
9132 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) | |
9133 { | |
9134 if (typ1->v_type != typ2->v_type) | |
9135 EMSG(_("E691: Can only compare List with List")); | |
9136 else | |
9137 EMSG(_("E692: Invalid operation for List")); | |
9138 clear_tv(typ1); | |
9139 return FAIL; | |
9140 } | |
9141 else | |
9142 { | |
9143 /* Compare two Lists for being equal or unequal. */ | |
9144 n1 = list_equal(typ1->vval.v_list, typ2->vval.v_list, | |
9145 ic, FALSE); | |
9146 if (type == TYPE_NEQUAL) | |
9147 n1 = !n1; | |
9148 } | |
9149 } | |
9150 | |
9151 else if (typ1->v_type == VAR_DICT || typ2->v_type == VAR_DICT) | |
9152 { | |
9153 if (type_is) | |
9154 { | |
9155 n1 = (typ1->v_type == typ2->v_type | |
9156 && typ1->vval.v_dict == typ2->vval.v_dict); | |
9157 if (type == TYPE_NEQUAL) | |
9158 n1 = !n1; | |
9159 } | |
9160 else if (typ1->v_type != typ2->v_type | |
9161 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) | |
9162 { | |
9163 if (typ1->v_type != typ2->v_type) | |
9164 EMSG(_("E735: Can only compare Dictionary with Dictionary")); | |
9165 else | |
9166 EMSG(_("E736: Invalid operation for Dictionary")); | |
9167 clear_tv(typ1); | |
9168 return FAIL; | |
9169 } | |
9170 else | |
9171 { | |
9172 /* Compare two Dictionaries for being equal or unequal. */ | |
9173 n1 = dict_equal(typ1->vval.v_dict, typ2->vval.v_dict, | |
9174 ic, FALSE); | |
9175 if (type == TYPE_NEQUAL) | |
9176 n1 = !n1; | |
9177 } | |
9178 } | |
9179 | |
9180 else if (typ1->v_type == VAR_FUNC || typ2->v_type == VAR_FUNC | |
9181 || typ1->v_type == VAR_PARTIAL || typ2->v_type == VAR_PARTIAL) | |
9182 { | |
9183 if (type != TYPE_EQUAL && type != TYPE_NEQUAL) | |
9184 { | |
9185 EMSG(_("E694: Invalid operation for Funcrefs")); | |
9186 clear_tv(typ1); | |
9187 return FAIL; | |
9188 } | |
9189 if ((typ1->v_type == VAR_PARTIAL | |
9190 && typ1->vval.v_partial == NULL) | |
9191 || (typ2->v_type == VAR_PARTIAL | |
9192 && typ2->vval.v_partial == NULL)) | |
9193 /* when a partial is NULL assume not equal */ | |
9194 n1 = FALSE; | |
9195 else if (type_is) | |
9196 { | |
9197 if (typ1->v_type == VAR_FUNC && typ2->v_type == VAR_FUNC) | |
9198 /* strings are considered the same if their value is | |
9199 * the same */ | |
9200 n1 = tv_equal(typ1, typ2, ic, FALSE); | |
9201 else if (typ1->v_type == VAR_PARTIAL | |
9202 && typ2->v_type == VAR_PARTIAL) | |
9203 n1 = (typ1->vval.v_partial == typ2->vval.v_partial); | |
9204 else | |
9205 n1 = FALSE; | |
9206 } | |
9207 else | |
9208 n1 = tv_equal(typ1, typ2, ic, FALSE); | |
9209 if (type == TYPE_NEQUAL) | |
9210 n1 = !n1; | |
9211 } | |
9210 | 9212 |
9211 #ifdef FEAT_FLOAT | 9213 #ifdef FEAT_FLOAT |
9212 /* | 9214 /* |
9213 * If one of the two variables is a float, compare as a float. | 9215 * If one of the two variables is a float, compare as a float. |
9214 * When using "=~" or "!~", always compare as string. | 9216 * When using "=~" or "!~", always compare as string. |
9215 */ | 9217 */ |
9216 else if ((typ1->v_type == VAR_FLOAT || typ2->v_type == VAR_FLOAT) | 9218 else if ((typ1->v_type == VAR_FLOAT || typ2->v_type == VAR_FLOAT) |
9217 && type != TYPE_MATCH && type != TYPE_NOMATCH) | 9219 && type != TYPE_MATCH && type != TYPE_NOMATCH) |
9218 { | 9220 { |
9219 float_T f1, f2; | 9221 float_T f1, f2; |
9220 | 9222 |
9221 if (typ1->v_type == VAR_FLOAT) | 9223 if (typ1->v_type == VAR_FLOAT) |
9222 f1 = typ1->vval.v_float; | 9224 f1 = typ1->vval.v_float; |
9223 else | 9225 else |
9224 f1 = get_tv_number(typ1); | 9226 f1 = get_tv_number(typ1); |
9225 if (typ2->v_type == VAR_FLOAT) | 9227 if (typ2->v_type == VAR_FLOAT) |
9226 f2 = typ2->vval.v_float; | 9228 f2 = typ2->vval.v_float; |
9227 else | 9229 else |
9228 f2 = get_tv_number(typ2); | 9230 f2 = get_tv_number(typ2); |
9229 n1 = FALSE; | 9231 n1 = FALSE; |
9230 switch (type) | 9232 switch (type) |
9231 { | 9233 { |
9232 case TYPE_EQUAL: n1 = (f1 == f2); break; | 9234 case TYPE_EQUAL: n1 = (f1 == f2); break; |
9233 case TYPE_NEQUAL: n1 = (f1 != f2); break; | 9235 case TYPE_NEQUAL: n1 = (f1 != f2); break; |
9234 case TYPE_GREATER: n1 = (f1 > f2); break; | 9236 case TYPE_GREATER: n1 = (f1 > f2); break; |
9235 case TYPE_GEQUAL: n1 = (f1 >= f2); break; | 9237 case TYPE_GEQUAL: n1 = (f1 >= f2); break; |
9236 case TYPE_SMALLER: n1 = (f1 < f2); break; | 9238 case TYPE_SMALLER: n1 = (f1 < f2); break; |
9237 case TYPE_SEQUAL: n1 = (f1 <= f2); break; | 9239 case TYPE_SEQUAL: n1 = (f1 <= f2); break; |
9238 case TYPE_UNKNOWN: | 9240 case TYPE_UNKNOWN: |
9239 case TYPE_MATCH: | 9241 case TYPE_MATCH: |
9240 case TYPE_NOMATCH: break; /* avoid gcc warning */ | 9242 case TYPE_NOMATCH: break; /* avoid gcc warning */ |
9241 } | 9243 } |
9242 } | 9244 } |
9243 #endif | 9245 #endif |
9244 | 9246 |
9245 /* | 9247 /* |
9246 * If one of the two variables is a number, compare as a number. | 9248 * If one of the two variables is a number, compare as a number. |
9247 * When using "=~" or "!~", always compare as string. | 9249 * When using "=~" or "!~", always compare as string. |
9248 */ | 9250 */ |
9249 else if ((typ1->v_type == VAR_NUMBER || typ2->v_type == VAR_NUMBER) | 9251 else if ((typ1->v_type == VAR_NUMBER || typ2->v_type == VAR_NUMBER) |
9250 && type != TYPE_MATCH && type != TYPE_NOMATCH) | 9252 && type != TYPE_MATCH && type != TYPE_NOMATCH) |
9251 { | 9253 { |
9252 n1 = get_tv_number(typ1); | 9254 n1 = get_tv_number(typ1); |
9253 n2 = get_tv_number(typ2); | 9255 n2 = get_tv_number(typ2); |
9254 switch (type) | 9256 switch (type) |
9255 { | 9257 { |
9256 case TYPE_EQUAL: n1 = (n1 == n2); break; | 9258 case TYPE_EQUAL: n1 = (n1 == n2); break; |
9257 case TYPE_NEQUAL: n1 = (n1 != n2); break; | 9259 case TYPE_NEQUAL: n1 = (n1 != n2); break; |
9258 case TYPE_GREATER: n1 = (n1 > n2); break; | 9260 case TYPE_GREATER: n1 = (n1 > n2); break; |
9259 case TYPE_GEQUAL: n1 = (n1 >= n2); break; | 9261 case TYPE_GEQUAL: n1 = (n1 >= n2); break; |
9260 case TYPE_SMALLER: n1 = (n1 < n2); break; | 9262 case TYPE_SMALLER: n1 = (n1 < n2); break; |
9261 case TYPE_SEQUAL: n1 = (n1 <= n2); break; | 9263 case TYPE_SEQUAL: n1 = (n1 <= n2); break; |
9262 case TYPE_UNKNOWN: | 9264 case TYPE_UNKNOWN: |
9263 case TYPE_MATCH: | 9265 case TYPE_MATCH: |
9264 case TYPE_NOMATCH: break; /* avoid gcc warning */ | 9266 case TYPE_NOMATCH: break; /* avoid gcc warning */ |
9265 } | 9267 } |
9266 } | 9268 } |
9269 else | |
9270 { | |
9271 s1 = get_tv_string_buf(typ1, buf1); | |
9272 s2 = get_tv_string_buf(typ2, buf2); | |
9273 if (type != TYPE_MATCH && type != TYPE_NOMATCH) | |
9274 i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2); | |
9267 else | 9275 else |
9268 { | 9276 i = 0; |
9269 s1 = get_tv_string_buf(typ1, buf1); | 9277 n1 = FALSE; |
9270 s2 = get_tv_string_buf(typ2, buf2); | 9278 switch (type) |
9271 if (type != TYPE_MATCH && type != TYPE_NOMATCH) | 9279 { |
9272 i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2); | 9280 case TYPE_EQUAL: n1 = (i == 0); break; |
9273 else | 9281 case TYPE_NEQUAL: n1 = (i != 0); break; |
9274 i = 0; | 9282 case TYPE_GREATER: n1 = (i > 0); break; |
9275 n1 = FALSE; | 9283 case TYPE_GEQUAL: n1 = (i >= 0); break; |
9276 switch (type) | 9284 case TYPE_SMALLER: n1 = (i < 0); break; |
9277 { | 9285 case TYPE_SEQUAL: n1 = (i <= 0); break; |
9278 case TYPE_EQUAL: n1 = (i == 0); break; | 9286 |
9279 case TYPE_NEQUAL: n1 = (i != 0); break; | 9287 case TYPE_MATCH: |
9280 case TYPE_GREATER: n1 = (i > 0); break; | 9288 case TYPE_NOMATCH: |
9281 case TYPE_GEQUAL: n1 = (i >= 0); break; | 9289 n1 = pattern_match(s2, s1, ic); |
9282 case TYPE_SMALLER: n1 = (i < 0); break; | 9290 if (type == TYPE_NOMATCH) |
9283 case TYPE_SEQUAL: n1 = (i <= 0); break; | 9291 n1 = !n1; |
9284 | 9292 break; |
9285 case TYPE_MATCH: | 9293 |
9286 case TYPE_NOMATCH: | 9294 case TYPE_UNKNOWN: break; /* avoid gcc warning */ |
9287 n1 = pattern_match(s2, s1, ic); | 9295 } |
9288 if (type == TYPE_NOMATCH) | 9296 } |
9289 n1 = !n1; | 9297 clear_tv(typ1); |
9290 break; | 9298 typ1->v_type = VAR_NUMBER; |
9291 | 9299 typ1->vval.v_number = n1; |
9292 case TYPE_UNKNOWN: break; /* avoid gcc warning */ | 9300 |
9293 } | |
9294 } | |
9295 clear_tv(typ1); | |
9296 clear_tv(typ2); | |
9297 typ1->v_type = VAR_NUMBER; | |
9298 typ1->vval.v_number = n1; | |
9299 } | |
9300 return OK; | 9301 return OK; |
9301 } | |
9302 | |
9303 int | |
9304 typval_copy(typ1, typ2) | |
9305 typval_T *typ1; | |
9306 typval_T *typ2; | |
9307 { | |
9308 if (typ2 == NULL) | |
9309 rettv_list_alloc(typ2); | |
9310 | |
9311 if (typ1 != NULL && typ2 != NULL) | |
9312 return item_copy(typ1, typ2, TRUE, 0); | |
9313 | |
9314 return FAIL; | |
9315 } | 9302 } |
9316 | 9303 |
9317 char_u * | 9304 char_u * |
9318 typval_tostring(arg) | 9305 typval_tostring(arg) |
9319 typval_T *arg; | 9306 typval_T *arg; |