7d6d14047849f1ddcf0aadf5491f2830996df7b5 braney Mon Jul 28 15:37:04 2014 -0700 allow underbars in gff3. Grok Is_circular. #13673 diff --git src/lib/gff3.c src/lib/gff3.c index 4fe91c9..fd6187b 100644 --- src/lib/gff3.c +++ src/lib/gff3.c @@ -29,30 +29,31 @@ */ static const int gffNumCols = 9; /* standard attribute names */ char *gff3AttrID = "ID"; char *gff3AttrName = "Name"; char *gff3AttrAlias = "Alias"; char *gff3AttrParent = "Parent"; char *gff3AttrTarget = "Target"; char *gff3AttrGap = "Gap"; char *gff3AttrDerivesFrom = "Derives_from"; char *gff3AttrNote = "Note"; char *gff3AttrDbxref = "Dbxref"; char *gff3AttrOntologyTerm = "Ontology_term"; +char *gff3AttrIsCircular = "Is_circular"; /* commonly used features names */ char *gff3FeatGene = "gene"; char *gff3FeatMRna = "mRNA"; char *gff3FeatExon = "exon"; char *gff3FeatCDS = "CDS"; char *gff3FeatThreePrimeUTR = "three_prime_UTR"; char *gff3FeatFivePrimeUTR = "five_prime_UTR"; char *gff3FeatStartCodon = "start_codon"; char *gff3FeatStopCodon = "stop_codon"; char *gff3FeatTranscript = "transcript"; static bool gff3FileStopDueToErrors(struct gff3File *g3f) /* determine if we should stop due to the number of errors */ { @@ -335,31 +336,31 @@ // 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 } } /* check that an attribute tag name is valid. */ static boolean checkAttrTag(struct gff3Ann *g3a, char *tag) { // FIXME: spec is not clear on what is a valid tag. char *tc = tag; boolean isOk = isalpha(*tc); for (tc++; isOk && (*tc != '\0'); tc++) { - if (!((*tc == '_') || isalnum(*tc))) + if (!((*tc == '-') || (*tc == '_') || isalnum(*tc))) isOk = FALSE; } if (!isOk) gff3AnnErr(g3a, "invalid attribute tag, must start with an alphabetic character and be composed of alphanumeric or underscore characters: %s", tag); return isOk; } static struct slName *parseAttrVals(struct gff3Ann *g3a, char *tag, char *valsStr) /* parse an attribute into its values */ { int i, numVals = chopString(valsStr, ",", NULL, 0); char **vals = needMem((numVals+1)*sizeof(char**)); // +1 allows for no values chopString(valsStr, ",", vals, numVals); struct slName *unescVals = NULL; for (i = 0; i < numVals; i++) @@ -480,30 +481,36 @@ static void parseGapAttr(struct gff3Ann *g3a, struct gff3Attr *attr) /* parse the Gap attribute */ { checkSingleValAttr(g3a, attr); g3a->gap = attr->vals->name; } static void parseDerivesFromAttr(struct gff3Ann *g3a, struct gff3Attr *attr) /* parse the Derives_from attribute */ { checkSingleValAttr(g3a, attr); g3a->derivesFromId = attr->vals->name; } +static void parseIsCircular(struct gff3Ann *g3a, struct gff3Attr *attr) +/* parse the Note attribute */ +{ +g3a->isCircular = TRUE; +} + static void parseNoteAttr(struct gff3Ann *g3a, struct gff3Attr *attr) /* parse the Note attribute */ { g3a->notes = attr->vals; } static void parseDbxrefAttr(struct gff3Ann *g3a, struct gff3Attr *attr) /* parse the Dbxref attribute */ { g3a->dbxrefs = attr->vals; } static void parseOntologyTermAttr(struct gff3Ann *g3a, struct gff3Attr *attr) /* parse the Ontology_term attribute */ { @@ -517,30 +524,32 @@ { if (sameString(attr->tag, gff3AttrID)) parseIDAttr(g3a, attr); else if (sameString(attr->tag, gff3AttrName)) parseNameAttr(g3a, attr); else if (sameString(attr->tag, gff3AttrAlias)) parseAliasAttr(g3a, attr); else if (sameString(attr->tag, gff3AttrParent)) parseParentAttr(g3a, attr); else if (sameString(attr->tag, gff3AttrTarget)) parseTargetAttr(g3a, attr); else if (sameString(attr->tag, gff3AttrGap)) parseGapAttr(g3a, attr); else if (sameString(attr->tag, gff3AttrDerivesFrom)) parseDerivesFromAttr(g3a, attr); +else if (sameString(attr->tag, gff3AttrIsCircular)) + parseIsCircular(g3a, attr); else if (sameString(attr->tag, gff3AttrNote)) parseNoteAttr(g3a, attr); else if (sameString(attr->tag, gff3AttrDbxref)) parseDbxrefAttr(g3a, attr); else if (sameString(attr->tag, gff3AttrOntologyTerm)) parseOntologyTermAttr(g3a, attr); else gff3AnnErr(g3a, "unknown standard attribute, user defined attributes must start with a lower-case letter: %s", attr->tag); } static void parseStdAttrs(struct gff3Ann *g3a) /* parse standard attributes (starting with upper case) into attributes * have been parsed into attribute list, which would have merged multiply * specified attributes. */ {