200 static PyObject *
201 set_operation(PyObject *s1, PyObject *s2,
202 int usevalues1, int usevalues2,
203
204 /* Comment # 42
205
206 The following ifdef works around a template/type problem
207
208 Weights are passed as integers. In particular, the weight passed by
209 difference is one. This works fine in the int value and float value
210 cases but makes no sense in the object value case. In the object
211 value case, we don't do merging, so we don't use the weights, so it
212 doesn't matter what they are.
213 */
214 #ifdef MERGE
215 VALUE_TYPE w1, VALUE_TYPE w2,
216 #else
217 int w1, int w2,
218 #endif
219 int c1, int c12, int c2)
220
221
222 {
223 Bucket *r=0;
224 SetIteration i1 = {0,0,0}, i2 = {0,0,0};
225 int cmp, merge;
226
227 if (initSetIteration(&i1, s1, usevalues1) < 0) goto err;
when considering range: 0 <= value <= 0x7fffffff
taking False path
228 if (initSetIteration(&i2, s2, usevalues2) < 0) goto err;
when considering range: 0 <= value <= 0x7fffffff
taking False path
229 merge = i1.usesValue | i2.usesValue;
230
231 if (merge)
when considering range: -0x80000000 <= value <= -1
taking True path
232 {
233 #ifndef MERGE
234 if (c12 && i1.usesValue && i2.usesValue) goto invalid_set_operation;
when considering range: -0x80000000 <= value <= -1
taking True path
when considering range: -0x80000000 <= value <= -1
taking True path
when considering value == (int)0 from src/BTrees/SetOpTemplate.c:234
taking False path
235 #endif
236 if (! i1.usesValue&& i2.usesValue)
when considering range: -0x80000000 <= value <= -1
taking False path
237 {
238 SetIteration t;
239 int i;
240
241 /* See comment # 42 above */
242 #ifdef MERGE
243 VALUE_TYPE v;
244 #else
245 int v;
246 #endif
247
248 t=i1; i1=i2; i2=t;
249 i=c1; c1=c2; c2=i;
250 v=w1; w1=w2; w2=v;
251 }
252 #ifdef MERGE_DEFAULT
253 i1.value=MERGE_DEFAULT;
254 i2.value=MERGE_DEFAULT;
255 #else
256 if (i1.usesValue)
when considering range: -0x80000000 <= value <= -1
taking True path
257 {
258 if (! i2.usesValue && c2) goto invalid_set_operation;
when considering range: -0x80000000 <= value <= -1
when considering range: -0x80000000 <= value <= -1
taking False path
259 }
260 else
261 {
262 if (c1 || c12) goto invalid_set_operation;
263 }
264 #endif
265
266 UNLESS(r=BUCKET(PyObject_CallObject(OBJECT(&BucketType), NULL)))
when PyObject_CallObject() succeeds
taking False path
267 goto err;
268 }
269 else
270 {
271 UNLESS(r=BUCKET(PyObject_CallObject(OBJECT(&SetType), NULL)))
272 goto err;
273 }
274
275 if (i1.next(&i1) < 0) goto err;
calling unknown int (*) (struct SetIteration_s *) from src/BTrees/SetOpTemplate.c:275
when considering range: 0 <= value <= 0x7fffffff
taking False path
276 if (i2.next(&i2) < 0) goto err;
calling unknown int (*) (struct SetIteration_s *) from src/BTrees/SetOpTemplate.c:276
when considering range: 0 <= value <= 0x7fffffff
taking False path
277
278 while (i1.position >= 0 && i2.position >= 0)
when considering range: -0x80000000 <= value <= -1
taking False path
279 {
280 TEST_KEY_SET_OR(cmp, i1.key, i2.key) goto err;
281 if(cmp < 0)
282 {
283 if(c1)
284 {
285 if(r->len >= r->size && Bucket_grow(r, -1, ! merge) < 0) goto err;
286 COPY_KEY(r->keys[r->len], i1.key);
287 INCREF_KEY(r->keys[r->len]);
288 if (merge)
289 {
290 COPY_VALUE(r->values[r->len], MERGE_WEIGHT(i1.value, w1));
291 INCREF_VALUE(r->values[r->len]);
292 }
293 r->len++;
294 }
295 if (i1.next(&i1) < 0) goto err;
296 }
297 else if(cmp==0)
298 {
299 if(c12)
300 {
301 if(r->len >= r->size && Bucket_grow(r, -1, ! merge) < 0) goto err;
302 COPY_KEY(r->keys[r->len], i1.key);
303 INCREF_KEY(r->keys[r->len]);
304 if (merge)
305 {
306 #ifdef MERGE
307 r->values[r->len] = MERGE(i1.value, w1, i2.value, w2);
308 #else
309 COPY_VALUE(r->values[r->len], i1.value);
310 INCREF_VALUE(r->values[r->len]);
311 #endif
312 }
313 r->len++;
314 }
315 if (i1.next(&i1) < 0) goto err;
316 if (i2.next(&i2) < 0) goto err;
317 }
318 else
319 {
320 if(c2)
321 {
322 if(r->len >= r->size && Bucket_grow(r, -1, ! merge) < 0) goto err;
323 COPY_KEY(r->keys[r->len], i2.key);
324 INCREF_KEY(r->keys[r->len]);
325 if (merge)
326 {
327 COPY_VALUE(r->values[r->len], MERGE_WEIGHT(i2.value, w2));
328 INCREF_VALUE(r->values[r->len]);
329 }
330 r->len++;
331 }
332 if (i2.next(&i2) < 0) goto err;
333 }
334 }
335 if(c1 && copyRemaining(r, &i1, merge, w1) < 0) goto err;
when considering range: -0x80000000 <= value <= -1
taking True path
when considering range: -0x80000000 <= value <= -1
taking True path
336 if(c2 && copyRemaining(r, &i2, merge, w2) < 0) goto err;
337
338
339 finiSetIteration(&i1);
340 finiSetIteration(&i2);
341
342 return OBJECT(r);
343
344 #ifndef MERGE_DEFAULT
345 invalid_set_operation:
346 PyErr_SetString(PyExc_TypeError, "invalid set operation");
347 #endif
348
349 err:
350 finiSetIteration(&i1);
351 finiSetIteration(&i2);
352 Py_XDECREF(r);
taking False path
when taking True path
353 return NULL;
354 }
returning (PyObject*)NULL without setting an exception
found 15 similar trace(s) to this