4a30449df90693f80750c79f16225a0000b9fa4c
kent
  Tue Mar 26 22:48:30 2013 -0700
Added test case.
diff --git src/meta/metaFlatten/metaFlatten.c src/meta/metaFlatten/metaFlatten.c
new file mode 100644
index 0000000..6c31cb7
--- /dev/null
+++ src/meta/metaFlatten/metaFlatten.c
@@ -0,0 +1,82 @@
+/* metaFlatten - Flatten meta.ra file so all stanzas include all tags.. */
+#include "common.h"
+#include "linefile.h"
+#include "hash.h"
+#include "options.h"
+#include "meta.h"
+
+boolean withParent = FALSE;
+boolean indent = 3;
+
+void usage()
+/* Explain usage and exit. */
+{
+errAbort(
+  "metaFlatten - Flatten meta.ra file so all stanzas include all tags.\n"
+  "usage:\n"
+  "   metaFlatten input output\n"
+  "options:\n"
+  "   -withParent - if set write out parent tags in each stanze\n"
+  "   -indent - amount to indent per level of nesting.  If 0, you better set -withParent too.\n"
+  "             Default is %d\n"
+  , indent
+  );
+}
+
+/* Command line validation table. */
+static struct optionSpec options[] = {
+   {"withParent", OPTION_BOOLEAN},
+   {"indent", OPTION_INT},
+   {NULL, 0},
+};
+
+static void addNewTags(struct meta *meta, struct metaTagVal *mtvList)
+/* Add all tags in list that are not already in meta to meta. */
+{
+struct metaTagVal *mtv;
+for (mtv = mtvList; mtv != NULL; mtv = mtv->next)
+    {
+    if (metaLocalTagVal(meta, mtv->tag) == NULL)
+        {
+	struct metaTagVal *newMtv;
+	AllocVar(newMtv);
+	newMtv->tag = mtv->tag;
+	newMtv->val = mtv->val;
+	slAddTail(&meta->tagList, newMtv);
+	}
+    }
+}
+
+static void rMetaFlatten(struct meta *metaList)
+/* Add tags from parents to our own tags (so long as they don't conflict */
+{
+struct meta *meta;
+for (meta = metaList; meta != NULL; meta = meta->next)
+    {
+    if (meta->parent)
+        addNewTags(meta, meta->parent->tagList);
+    metaSortTags(meta);
+    if (meta->children)
+        rMetaFlatten(meta->children);
+    }
+}
+
+void metaFlatten(char *input, char *output)
+/* metaFlatten - Flatten meta.ra file so all stanzas include all tags.. */
+{
+struct meta *metaList = metaLoadAll(input, "meta", "parent", FALSE, FALSE);
+rMetaFlatten(metaList);
+metaWriteAll(metaList, output, indent, withParent);
+}
+
+int main(int argc, char *argv[])
+/* Process command line. */
+{
+optionInit(&argc, argv, options);
+if (argc != 3)
+    usage();
+indent = optionInt("indent", indent);
+withParent = optionExists("withParent");
+metaFlatten(argv[1], argv[2]);
+return 0;
+}