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)); }