diff options
-rw-r--r-- | srfi/ChangeLog | 5 | ||||
-rw-r--r-- | srfi/srfi-14.c | 14 |
2 files changed, 16 insertions, 3 deletions
diff --git a/srfi/ChangeLog b/srfi/ChangeLog index e4a7440a8..3a3937b29 100644 --- a/srfi/ChangeLog +++ b/srfi/ChangeLog @@ -2,6 +2,11 @@ * srfi-14.c (scm_char_set_intersection, scm_char_set_xor): remove the compulsory cs1 arguments: all args are optional in final spec. + (scm_char_set_xor): bug fix: characters should only be included if + they occur in exactly one argument, but were included if they + occured an odd number of times >= 3, e.g, in (char-set-xor a a a) + where a is (char-set #\a). fix it with a "mask" array. + * srfi-14.h: declarations updated. 2001-07-18 Martin Grabmueller <mgrabmue@cs.tu-berlin.de> diff --git a/srfi/srfi-14.c b/srfi/srfi-14.c index 798f75bb5..8d628252a 100644 --- a/srfi/srfi-14.c +++ b/srfi/srfi-14.c @@ -1155,16 +1155,18 @@ SCM_DEFINE (scm_char_set_xor, "char-set-xor", 0, 0, 1, { long * p; int argnum = 2; + long mask[LONGS_PER_CHARSET]; + int k; + memset (mask, 0, sizeof mask); res = scm_char_set_copy (SCM_CAR (rest)); p = (long *) SCM_SMOB_DATA (res); rest = SCM_CDR (rest); while (SCM_CONSP (rest)) { - int k; SCM cs = SCM_CAR (rest); - long *cs_data; + long *cs_data; SCM_VALIDATE_SMOB (argnum, cs, charset); argnum++; @@ -1172,8 +1174,14 @@ SCM_DEFINE (scm_char_set_xor, "char-set-xor", 0, 0, 1, rest = SCM_CDR (rest); for (k = 0; k < LONGS_PER_CHARSET; k++) - p[k] ^= cs_data[k]; + { + mask[k] |= p[k] & cs_data[k]; + p[k] ^= cs_data[k]; + } } + /* avoid including characters that occur an odd number of times >= 3. */ + for (k = 0; k < LONGS_PER_CHARSET; k++) + p[k] &= ~mask[k]; } return res; } |