summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark H Weaver <mhw@netris.org>2013-02-28 18:43:09 -0500
committerMark H Weaver <mhw@netris.org>2013-02-28 18:43:09 -0500
commit8dd01861a9a0331b912a1ae6310e64eb6b47c29c (patch)
tree9b53d4dc72fd6ad26c3380b52729fecfceb7de77
parentb8d8f8b9292a4755d2c63bc7a955d75d96eb05e0 (diff)
downloadguile-8dd01861a9a0331b912a1ae6310e64eb6b47c29c.tar.gz
Fix later-bindings-win logic in with-fluids.
Based on a patch by David Kastrup <dak@gnu.org>. Fixes <http://bugs.gnu.org/13843>. * libguile/fluids.c (scm_i_make_with_fluids): Reverse direction of inner loop that checks for duplicates, to properly handle more than two bindings to the same fluid.
-rw-r--r--libguile/fluids.c6
-rw-r--r--test-suite/tests/fluids.test10
2 files changed, 9 insertions, 7 deletions
diff --git a/libguile/fluids.c b/libguile/fluids.c
index 277246e35..327d12f4c 100644
--- a/libguile/fluids.c
+++ b/libguile/fluids.c
@@ -319,10 +319,10 @@ scm_i_make_with_fluids (size_t n, SCM *fluids, SCM *vals)
/* Ensure that there are no duplicates in the fluids set -- an N^2 operation,
but N will usually be small, so perhaps that's OK. */
{
- size_t i, j = n;
+ size_t i, j;
- while (j--)
- for (i = 0; i < j; i++)
+ for (j = n; j--;)
+ for (i = j; i--;)
if (scm_is_eq (fluids[i], fluids[j]))
{
vals[i] = vals[j]; /* later bindings win */
diff --git a/test-suite/tests/fluids.test b/test-suite/tests/fluids.test
index 5552fd936..9ad9e81f8 100644
--- a/test-suite/tests/fluids.test
+++ b/test-suite/tests/fluids.test
@@ -85,15 +85,17 @@
(pass-if "last value wins"
(compile '(with-fluids ((a 1)
- (a 2))
- (eqv? (fluid-ref a) 2))
+ (a 2)
+ (a 3))
+ (eqv? (fluid-ref a) 3))
#:env (current-module)))
(pass-if "remove the duplicate, not the last binding"
(compile '(with-fluids ((a 1)
(a 2)
- (b 3))
- (eqv? (fluid-ref b) 3))
+ (a 3)
+ (b 4))
+ (eqv? (fluid-ref b) 4))
#:env (current-module)))
(pass-if "original value restored"