c1652a35737e2110ab747d6acd85f5709624655f
markd
  Sun Feb 4 19:50:49 2018 -0800
fixed stupid bug in unlinking child with multiple parents from one of thoses parents

diff --git src/lib/gff3.c src/lib/gff3.c
index 8d2f9e4..45f844c 100644
--- src/lib/gff3.c
+++ src/lib/gff3.c
@@ -187,30 +187,40 @@
     {
     if (sameString(attr->tag, tag))
         return attr;
     }
 return NULL;
 }
 
 static struct gff3AnnRef *gff3AnnRefAlloc(struct gff3Ann *g3a)
 /* construct an annotation reference, allocated in the memory pool*/
 {
 struct gff3AnnRef *ref = gff3FileAlloc(g3a->file, sizeof(struct gff3AnnRef));
 ref->ann = g3a;
 return ref;
 }
 
+struct gff3AnnRef *gff3RefFind(struct gff3AnnRef *refList, struct gff3Ann *ann)
+/* Return ref if ann is already on list, otherwise NULL. */
+{
+struct gff3AnnRef *ref;
+for (ref = refList; ref != NULL; ref = ref->next)
+    if (ref->ann == ann)
+        return ref;
+return NULL;
+}
+
 static void raiseInvalidEscape(struct gff3Ann *g3a, char *str)
 /* raise an error about an invalid escape in a string */
 {
 gff3AnnErr(g3a, "invalid GFF escape sequence in string: %s", str);
 }
 
 static char convertEscape(struct gff3Ann *g3a, char *esc, char *src)
 /* convert character at esc, which should start with a `%' and be a string
  * in the form `%09' */
 {
 if (!(isxdigit(esc[1]) && isxdigit(esc[2])))
     raiseInvalidEscape(g3a, src);
 char num[3], *end;
 strncpy(num, esc+1, 2);
 num[2] = '\0';
@@ -1112,37 +1122,40 @@
         diff = -1;
     else
         diff = strcmp(a->strand, b->strand);
     }
 if (diff == 0)
     diff = a->start - b->start;
 if (diff == 0)
     diff = a->end - b->end;
 return diff;
 }
 
 void gff3UnlinkChild(struct gff3Ann *g3a,
                      struct gff3Ann *child)
 /* unlink the child from it's parent (do not free) */
 {
-struct gff3AnnRef *childRef;
-for (childRef = g3a->children; childRef != NULL; childRef = childRef->next)
-    if (childRef->ann == child)
-        break;
+struct gff3AnnRef *childRef = gff3RefFind(g3a->children, child);
 if (childRef == NULL)
     errAbort("gff3UnlinkChild: not a child of specified parent");
 slRemoveEl(&g3a->children, childRef);
-child->parentIds = NULL;
-child->parents = NULL;
+
+// assume correct linked now that relationship is verfied
+struct gff3AnnRef *parentRef = gff3RefFind(child->parents, g3a);
+slRemoveEl(&child->parents, parentRef);
+
+struct slName *parentId = slNameFind(child->parentIds, g3a->id);
+slRemoveEl(&child->parentIds, parentId);
+// don't free, links are in localmem
 }
 
 void gff3LinkChild(struct gff3Ann *g3a,
                    struct gff3Ann *child)
 /* Add a child to new parent */
 {
 struct gff3AnnRef *childRef = gff3AnnRefAlloc(child);
 slSafeAddHead(&g3a->children, childRef);
 slSort(&g3a->children, gff3AnnRefLocCmp);
 slAddHead(&child->parentIds, gff3FileSlNameNew(g3a->file, g3a->id));
 slAddHead(&child->parents, gff3AnnRefAlloc(g3a));
 }