05563be2e445f57aaadc21dd3a843db0ff8faee6 kent Tue Mar 26 21:52:43 2013 -0700 Adding several new functions to meta library. diff --git src/hg/lib/meta.c src/hg/lib/meta.c index a30fb9b..70e4c18 100644 --- src/hg/lib/meta.c +++ src/hg/lib/meta.c @@ -7,30 +7,55 @@ * target H3K4Me3 * antibody abCamAntiH3k4me3 * * meta lowLevel * fileName hg19/chipSeq/helaH3k4me3.narrowPeak.bigBed * The file is interpreted so that lower level stanzas inherit tags from higher level ones. */ #include "common.h" #include "linefile.h" #include "hash.h" #include "errabort.h" #include "meta.h" #include "ra.h" +struct metaTagVal *metaTagValNew(char *tag, char *val) +/* Create new meta tag/val */ +{ +struct metaTagVal *mtv; +AllocVar(mtv); +mtv->tag = cloneString(tag); +mtv->val = cloneString(val); +return mtv; +} + +int metaTagValCmp(const void *va, const void *vb) +/* Compare to sort based on tag name . */ +{ +const struct metaTagVal *a = *((struct metaTagVal **)va); +const struct metaTagVal *b = *((struct metaTagVal **)vb); +return strcmp(a->tag, b->tag); +} + +void metaSortTags(struct meta *meta) +/* Do canonical sort so that the first tag stays first but the + * rest are alphabetical. */ +{ +slSort(&meta->tagList->next, metaTagValCmp); +} + int countLeadingSpacesDetabbing(char *s, int tabStop) /* Count up leading chars including those implied by tab. Set tabStop to 8 * for usual UNIX results. */ { int count = 0; char c; while ((c = *s++) != 0) { if (c == ' ') ++count; else if (c == '\t') { int tabBefore = (count % tabStop) * tabStop; count = (tabBefore+1)*tabStop; } @@ -262,30 +287,49 @@ char *metaTagVal(struct meta *meta, char *name) /* Return value of tag found in this node or if its not there in parents. * Returns NULL if tag not found. */ { struct meta *m; for (m = meta; m != NULL; m = m->parent) { char *val = metaLocalTagVal(m, name); if (val != NULL) return val; } return NULL; } +void metaAddTag(struct meta *meta, char *tag, char *val) +/* Add tag to meta, replacing existing tag if any */ +{ +/* First loop through to replace an existing tag. */ +struct metaTagVal *mtv; +for (mtv = meta->tagList; mtv != NULL; mtv = mtv->next) + { + if (sameString(mtv->tag, tag)) + { + freeMem(mtv->val); + mtv->val = cloneString(val); + return; + } + } +/* If didn't make it then add new tag (at end) */ +mtv = metaTagValNew(tag, val); +slAddTail(&meta->tagList, mtv); +} + static void rHashMetaList(struct hash *hash, struct meta *list) /* Add list, and any children of list to hash */ { struct meta *meta; for (meta = list; meta != NULL; meta = meta->next) { hashAddUnique(hash, meta->name, meta); if (meta->children) rHashMetaList(hash, meta->children); } } struct hash *metaHash(struct meta *forest) /* Return hash of meta at all levels of heirarchy keyed by forest. */ {