[Zodb-checkins] CVS: Zope3/lib/python/Persistence/BTrees - SetOpTemplate.c:1.1.2.5

Tim Peters tim.one@comcast.net
Tue, 4 Jun 2002 18:41:25 -0400


Update of /cvs-repository/Zope3/lib/python/Persistence/BTrees
In directory cvs.zope.org:/tmp/cvs-serv22639

Modified Files:
      Tag: Zope-3x-branch
	SetOpTemplate.c 
Log Message:
Plug leaks due to references tucked away in SetIteration structs.  Lucky
break:  some of these that existed on the trunk were already fixed on the
branch.
Document initSetIteration().


=== Zope3/lib/python/Persistence/BTrees/SetOpTemplate.c 1.1.2.4 => 1.1.2.5 ===
 #endif
 
+/* initSetIteration
+ *
+ * Start the set iteration protocol.  See the comments at struct SetIteration.
+ *
+ * Arguments
+ *      i       The address of a SetIteration control struct.
+ *      s       The address of the set, bucket, BTree, ..., to be iterated.
+ *      w       If w < 0, ignore values when iterating.
+ *      merge   Is set to 1 if s has values (as well as keys) and w >= 0.
+ *              The value on input is ignored.
+ *
+ * Return
+ *      0 on success; -1 and an exception set if error.
+ *      merge is set to 1 if s has values and w >= 0, else merge is left
+ *          alone.
+ *      i.set gets a new reference to s, or to some other object used to
+ *          iterate over s.  The caller must Py_XDECREF i.set when it's
+ *          done with i, and regardless of whether the call to
+ *          initSetIteration succeeds or fails (a failing call may or not
+ *          set i.set to NULL).
+ *      i.position is set to 0.
+ *      i.hasValue is set to true if s has values, and to false otherwise.
+ *          Note that this is done independent of w's value.
+ *      i.next is set to an appropriate iteration function.
+ *      i.key and i.value are left alone.
+ */
 static int
 initSetIteration(SetIteration *i, PyObject *s, int w, int *merge)
 {
@@ -178,8 +204,8 @@
   SetIteration i1 = {0,0,0}, i2 = {0,0,0};
   int cmp, merge=0;
 
-  if (initSetIteration(&i1, s1, w1, &merge) < 0) return NULL;
-  if (initSetIteration(&i2, s2, w2, &merge) < 0) return NULL;
+  if (initSetIteration(&i1, s1, w1, &merge) < 0) goto err;
+  if (initSetIteration(&i2, s2, w2, &merge) < 0) goto err;
 
   if (merge)
     {
@@ -218,8 +244,8 @@
         goto err;
     }
 
-  if (i1.next(&i1) < 0) return NULL;
-  if (i2.next(&i2) < 0) return NULL;
+  if (i1.next(&i1) < 0) goto err;
+  if (i2.next(&i2) < 0) goto err;
 
   while (i1.position >= 0 && i2.position >= 0)
     {