8c908f948b09826c6cb4452ee5b282aca41be85e galt Tue Dec 8 21:52:59 2015 -0800 Multi-region (exonMostly). This work allows people to look at virtual chromosomes from a list of regions and then navigate and perform all of the usual functions on it. diff --git src/hg/lib/hdb.c src/hg/lib/hdb.c index 66af474..f466337 100644 --- src/hg/lib/hdb.c +++ src/hg/lib/hdb.c @@ -4015,39 +4015,39 @@ { struct trackDb *cTdb = NULL; if (sTdb != NULL) { char *subTrackSetting = cloneString(trackDbLocalSetting(sTdb, "parent")); if (subTrackSetting != NULL) { char *compositeName = firstWordInLine(subTrackSetting); cTdb = hTrackDbForTrack(db, compositeName); freez(&subTrackSetting); } } return cTdb; } -boolean hgParseChromRange(char *db, char *spec, char **retChromName, - int *retWinStart, int *retWinEnd) +boolean hgParseChromRangeLong(char *db, char *spec, char **retChromName, + long *retWinStart, long *retWinEnd) /* Parse something of form chrom:start-end into pieces. * if db != NULL then check with chromInfo for names */ { boolean haveDb = (db != NULL); char *chrom, *start, *end; char buf[256]; -int iStart, iEnd; +long iStart, iEnd; safecpy(buf, sizeof(buf), spec); stripChar(buf, ','); chrom = buf; start = strchr(chrom, ':'); if (start == NULL) { /* If just chromosome name cover all of it. */ if (!haveDb || ((chrom = hgOfficialChromName(db, chrom)) == NULL)) return FALSE; else { iStart = 0; iEnd = hChromSize(db, chrom); @@ -4058,42 +4058,59 @@ *start++ = 0; end = strchr(start, '-'); if (end == NULL) return FALSE; else *end++ = 0; chrom = trimSpaces(chrom); start = trimSpaces(start); end = trimSpaces(end); if (!isdigit(start[0])) return FALSE; if (!isdigit(end[0])) return FALSE; if (haveDb && ((chrom = hgOfficialChromName(db, chrom)) == NULL)) return FALSE; - iStart = atoi(start)-1; - iEnd = atoi(end); + iStart = atol(start)-1; + iEnd = atol(end); } if (retChromName != NULL) *retChromName = (haveDb)? chrom : cloneString(chrom); if (retWinStart != NULL) *retWinStart = iStart; if (retWinEnd != NULL) *retWinEnd = iEnd; return TRUE; } +boolean hgParseChromRange(char *db, char *spec, char **retChromName, + int *retWinStart, int *retWinEnd) +/* Parse something of form chrom:start-end into pieces. + * if db != NULL then check with chromInfo for names */ +{ +long winStart, winEnd; +boolean result = hgParseChromRangeLong(db, spec, retChromName, &winStart, &winEnd); +if (result) + { + if (retWinStart != NULL) + *retWinStart = winStart; + if (retWinEnd != NULL) + *retWinEnd = winEnd; + } +return result; +} + boolean hgIsChromRange(char *db, char *spec) /* Returns TRUE if spec is chrom:N-M for some human * chromosome chrom and some N and M. */ { return hgParseChromRange(db, spec, NULL, NULL, NULL); } struct trackDb *hMaybeTrackInfo(struct sqlConnection *conn, char *trackName) /* Load trackDb object for a track. Actually the whole trackDb gets loaded * and just the one track returned. This is mostly just so parent and subtracks * fields can be correct. Don't die if conn has no trackDb table. Return NULL * if trackName is not found. */ { struct slName *tdb, *tdbs = hTrackDbList(); for (tdb = tdbs; tdb != NULL; tdb = tdb->next) @@ -4778,47 +4795,45 @@ hashElFreeList(&helList); if (retHashOfHash) *retHashOfHash = hashOfHash; else hashFree(&hashOfHash); return raList; } char *addCommasToPos(char *db, char *position) /* add commas to the numbers in a position * returns pointer to static */ { static char buffer[256]; -int winStart, winEnd; +long winStart, winEnd; // long to support virtual chrom char *chromName; char num1Buf[64], num2Buf[64]; /* big enough for 2^64 (and then some) */ if (position == NULL) return NULL; -buffer[sizeof(buffer) - 1] = 0; -if (!hgParseChromRange(NULL, position, &chromName, &winStart, &winEnd)) - strncpy(buffer, position, sizeof(buffer) - 1); -else +if (hgParseChromRangeLong(NULL, position, &chromName, &winStart, &winEnd)) { sprintLongWithCommas(num1Buf, winStart + 1); sprintLongWithCommas(num2Buf, winEnd); - safef(buffer, sizeof(buffer) - 1, "%s:%s-%s",chromName, num1Buf, num2Buf); + safef(buffer, sizeof(buffer), "%s:%s-%s",chromName, num1Buf, num2Buf); } - +else + safecpy(buffer, sizeof(buffer), position); return buffer; } INLINE boolean isAllDigits(char *str) /* Return TRUE if every character in str is a digit. */ { char *p = str; while (*p != '\0') if (!isdigit(*p++)) return FALSE; return TRUE; } boolean parsePosition(char *position, char **retChrom, uint *retStart, uint *retEnd) /* If position is word:number-number (possibly with commas & whitespace),