5b19f269d7e89acb83b34ad0ffeb1f6451a8210b
markd
  Sun Oct 17 19:32:25 2021 -0700
added option to bigBedToBed to write autoSql style column header

diff --git src/utils/bigBedToBed/bigBedToBed.c src/utils/bigBedToBed/bigBedToBed.c
index 1acbcc7..61e5d4d 100644
--- src/utils/bigBedToBed/bigBedToBed.c
+++ src/utils/bigBedToBed/bigBedToBed.c
@@ -1,64 +1,88 @@
 /* bigBedToBed - Convert from bigBed to ascii bed format.. */
 
 /* Copyright (C) 2014 The Regents of the University of California 
  * See README in this or parent directory for licensing information. */
 #include "common.h"
 #include "linefile.h"
 #include "hash.h"
 #include "options.h"
 #include "localmem.h"
 #include "udc.h"
 #include "bigBed.h"
+#include "asParse.h"
 #include "obscure.h"
 
 
 char *clChrom = NULL;
 int clStart = -1;
 int clEnd = -1;
 int maxItems = 0;
+boolean header = FALSE;
 
 void usage()
 /* Explain usage and exit. */
 {
 errAbort(
   "bigBedToBed v1 - Convert from bigBed to ascii bed format.\n"
   "usage:\n"
   "   bigBedToBed input.bb output.bed\n"
   "options:\n"
   "   -chrom=chr1 - if set restrict output to given chromosome\n"
   "   -start=N - if set, restrict output to only that over start\n"
   "   -end=N - if set, restict output to only that under end\n"
   "   -maxItems=N - if set, restrict output to first N items\n"
   "   -udcDir=/dir/to/cache - place to put cache for remote bigBed/bigWigs\n"
+  "   -header - output a autoSql-style header (starts with '#').\n"
   );
 }
 
 static struct optionSpec options[] = {
    {"chrom", OPTION_STRING},
    {"start", OPTION_INT},
    {"end", OPTION_INT},
    {"maxItems", OPTION_INT},
    {"udcDir", OPTION_STRING},
+   {"header", OPTION_BOOLEAN},
    {NULL, 0},
 };
 
+
+void writeHeader(struct bbiFile *bbi, FILE *f)
+/* output a header from the autoSql in the file */
+{
+char *asText = bigBedAutoSqlText(bbi);
+if (asText == NULL)
+    errAbort("bigBed files does not contain an autoSql schema");
+struct asObject *asObj = asParseText(asText);
+char sep = '#';
+for (struct asColumn *asCol = asObj->columnList; asCol != NULL; asCol = asCol->next)
+    {
+    fputc(sep, f);
+    fputs(asCol->name, f);
+    sep = '\t';
+    }
+fputc('\n', f);
+}
+
 void bigBedToBed(char *inFile, char *outFile)
 /* bigBedToBed - Convert from bigBed to ascii bed format.. */
 {
 struct bbiFile *bbi = bigBedFileOpen(inFile);
 FILE *f = mustOpen(outFile, "w");
+if (header)
+    writeHeader(bbi, f);
 struct bbiChromInfo *chrom, *chromList = bbiChromList(bbi);
 int itemCount = 0;
 for (chrom = chromList; chrom != NULL; chrom = chrom->next)
     {
     if (clChrom != NULL && !sameString(clChrom, chrom->name))
         continue;
     char *chromName = chrom->name;
     int start = 0, end = chrom->size;
     if (clStart > 0)
         start = clStart;
     if (clEnd > 0)
         end = clEnd;
     int itemsLeft = 0;	// Zero actually means no limit.... 
     if (maxItems != 0)
         {
@@ -82,22 +106,23 @@
     }
 bbiChromInfoFreeList(&chromList);
 carefulClose(&f);
 bbiFileClose(&bbi);
 }
 
 int main(int argc, char *argv[])
 /* Process command line. */
 {
 optionInit(&argc, argv, options);
 clChrom = optionVal("chrom", clChrom);
 clStart = optionInt("start", clStart);
 clEnd = optionInt("end", clEnd);
 maxItems = optionInt("maxItems", maxItems);
 udcSetDefaultDir(optionVal("udcDir", udcDefaultDir()));
+header = optionExists("header");
 if (argc != 3)
     usage();
 bigBedToBed(argv[1], argv[2]);
 if (verboseLevel() > 1)
     printVmPeak();
 return 0;
 }