src/lib/gff3.c 1.4

1.4 2010/03/20 15:32:13 markd
spec unclear where phase is allowed, so don't reject for non-CDS feeatures
Index: src/lib/gff3.c
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/lib/gff3.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -b -B -U 4 -r1.3 -r1.4
--- src/lib/gff3.c	12 Aug 2009 07:48:05 -0000	1.3
+++ src/lib/gff3.c	20 Mar 2010 15:32:13 -0000	1.4
@@ -306,10 +306,21 @@
     g3a->haveScore = TRUE;
     }
 g3a->strand = parseStrand(g3a, words[6]);
 g3a->phase = parsePhase(g3a, words[7]);
-if (sameString(g3a->type, "CDS") && (g3a->phase < 0))
+if (sameString(g3a->type, "CDS"))
+    {
+    if (g3a->phase < 0)
     gff3AnnErr(g3a, "CDS feature must have phase");
+    }
+else
+    {
+#if 0 // spec unclear; bug report filed
+    // spec currently doesn't restrict phase, unclear if it's allowed on start/stop codon features
+    if (g3a->phase >= 0)
+        gff3AnnErr(g3a, "phase only allowed on CDS features");
+#endif
+    }
 }
 
 static struct slName *parseAttrVals(struct gff3Ann *g3a, char *attr, char *valsStr)
 /* parse an attribute into its values */
@@ -345,13 +356,16 @@
 {
 char *eq = strchr(attrValsStr, '=');
 if ((eq == NULL) || (eq == attrValsStr))
     gff3AnnErr(g3a, "expected name=value: %s", attrValsStr);
-char *attr = attrValsStr;
-char *vals = eq+1;
-*eq = '\0';
-unescapeStr(g3a, attr, attr);
-addAttrVals(g3a, attr, vals);
+else
+    {
+    char *attr = attrValsStr;
+    char *vals = eq+1;
+    *eq = '\0';
+    unescapeStr(g3a, attr, attr);
+    addAttrVals(g3a, attr, vals);
+    }
 }
 
 static void parseAttrs(struct gff3Ann *g3a, char *attrsCol)
 /* parse the attribute column in an annotation record */
@@ -792,9 +806,13 @@
 g3f->lf = lineFileOpen(g3f->fileName, TRUE);
 parseHeader(g3f);
 char *line;
 while (lineFileNext(g3f->lf, &line, NULL))
+    {
     parseLine(g3f, line);
+    if (g3f->errCnt >= g3f->maxErr)
+        break;
+    }
 lineFileClose(&g3f->lf);
 slReverse(&g3f->anns);
 }
 
@@ -841,9 +859,13 @@
 /* do resolution phase of reading a GFF3 file */
 {
 struct gff3Ann *g3a;
 for (g3a = g3f->anns; g3a != NULL; g3a = g3a->next)
+    {
     resolveAnn(g3a);
+    if (g3f->errCnt >= g3f->maxErr)
+        break;
+    }
 // reorder just for test reproducibility
 slReverse(&g3f->seqRegions);
 slReverse(&g3f->featureOntologies);
 slReverse(&g3f->attributeOntologies);
@@ -872,9 +894,10 @@
 g3f->fileName = gff3FileCloneStr(g3f, fileName);
 g3f->errFh = (errFh != NULL) ? errFh : stderr;
 g3f->maxErr = (maxErr < 0) ? INT_MAX : maxErr;
 parseFile(g3f);
-resolveFile(g3f);
+if (g3f->errCnt < g3f->maxErr)
+    resolveFile(g3f);
 if (g3f->errCnt > 0)
     errAbort("GFF3: %d parser errors", g3f->errCnt);
 return g3f;
 }