261c6956765a12f489c8f210e86d327f80173f5c galt Fri Aug 21 19:25:56 2020 -0700 Fixes bug found by Jonathan during code review that can have infinite loop. Code is now a little simpler and more reliable. refs#26088 diff --git src/hg/lib/liftOver.c src/hg/lib/liftOver.c index 6e65268..38f7a25 100644 --- src/hg/lib/liftOver.c +++ src/hg/lib/liftOver.c @@ -777,79 +777,74 @@ int *pThickStart, int *pThickEnd, double minBlocks, bool fudgeThick, struct liftRange **retGood, struct liftRange **retBad, char **retError) /* Remap range list through chain. Return error message on failure, * NULL on success. */ { struct cBlock *b = chain->blockList; struct liftRange *r = *pRangeList, *nextR, *goodList = NULL, *badList = NULL; int bDiff, rStart = 0; bool gotStart = FALSE; int rCount = slCount(r), goodCount = 0; int thickStart = *pThickStart, thickEnd = *pThickEnd; int fudgeThickStart = 0, fudgeThickEnd = 0; bool gotThickStart = FALSE, gotThickEnd = FALSE; bool gotFudgeThickStart = FALSE; bool needThick = (thickStart != thickEnd); -boolean done = FALSE; static char bErr[512]; char *err = NULL; *pRangeList = NULL; if (r == NULL) { *retGood = *retBad = NULL; *retError = NULL; return; } if (b == NULL) { *retGood = NULL; *retBad = r; *retError = "Empty block list in intersecting chain"; return; } nextR = r->next; for (;;) { /* Skip over chain blocks that end before range starts. */ - while (b->tEnd <= r->start) + if (b->tEnd <= r->start) { b = b->next; if (b == NULL) { - done = TRUE; break; } + continue; } - if (done) - break; /* Put any range blocks that end before block starts on badList */ - while (r->end <= b->tStart) + if (r->end <= b->tStart) { slAddHead(&badList, r); r = nextR; if (r == NULL) { - done = TRUE; break; } nextR = r->next; gotStart = FALSE; + continue; } - if (done) - break; /* Map start and end of 'thick area' in a slightly picky fashion. */ if (needThick) { if (b->tStart <= thickStart && thickStart < b->tEnd) { *pThickStart = thickStart + b->qStart - b->tStart; gotThickStart = TRUE; fudgeThickStart = *pThickStart; gotFudgeThickStart = TRUE; } if (b->tStart <= thickEnd && thickEnd <= b->tEnd) { *pThickEnd = thickEnd + b->qStart - b->tStart; gotThickEnd = TRUE; @@ -877,52 +872,45 @@ bDiff = b->qStart - b->tStart; if (gotStart) { r->start = rStart; r->end += bDiff; slAddHead(&goodList, r); ++goodCount; } else { slAddHead(&badList, r); } r = nextR; if (r == NULL) { - done = TRUE; break; } nextR = r->next; gotStart = FALSE; + continue; } - if (done) - break; - // May have multiple small chain segments spanned by one exon, - // so advance one exon if we are in the middle of a run, have start but no end yet. - if (b->tEnd < r->end && gotStart) + if (b->tEnd < r->end) { b = b->next; if (b == NULL) { - done = TRUE; break; } } - if (done) - break; } slReverse(&goodList); slReverse(&badList); if (needThick) { if (goodList != NULL && !gotFudgeThickStart) fudgeThickStart = fudgeThickEnd = goodList->start; if (!gotThickStart) { if (fudgeThick) { if (goodList != NULL) *pThickStart = fudgeThickStart; } else