8a0946dd6870f10cde056ba243f1fb4ec1fd16b4 angie Thu Feb 27 11:58:33 2014 -0800 Adding support for plain VCF custom tracks (as opposed to VCF+tabix),since users seem to want to upload VCF, and as long as the file is not too big it will work OK. This means adding a new track type vcf (as opposed to vcfTabix) and supporting it in hgTracks, hgTrackUi, hgc, hgTables and hgVai. (and others I've forgotten?) refs #12416 diff --git src/hg/lib/customPp.c src/hg/lib/customPp.c index 112fc2d..53942ac 100644 --- src/hg/lib/customPp.c +++ src/hg/lib/customPp.c @@ -32,30 +32,31 @@ AllocVar(cpp); cpp->fileStack = lf; return cpp; } void customPpFree(struct customPp **pCpp) /* Close files and free up customPp. */ { struct customPp *cpp = *pCpp; if (cpp) { lineFileCloseList(&cpp->fileStack); slFreeList(&cpp->browserLines); slFreeList(&cpp->reusedLines); freeMem(cpp->inReuse); + slFreeList(&cpp->skippedLines); } } char *customPpNext(struct customPp *cpp) /* Return next line. */ { /* Check first for line to reuse. */ struct slName *reused = cpp->reusedLines; if (reused) { /* We need to keep line actually reusing in memory until next * call to customPpNext, so we move it to inReuse rather than * immediately freeing it. */ freeMem(cpp->inReuse); cpp->reusedLines = reused->next; @@ -93,53 +94,67 @@ continue; } } return line; } else { cpp->fileStack = lf->next; lineFileClose(&lf); } } return NULL; } char *customPpNextReal(struct customPp *cpp) -/* Return next line that's nonempty and non-space. */ +/* Return next line that's nonempty, non-space and not a comment. + * Save skipped comment lines to cpp->skippedLines. */ { +slFreeList(&cpp->skippedLines); for (;;) { char *line = customPpNext(cpp); if (line == NULL) return line; char *s = skipLeadingSpaces(line); char c = *s; if (c != 0 && c != '#') return line; + else if (c == '#') + slNameAddHead(&cpp->skippedLines, line); } } void customPpReuse(struct customPp *cpp, char *line) /* Reuse line. May be called many times before next customPpNext/NextReal. * Should be called with last line to be reused first if called multiply. */ { struct slName *s = slNameNew(line); slAddHead(&cpp->reusedLines, s); } struct slName *customPpTakeBrowserLines(struct customPp *cpp) /* Grab browser lines from cpp, which will no longer have them. */ { struct slName *browserLines = cpp->browserLines; cpp->browserLines = NULL; return browserLines; } +struct slName *customPpCloneSkippedLines(struct customPp *cpp) +/* Return a clone of most recent nonempty skipped (comment/header) lines from cpp, + * which will still have them. slFreeList when done. */ +{ +struct slName *skippedLines = NULL, *sl; +for (sl = cpp->skippedLines; sl != NULL; sl = sl->next) + slNameAddHead(&skippedLines, sl->name); +return skippedLines; +} + char *customPpFileName(struct customPp *cpp) /* Return the name of the current file being parsed (top of fileStack), or NULL * if fileStack is NULL. Free when done. */ { if (cpp->fileStack == NULL) return NULL; return cloneString(cpp->fileStack->fileName); }