2070aedea88da26aee0af3e2fd867b67140b09b5 lrnassar Wed Aug 5 16:59:19 2026 -0700 Move the maf sequence-name splitter into jkweb so both summary tools share one copy. refs #37928 mafSplitSrcGetChrom existed as two independent copies, in hgLoadMafSummary.c and mafToBigMafSummary.c, and they had diverged: only the first had the GenArk accession rule added by 2db6bab8db0. It now lives in src/lib/maf.c, with the rules documented in maf.h. mafToBigMafSummary therefore picks up the GenArk rule it was missing, so a dotted GenArk name like GCA_009914755.4.CM034974.1 now keeps its accession version instead of dropping it, which matches what hprc90waySummary already holds. Also removes mafCompGetSrcDb and mafCompGetSrcName from maf.c and maf.h. Both were first-dot splitters with no callers anywhere in the tree. diff --git src/lib/maf.c src/lib/maf.c index 2930fa43b4d..6141c5ae922 100644 --- src/lib/maf.c +++ src/lib/maf.c @@ -390,52 +390,76 @@ } void mafCompFreeList(struct mafComp **pList) /* Free up a list of maf components. */ { struct mafComp *el, *next; for (el = *pList; el != NULL; el = next) { next = el->next; mafCompFree(&el); } *pList = NULL; } -char *mafCompGetSrcDb(struct mafComp *mc, char *buf, int bufSize) -/* parse the srcDb name from the mafComp src name, return NULL if no srcDb */ +char *mafSplitSrcGetChrom(char *src, char *database) +/* Split a maf sequence name into its db and chrom: truncate src in place so it holds only + * the db, and return a pointer to the chrom. The numbered steps below are spelled out in + * maf.h, which is the authority on the rules. See mafSrcDb for the simpler + * non-destructive first-dot-only version used by the track display code. */ { -char *e = strchr(mc->src, '.'); -if (e == NULL) - return NULL; -int len = e - mc->src; -if (len >= bufSize-1) - errAbort("srcDb name in \"%s\" overflows buffer length of %d", mc->src, bufSize); -strncpy(buf, mc->src, len); -buf[len] = '\0'; -return buf; +/* 1. A pipe is always an explicit db|chrom separator. */ +char *pipe = strchr(src, '|'); +if (pipe != NULL) + { + *pipe = '\0'; + return pipe + 1; } -char *mafCompGetSrcName(struct mafComp *mc) -/* parse the src sequence name from the mafComp src name */ +/* 2. No separator at all: the whole string is the chrom, and src is left whole. */ +char *dot1 = strchr(src, '.'); +if (dot1 == NULL) + return src; + +/* 3. When we know the reference database and src starts with "<database>.", split there. */ +if (database != NULL) { -char *e = strchr(mc->src, '.'); -if (e == NULL) - return mc->src; -else - return e+1; + int dbLen = strlen(database); + if (startsWith(database, src) && src[dbLen] == '.') + { + src[dbLen] = '\0'; + return src + dbLen + 1; + } + } + +/* 4. A GenArk accession db (GCA_/GCF_) carries one internal dot (accession.version), + * so the db ends at the second dot. */ +if (startsWith("GCA_", src) || startsWith("GCF_", src)) + { + char *dot2 = strchr(dot1 + 1, '.'); + if (dot2 != NULL) + { + *dot2 = '\0'; + return dot2 + 1; + } + // accession with no chrom after the version: fall through to the first-dot split + } + +/* 5. Ordinary db with no dot: split at the first dot. */ +*dot1 = '\0'; +return dot1 + 1; } int mafPlusStart(struct mafComp *comp) /* Return start relative to plus strand of src. */ { if (comp->strand == '-') return comp->srcSize - (comp->start + comp->size); else return comp->start; } void mafAliFree(struct mafAli **pObj) /* Free up a maf alignment. */ { struct mafAli *obj = *pObj;