Mercurial > vim
comparison src/eval.c @ 9183:988c8ab557bf v7.4.1875
commit https://github.com/vim/vim/commit/8e759ba8651428995b338b66c615367259f79766
Author: Bram Moolenaar <Bram@vim.org>
Date: Thu Jun 2 17:46:20 2016 +0200
patch 7.4.1875
Problem: Comparing functions and partials doesn't work well.
Solution: Add tests. (Nikolai Pavlov) Compare the dict and arguments in the
partial. (closes https://github.com/vim/vim/issues/813)
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Thu, 02 Jun 2016 18:00:07 +0200 |
parents | 0ea97a753a2d |
children | 9495e43a800d |
comparison
equal
deleted
inserted
replaced
9182:d0a54c4069ab | 9183:988c8ab557bf |
---|---|
4625 EMSG(_("E694: Invalid operation for Funcrefs")); | 4625 EMSG(_("E694: Invalid operation for Funcrefs")); |
4626 clear_tv(rettv); | 4626 clear_tv(rettv); |
4627 clear_tv(&var2); | 4627 clear_tv(&var2); |
4628 return FAIL; | 4628 return FAIL; |
4629 } | 4629 } |
4630 n1 = tv_equal(rettv, &var2, FALSE, FALSE); | 4630 if ((rettv->v_type == VAR_PARTIAL |
4631 && rettv->vval.v_partial == NULL) | |
4632 || (var2.v_type == VAR_PARTIAL | |
4633 && var2.vval.v_partial == NULL)) | |
4634 /* when a partial is NULL assume not equal */ | |
4635 n1 = FALSE; | |
4636 else if (type_is) | |
4637 { | |
4638 if (rettv->v_type == VAR_FUNC && var2.v_type == VAR_FUNC) | |
4639 /* strings are considered the same if their value is | |
4640 * the same */ | |
4641 n1 = tv_equal(rettv, &var2, ic, FALSE); | |
4642 else if (rettv->v_type == VAR_PARTIAL | |
4643 && var2.v_type == VAR_PARTIAL) | |
4644 n1 = (rettv->vval.v_partial == var2.vval.v_partial); | |
4645 else | |
4646 n1 = FALSE; | |
4647 } | |
4648 else | |
4649 n1 = tv_equal(rettv, &var2, ic, FALSE); | |
4631 if (type == TYPE_NEQUAL) | 4650 if (type == TYPE_NEQUAL) |
4632 n1 = !n1; | 4651 n1 = !n1; |
4633 } | 4652 } |
4634 | 4653 |
4635 #ifdef FEAT_FLOAT | 4654 #ifdef FEAT_FLOAT |
6256 return TRUE; | 6275 return TRUE; |
6257 } | 6276 } |
6258 | 6277 |
6259 static int tv_equal_recurse_limit; | 6278 static int tv_equal_recurse_limit; |
6260 | 6279 |
6280 static int | |
6281 func_equal( | |
6282 typval_T *tv1, | |
6283 typval_T *tv2, | |
6284 int ic) /* ignore case */ | |
6285 { | |
6286 char_u *s1, *s2; | |
6287 dict_T *d1, *d2; | |
6288 int a1, a2; | |
6289 int i; | |
6290 | |
6291 /* empty and NULL function name considered the same */ | |
6292 s1 = tv1->v_type == VAR_FUNC ? tv1->vval.v_string | |
6293 : tv1->vval.v_partial->pt_name; | |
6294 if (s1 != NULL && *s1 == NUL) | |
6295 s1 = NULL; | |
6296 s2 = tv2->v_type == VAR_FUNC ? tv2->vval.v_string | |
6297 : tv2->vval.v_partial->pt_name; | |
6298 if (s2 != NULL && *s2 == NUL) | |
6299 s2 = NULL; | |
6300 if (s1 == NULL || s2 == NULL) | |
6301 { | |
6302 if (s1 != s2) | |
6303 return FALSE; | |
6304 } | |
6305 else if (STRCMP(s1, s2) != 0) | |
6306 return FALSE; | |
6307 | |
6308 /* empty dict and NULL dict is different */ | |
6309 d1 = tv1->v_type == VAR_FUNC ? NULL : tv1->vval.v_partial->pt_dict; | |
6310 d2 = tv2->v_type == VAR_FUNC ? NULL : tv2->vval.v_partial->pt_dict; | |
6311 if (d1 == NULL || d2 == NULL) | |
6312 { | |
6313 if (d1 != d2) | |
6314 return FALSE; | |
6315 } | |
6316 else if (!dict_equal(d1, d2, ic, TRUE)) | |
6317 return FALSE; | |
6318 | |
6319 /* empty list and no list considered the same */ | |
6320 a1 = tv1->v_type == VAR_FUNC ? 0 : tv1->vval.v_partial->pt_argc; | |
6321 a2 = tv2->v_type == VAR_FUNC ? 0 : tv2->vval.v_partial->pt_argc; | |
6322 if (a1 != a2) | |
6323 return FALSE; | |
6324 for (i = 0; i < a1; ++i) | |
6325 if (!tv_equal(tv1->vval.v_partial->pt_argv + i, | |
6326 tv2->vval.v_partial->pt_argv + i, ic, TRUE)) | |
6327 return FALSE; | |
6328 | |
6329 return TRUE; | |
6330 } | |
6331 | |
6261 /* | 6332 /* |
6262 * Return TRUE if "tv1" and "tv2" have the same value. | 6333 * Return TRUE if "tv1" and "tv2" have the same value. |
6263 * Compares the items just like "==" would compare them, but strings and | 6334 * Compares the items just like "==" would compare them, but strings and |
6264 * numbers are different. Floats and numbers are also different. | 6335 * numbers are different. Floats and numbers are also different. |
6265 */ | 6336 */ |
6272 { | 6343 { |
6273 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; | 6344 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; |
6274 char_u *s1, *s2; | 6345 char_u *s1, *s2; |
6275 static int recursive_cnt = 0; /* catch recursive loops */ | 6346 static int recursive_cnt = 0; /* catch recursive loops */ |
6276 int r; | 6347 int r; |
6277 | |
6278 /* For VAR_FUNC and VAR_PARTIAL only compare the function name. */ | |
6279 if ((tv1->v_type == VAR_FUNC | |
6280 || (tv1->v_type == VAR_PARTIAL && tv1->vval.v_partial != NULL)) | |
6281 && (tv2->v_type == VAR_FUNC | |
6282 || (tv2->v_type == VAR_PARTIAL && tv2->vval.v_partial != NULL))) | |
6283 { | |
6284 s1 = tv1->v_type == VAR_FUNC ? tv1->vval.v_string | |
6285 : tv1->vval.v_partial->pt_name; | |
6286 s2 = tv2->v_type == VAR_FUNC ? tv2->vval.v_string | |
6287 : tv2->vval.v_partial->pt_name; | |
6288 return (s1 != NULL && s2 != NULL && STRCMP(s1, s2) == 0); | |
6289 } | |
6290 | |
6291 if (tv1->v_type != tv2->v_type) | |
6292 return FALSE; | |
6293 | 6348 |
6294 /* Catch lists and dicts that have an endless loop by limiting | 6349 /* Catch lists and dicts that have an endless loop by limiting |
6295 * recursiveness to a limit. We guess they are equal then. | 6350 * recursiveness to a limit. We guess they are equal then. |
6296 * A fixed limit has the problem of still taking an awful long time. | 6351 * A fixed limit has the problem of still taking an awful long time. |
6297 * Reduce the limit every time running into it. That should work fine for | 6352 * Reduce the limit every time running into it. That should work fine for |
6302 if (recursive_cnt >= tv_equal_recurse_limit) | 6357 if (recursive_cnt >= tv_equal_recurse_limit) |
6303 { | 6358 { |
6304 --tv_equal_recurse_limit; | 6359 --tv_equal_recurse_limit; |
6305 return TRUE; | 6360 return TRUE; |
6306 } | 6361 } |
6362 | |
6363 /* For VAR_FUNC and VAR_PARTIAL only compare the function name. */ | |
6364 if ((tv1->v_type == VAR_FUNC | |
6365 || (tv1->v_type == VAR_PARTIAL && tv1->vval.v_partial != NULL)) | |
6366 && (tv2->v_type == VAR_FUNC | |
6367 || (tv2->v_type == VAR_PARTIAL && tv2->vval.v_partial != NULL))) | |
6368 { | |
6369 ++recursive_cnt; | |
6370 r = func_equal(tv1, tv2, ic); | |
6371 --recursive_cnt; | |
6372 return r; | |
6373 } | |
6374 | |
6375 if (tv1->v_type != tv2->v_type) | |
6376 return FALSE; | |
6307 | 6377 |
6308 switch (tv1->v_type) | 6378 switch (tv1->v_type) |
6309 { | 6379 { |
6310 case VAR_LIST: | 6380 case VAR_LIST: |
6311 ++recursive_cnt; | 6381 ++recursive_cnt; |