Mercurial > vim
comparison src/userfunc.c @ 21319:fb3dcd8ed14d v8.2.1210
patch 8.2.1210: using ht_used when looping through a hashtab is less reliable
Commit: https://github.com/vim/vim/commit/1f22cc5cdb2da867d6bbf54dd371f279c38a2f56
Author: Bram Moolenaar <Bram@vim.org>
Date: Tue Jul 14 21:08:49 2020 +0200
patch 8.2.1210: using ht_used when looping through a hashtab is less reliable
Problem: Using ht_used when looping through a hashtab is less reliable.
Solution: Use ht_changed in a few more places.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Tue, 14 Jul 2020 21:15:04 +0200 |
parents | e641f678bdb9 |
children | aa7675a4a0cd |
comparison
equal
deleted
inserted
replaced
21318:b1121f5c029a | 21319:fb3dcd8ed14d |
---|---|
1710 { | 1710 { |
1711 hashitem_T *hi; | 1711 hashitem_T *hi; |
1712 ufunc_T *fp; | 1712 ufunc_T *fp; |
1713 long_u skipped = 0; | 1713 long_u skipped = 0; |
1714 long_u todo = 1; | 1714 long_u todo = 1; |
1715 long_u used; | 1715 int changed; |
1716 | 1716 |
1717 // Clean up the current_funccal chain and the funccal stack. | 1717 // Clean up the current_funccal chain and the funccal stack. |
1718 while (current_funccal != NULL) | 1718 while (current_funccal != NULL) |
1719 { | 1719 { |
1720 clear_tv(current_funccal->rettv); | 1720 clear_tv(current_funccal->rettv); |
1741 // supposed to be freed when no longer referenced. | 1741 // supposed to be freed when no longer referenced. |
1742 if (func_name_refcount(fp->uf_name)) | 1742 if (func_name_refcount(fp->uf_name)) |
1743 ++skipped; | 1743 ++skipped; |
1744 else | 1744 else |
1745 { | 1745 { |
1746 used = func_hashtab.ht_used; | 1746 changed = func_hashtab.ht_changed; |
1747 func_clear(fp, TRUE); | 1747 func_clear(fp, TRUE); |
1748 if (used != func_hashtab.ht_used) | 1748 if (changed != func_hashtab.ht_changed) |
1749 { | 1749 { |
1750 skipped = 0; | 1750 skipped = 0; |
1751 break; | 1751 break; |
1752 } | 1752 } |
1753 } | 1753 } |
2482 * Otherwise functions matching "regmatch". | 2482 * Otherwise functions matching "regmatch". |
2483 */ | 2483 */ |
2484 static void | 2484 static void |
2485 list_functions(regmatch_T *regmatch) | 2485 list_functions(regmatch_T *regmatch) |
2486 { | 2486 { |
2487 long_u used = func_hashtab.ht_used; | 2487 int changed = func_hashtab.ht_changed; |
2488 long_u todo = used; | 2488 long_u todo = func_hashtab.ht_used; |
2489 hashitem_T *ht_array = func_hashtab.ht_array; | |
2490 hashitem_T *hi; | 2489 hashitem_T *hi; |
2491 | 2490 |
2492 for (hi = ht_array; todo > 0 && !got_int; ++hi) | 2491 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) |
2493 { | 2492 { |
2494 if (!HASHITEM_EMPTY(hi)) | 2493 if (!HASHITEM_EMPTY(hi)) |
2495 { | 2494 { |
2496 ufunc_T *fp = HI2UF(hi); | 2495 ufunc_T *fp = HI2UF(hi); |
2497 | 2496 |
2502 && !func_name_refcount(fp->uf_name) | 2501 && !func_name_refcount(fp->uf_name) |
2503 : !isdigit(*fp->uf_name) | 2502 : !isdigit(*fp->uf_name) |
2504 && vim_regexec(regmatch, fp->uf_name, 0))) | 2503 && vim_regexec(regmatch, fp->uf_name, 0))) |
2505 { | 2504 { |
2506 list_func_head(fp, FALSE); | 2505 list_func_head(fp, FALSE); |
2507 if (used != func_hashtab.ht_used | 2506 if (changed != func_hashtab.ht_changed) |
2508 || ht_array != func_hashtab.ht_array) | |
2509 { | 2507 { |
2510 emsg(_("E454: function list was modified")); | 2508 emsg(_("E454: function list was modified")); |
2511 return; | 2509 return; |
2512 } | 2510 } |
2513 } | 2511 } |
3562 */ | 3560 */ |
3563 char_u * | 3561 char_u * |
3564 get_user_func_name(expand_T *xp, int idx) | 3562 get_user_func_name(expand_T *xp, int idx) |
3565 { | 3563 { |
3566 static long_u done; | 3564 static long_u done; |
3565 static int changed; | |
3567 static hashitem_T *hi; | 3566 static hashitem_T *hi; |
3568 ufunc_T *fp; | 3567 ufunc_T *fp; |
3569 | 3568 |
3570 if (idx == 0) | 3569 if (idx == 0) |
3571 { | 3570 { |
3572 done = 0; | 3571 done = 0; |
3573 hi = func_hashtab.ht_array; | 3572 hi = func_hashtab.ht_array; |
3574 } | 3573 changed = func_hashtab.ht_changed; |
3575 if (done < func_hashtab.ht_used) | 3574 } |
3575 if (changed == func_hashtab.ht_changed && done < func_hashtab.ht_used) | |
3576 { | 3576 { |
3577 if (done++ > 0) | 3577 if (done++ > 0) |
3578 ++hi; | 3578 ++hi; |
3579 while (HASHITEM_EMPTY(hi)) | 3579 while (HASHITEM_EMPTY(hi)) |
3580 ++hi; | 3580 ++hi; |