56c5a21bd036712b38873f830b46b33351fbb5e4 giardine Fri Nov 5 13:21:35 2010 -0700 Added error checking for pgSnp and bedDetail custom track loaders, issue #1595 diff --git src/hg/lib/pgSnp.c src/hg/lib/pgSnp.c index d6149f3..44e0ba0 100644 --- src/hg/lib/pgSnp.c +++ src/hg/lib/pgSnp.c @@ -1,27 +1,28 @@ /* pgSnp.c was originally generated by the autoSql program, which also * generated pgSnp.h and pgSnp.sql. This module links the database and * the RAM representation of objects. */ #include "common.h" #include "linefile.h" #include "dystring.h" #include "jksql.h" #include "pgSnp.h" #include "hdb.h" #include "dnaseq.h" #include "pgPhenoAssoc.h" +#include "hgFindSpec.h" static char const rcsid[] = "$Id: pgSnp.c,v 1.8 2010/03/08 17:45:41 giardine Exp $"; void pgSnpStaticLoad(char **row, struct pgSnp *ret) /* Load a row from pgSnp table into ret. The contents of ret will * be replaced at the next call to this function. */ { ret->bin = sqlUnsigned(row[0]); ret->chrom = row[1]; ret->chromStart = sqlUnsigned(row[2]); ret->chromEnd = sqlUnsigned(row[3]); ret->name = row[4]; ret->alleleCount = sqlSigned(row[5]); ret->alleleFreq = row[6]; @@ -640,15 +641,51 @@ { struct pgSnp *ret; AllocVar(ret); ret->bin = 0; ret->chrom = cloneString(row[0]); ret->chromStart = sqlUnsigned(row[1]); ret->chromEnd = sqlUnsigned(row[2]); ret->name = cloneString(row[3]); ret->alleleCount = sqlSigned(row[4]); ret->alleleFreq = cloneString(row[5]); ret->alleleScores = cloneString(row[6]); return ret; } +struct pgSnp *pgSnpLineFileLoad(char **row, struct lineFile *lf) +/* Load pgSnp from a lineFile line, with error checking. */ +/* Requires comma separated zeroes for frequency and scores. */ +{ +struct pgSnp *item; +AllocVar(item); +item->chrom = cloneString(row[0]); +item->chromStart = lineFileNeedNum(lf, row, 1); +item->chromEnd = lineFileNeedNum(lf, row, 2); +if (item->chromEnd < 1) + lineFileAbort(lf, "chromEnd less than 1 (%d)", item->chromEnd); +if (item->chromEnd < item->chromStart) + lineFileAbort(lf, "chromStart after chromEnd (%d > %d)", + item->chromStart, item->chromEnd); +/* use pattern match to check values and counts both */ +/* alleles are separated by / and can be ACTG- */ +item->name = cloneString(row[3]); +/* allele count, positive integer matching # of alleles */ +item->alleleCount = lineFileNeedNum(lf, row, 4); +char alleles[128]; /* pattern to match alleles */ +safef(alleles, sizeof(alleles), "^[ACTG-]+(\\/[ACTG-]+){%d}$", item->alleleCount - 1); +if (! matchRegex(row[3], alleles)) + errAbort("invalid alleles %s", row[3]); +/* read count, comma separated list of numbers with above # of items */ +item->alleleFreq = cloneString(row[5]); +char pattern[128]; +safef(pattern, sizeof(pattern), "^[0-9]+(,[0-9]+){%d}$", item->alleleCount - 1); +if (! matchRegex(row[5], pattern)) + errAbort("invalid allele frequency, %s with count of %d", row[5], item->alleleCount); +/* scores, comma separated list of numbers with above # of items */ +item->alleleScores = cloneString(row[6]); +safef(pattern, sizeof(pattern), "^[0-9.]+(,[0-9.]+){%d}$", item->alleleCount - 1); +if (! matchRegex(row[6], pattern)) + errAbort("invalid allele scores, %s with count of %d", row[6], item->alleleCount); +return item; +}