src/hg/overlapSelect/coordCols.c 1.4
1.4 2010/01/30 01:14:00 markd
allow specifying location of name when specifying column indices so that -statsOutput is useful
Index: src/hg/overlapSelect/coordCols.c
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/hg/overlapSelect/coordCols.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -b -B -U 1000000 -r1.3 -r1.4
--- src/hg/overlapSelect/coordCols.c 31 Jul 2009 18:09:23 -0000 1.3
+++ src/hg/overlapSelect/coordCols.c 30 Jan 2010 01:14:00 -0000 1.4
@@ -1,75 +1,86 @@
/* coordCols - parsing of file by specifying coordinate columns */
#include "common.h"
#include "coordCols.h"
#include "rowReader.h"
#include "sqlNum.h"
static char const rcsid[] = "$Id$";
static void invalidSpec(char *optName, char* spec)
/* generate an error, msg can be null */
{
errAbort("invalid coord column spec for %s: %s", optName, spec);
}
+static int colIdxOrOmitted(char **words, int numWords, int iWord)
+/* return the column index or -1 if omitted by empty or the end */
+{
+if ((iWord >= numWords) || (strlen(words[iWord]) == 0))
+ return -1;
+else
+ return sqlUnsigned(words[iWord]);
+}
+
struct coordCols coordColsParseSpec(char *optName, char* spec)
/* parse coordinate specified in an option. Can be in the form
* - chromCol - chrom in this column followed by start and end.
- * - chromCol,startCol,endCol - chrom, start, and end in specified
- * columns.
- * - chromCol,startCol,endCol,strandCol - chrom, start, end, and
- * strand in specified columns.
+ * - chromCol,startCol,endCol,strandCol,name - chrom, start, end, and
+ * strand in specified columns. With unneeded columns empty or dropped
+ * from the end.
*/
{
char buf[128];
int numWords;
-char *words[4];
+char *words[6];
struct coordCols cols;
ZeroVar(&cols);
cols.strandCol = -1;
if (strlen(spec) > sizeof(buf)-1)
invalidSpec(optName, spec);
-strcpy(buf, spec);
-numWords = chopString(buf, ",", words, ArraySize(words));
-switch (numWords) {
-case 1:
+safecpy(buf, sizeof(buf), spec);
+numWords = chopByChar(buf, ',', words, ArraySize(words));
+if (numWords == 1)
+ {
cols.chromCol = sqlUnsigned(words[0]);
cols.startCol = cols.chromCol + 1;
cols.endCol = cols.chromCol + 2;
- break;
-case 4:
- cols.strandCol = sqlUnsigned(words[3]);
-case 3:
+ }
+else if (numWords <= 5)
+ {
cols.chromCol = sqlUnsigned(words[0]);
cols.startCol = sqlUnsigned(words[1]);
cols.endCol = sqlUnsigned(words[2]);
- break;
-default:
+ cols.strandCol = colIdxOrOmitted(words, numWords, 3);
+ cols.nameCol = colIdxOrOmitted(words, numWords, 4);
+ }
+else
invalidSpec(optName, spec);
-}
-cols.minNumCols = cols.chromCol;
-cols.minNumCols = max(cols.minNumCols, cols.startCol);
-cols.minNumCols = max(cols.minNumCols, cols.endCol);
+// find minimum number of columns
+cols.minNumCols = cols.chromCol+1;
+cols.minNumCols = max(cols.minNumCols, cols.startCol+1);
+cols.minNumCols = max(cols.minNumCols, cols.endCol+1);
if (cols.strandCol >= 0)
- cols.minNumCols = max(cols.minNumCols, cols.strandCol);
-cols.minNumCols++;
-
+ cols.minNumCols = max(cols.minNumCols, cols.strandCol+1);
+if (cols.nameCol >= 0)
+ cols.minNumCols = max(cols.minNumCols, cols.nameCol+1);
return cols;
}
struct coordColVals coordColParseRow(struct coordCols* cols,
struct rowReader *rr)
-/* parse coords from a row */
+/* parse coords from a row, call coordColsRelease when done with result */
{
struct coordColVals colVals;
ZeroVar(&colVals);
rowReaderExpectAtLeast(rr, cols->minNumCols);
colVals.chrom = rr->row[cols->chromCol];
colVals.start = sqlUnsigned(rr->row[cols->startCol]);
colVals.end = sqlUnsigned(rr->row[cols->endCol]);
if (cols->strandCol >= 0)
colVals.strand = rr->row[cols->strandCol][0];
+if (cols->nameCol >= 0)
+ colVals.name = cloneString(rr->row[cols->nameCol]);
return colVals;
}