mirror of
git://git.sv.gnu.org/autoconf
synced 2025-04-12 15:20:26 +08:00
Both the recursive and the iterative versions of m4_set_add_all had a bug where they did not update the set size correctly if the set contained tombstones. I guess m4_set_remove isn’t used that often. (I found this bug by accident while investigating an unrelated thing.) The root cause of the bug was that in the tombstone case we had two different layers quarreling over who got the last word on the size of the set: m4_set_add, called for each value argument, was updating the set size for each actual addition, and then the outer expansion of m4_set_add_all was clobbering those updates with a calculation based on the number of times the loop evaluated to a ‘-’ character, which in the tombstone case was always zero. The fix is to not mess with the set size on each actual addition, relying on the outer calculation in all cases. Most of the volume of the patch is refactoring to eliminate all the duplicate copies of the “add this element only if it isn’t already there” logic which were confusing the issue. I also made m4_set_add_all not go into an infinite loop if invoked with fewer than two arguments. Possibly it should error out in this case instead of silently doing nothing, but I don’t think it matters very much. * lib/m4sugar/m4sugar.m4 (_m4_set_add, _m4_set_add_clean): New macros, factoring out common “add element to set” logic. (m4_set_add): Redefine using _m4_set_add. (_m4_set_add_all): Rename to _m4_set_add_all_clean; use _m4_set_add_clean. (_m4_set_add_check): Use _m4_set_add, not m4_set_add; emit a string of dashes as _m4_set_add_all_clean does. (m4_set_add_all): Update to match renamed _m4_set_add_all_clean. Do nothing if invoked with fewer than two arguments. * lib/m4sugar/foreach.m4: Define variants of _m4_set_add_all_clean and _m4_set_add_all_check, matching the behavior of the definitions in m4sugar.m4. Do not define m4_set_add_all here. * tests/m4sugar.at (m4_set): Add more tests of interaction among m4_set_add_all, m4_set_remove, and m4_set_size.