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,