Mercurial > hg > xemacs-beta
comparison src/fns.c @ 5283:be436ac36ba4
Don't share a counter when checking for circularity, list_merge().
src/ChangeLog addition:
2010-10-12 Aidan Kehoe <kehoea@parhasard.net>
* fns.c (list_merge):
Circularity checking here needs to be done independently for each
list, they can't share a loop counter. Thank you for the bug
report, Robert Pluim!
tests/ChangeLog addition:
2010-10-12 Aidan Kehoe <kehoea@parhasard.net>
* automated/lisp-tests.el:
Make sure circularity checking with #'merge is sane.
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Tue, 12 Oct 2010 18:14:12 +0100 |
parents | d804e621add0 |
children | 99de5fd48e87 |
comparison
equal
deleted
inserted
replaced
5282:dcc34e28cd84 | 5283:be436ac36ba4 |
---|---|
2155 Lisp_Object tail; | 2155 Lisp_Object tail; |
2156 Lisp_Object tem; | 2156 Lisp_Object tem; |
2157 Lisp_Object l1, l2; | 2157 Lisp_Object l1, l2; |
2158 Lisp_Object tortoises[2]; | 2158 Lisp_Object tortoises[2]; |
2159 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; | 2159 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; |
2160 int looped = 0; | 2160 int l1_count = 0, l2_count = 0; |
2161 | 2161 |
2162 l1 = org_l1; | 2162 l1 = org_l1; |
2163 l2 = org_l2; | 2163 l2 = org_l2; |
2164 tail = Qnil; | 2164 tail = Qnil; |
2165 value = Qnil; | 2165 value = Qnil; |
2201 if (NILP (c_predicate (Fcar (l2), Fcar (l1), predicate, key_func))) | 2201 if (NILP (c_predicate (Fcar (l2), Fcar (l1), predicate, key_func))) |
2202 { | 2202 { |
2203 tem = l1; | 2203 tem = l1; |
2204 l1 = Fcdr (l1); | 2204 l1 = Fcdr (l1); |
2205 org_l1 = l1; | 2205 org_l1 = l1; |
2206 | |
2207 if (l1_count++ > CIRCULAR_LIST_SUSPICION_LENGTH) | |
2208 { | |
2209 if (l1_count & 1) | |
2210 { | |
2211 if (!CONSP (tortoises[0])) | |
2212 { | |
2213 mapping_interaction_error (Qmerge, tortoises[0]); | |
2214 } | |
2215 | |
2216 tortoises[0] = XCDR (tortoises[0]); | |
2217 } | |
2218 | |
2219 if (EQ (org_l1, tortoises[0])) | |
2220 { | |
2221 signal_circular_list_error (org_l1); | |
2222 } | |
2223 } | |
2206 } | 2224 } |
2207 else | 2225 else |
2208 { | 2226 { |
2209 tem = l2; | 2227 tem = l2; |
2210 l2 = Fcdr (l2); | 2228 l2 = Fcdr (l2); |
2211 org_l2 = l2; | 2229 org_l2 = l2; |
2230 | |
2231 if (l2_count++ > CIRCULAR_LIST_SUSPICION_LENGTH) | |
2232 { | |
2233 if (l2_count & 1) | |
2234 { | |
2235 if (!CONSP (tortoises[1])) | |
2236 { | |
2237 mapping_interaction_error (Qmerge, tortoises[1]); | |
2238 } | |
2239 | |
2240 tortoises[1] = XCDR (tortoises[1]); | |
2241 } | |
2242 | |
2243 if (EQ (org_l2, tortoises[1])) | |
2244 { | |
2245 signal_circular_list_error (org_l2); | |
2246 } | |
2247 } | |
2212 } | 2248 } |
2249 | |
2213 if (NILP (tail)) | 2250 if (NILP (tail)) |
2214 value = tem; | 2251 value = tem; |
2215 else | 2252 else |
2216 Fsetcdr (tail, tem); | 2253 Fsetcdr (tail, tem); |
2254 | |
2217 tail = tem; | 2255 tail = tem; |
2218 | |
2219 if (++looped > CIRCULAR_LIST_SUSPICION_LENGTH) | |
2220 { | |
2221 if (looped & 1) | |
2222 { | |
2223 tortoises[0] = XCDR (tortoises[0]); | |
2224 tortoises[1] = XCDR (tortoises[1]); | |
2225 } | |
2226 | |
2227 if (EQ (org_l1, tortoises[0])) | |
2228 { | |
2229 signal_circular_list_error (org_l1); | |
2230 } | |
2231 | |
2232 if (EQ (org_l2, tortoises[1])) | |
2233 { | |
2234 signal_circular_list_error (org_l2); | |
2235 } | |
2236 } | |
2237 } | 2256 } |
2238 } | 2257 } |
2239 | 2258 |
2240 static void | 2259 static void |
2241 array_merge (Lisp_Object *dest, Elemcount dest_len, | 2260 array_merge (Lisp_Object *dest, Elemcount dest_len, |