NCBI C++ ToolKit
xgbfeat.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /***************************************************************************
2  * gbfeat.c:
3  * -- all routines for checking genbank feature table
4  * -- all extern variables are in gbftglob.c
5  * 10-11-93
6  *
7  ****************************************************************************/
8 
9 #include <ncbi_pch.hpp>
10 
13 
14 #include "ftacpp.hpp"
15 
16 #include "ftaerr.hpp"
17 #include "xgbfeat.h"
18 
19 #ifdef THIS_FILE
20 # undef THIS_FILE
21 #endif
22 #define THIS_FILE "xgbfeat.cpp"
23 
26 
27 static const Char* this_module = "validatr";
28 
29 #ifdef THIS_MODULE
30 # undef THIS_MODULE
31 #endif
32 #define THIS_MODULE this_module
33 
34 
35 // error definitions from C-toolkit
36 #define ERR_FEATURE 1, 0
37 #define ERR_FEATURE_UnknownFeatureKey 1, 1
38 #define ERR_FEATURE_MissManQual 1, 2
39 #define ERR_FEATURE_QualWrongThisFeat 1, 3
40 #define ERR_FEATURE_FeatureKeyReplaced 1, 4
41 #define ERR_FEATURE_LocationParsing 1, 5
42 #define ERR_FEATURE_IllegalFormat 1, 6
43 #define ERR_QUALIFIER 2, 0
44 #define ERR_QUALIFIER_InvalidDataFormat 2, 1
45 #define ERR_QUALIFIER_Too_many_tokens 2, 2
46 #define ERR_QUALIFIER_MultiValue 2, 3
47 #define ERR_QUALIFIER_UnknownSpelling 2, 4
48 #define ERR_QUALIFIER_Xtratext 2, 5
49 #define ERR_QUALIFIER_SeqPosComma 2, 6
50 #define ERR_QUALIFIER_Pos 2, 7
51 #define ERR_QUALIFIER_EmptyNote 2, 8
52 #define ERR_QUALIFIER_NoteEmbeddedQual 2, 9
53 #define ERR_QUALIFIER_EmbeddedQual 2, 10
54 #define ERR_QUALIFIER_AA 2, 11
55 #define ERR_QUALIFIER_Seq 2, 12
56 #define ERR_QUALIFIER_BadECnum 2, 13
57 #define ERR_QUALIFIER_Cons_splice 2, 14
58 
59 #define ParFlat_Stoken_type 1
60 #define ParFlat_BracketInt_type 2
61 #define ParFlat_Integer_type 3
62 #define ParFlat_Number_type 4
63 
64 static int SplitMultiValQual(TQualVector& quals);
65 static int GBQualSemanticValid(TQualVector& quals, bool error_msgs, bool perform_corrections);
66 static int CkQualPosaa(CGb_qual& cur, bool error_msgs);
67 static int CkQualNote(CGb_qual& cur,
68  bool error_msgs,
69  bool perform_corrections);
70 static int CkQualText(CGb_qual& cur,
71  bool* has_embedded,
72  bool from_note,
73  bool error_msgs,
74  bool perform_corrections);
75 static int CkQualTokenType(CGb_qual& cur,
76  bool error_msgs,
77  Uint1 type);
78 static int CkQualSeqaa(CGb_qual& cur, bool error_msgs);
79 static int CkQualMatchToken(CGb_qual& cur,
80  bool error_msgs,
81  const Char* array_string[],
82  Int2 totalstr);
83 static int CkQualSite(CGb_qual& cur, bool error_msgs);
84 static int CkQualEcnum(CGb_qual& cur,
85  bool error_msgs,
86  bool perform_corrections);
87 
88 static const Char* CkBracketType(const Char* str);
89 static const Char* CkNumberType(const Char* str);
90 static const Char* CkLabelType(const Char* str);
91 
92 
93 #define ParFlat_SPLIT_IGNORE 4
95  "citation", "EC_number", "rpt_type", "usedin"
96 };
97 
98 
99 /*------------------------- GBQualSplit() ------------------------*/
100 /****************************************************************************
101  * GBQualSplit:
102  * -- return index of the GBQual_names_split_ignore array if it is a valid
103  * qualifier (ignore case), qual; otherwise return (-1)
104  * 10-12-93
105  *****************************************************************************/
106 static Int2 GBQualSplit(const Char* qual)
107 {
108  Int2 i;
109 
110  for (i = 0; i < ParFlat_SPLIT_IGNORE && qual; i++) {
112  return (i);
113  }
114 
115  return (-1);
116 
117 } /* GBQualSplit */
118 
119 /*--------------------------- GBFeatKeyQualValid() -----------------------*/
120 /***************************************************************************
121  * GBFeatKeyQualValid:
122  * -- returns error severity level.
123  * error dealt with here. Messages output if parameter 'error_msgs' set,
124  * repair done if 'perform_corrections' set
125  * 10-11-93
126  *****************************************************************************/
127 int XGBFeatKeyQualValid(CSeqFeatData::ESubtype subtype, TQualVector& quals, bool error_msgs, bool perform_corrections)
128 {
129  bool fqual = false;
130  int retval = GB_FEAT_ERR_NONE;
131 
132  /* unknown qual will be drop after the routine */
133  retval = SplitMultiValQual(quals);
134  retval = GBQualSemanticValid(quals, error_msgs, perform_corrections);
135  /*----------------------------------------
136  if the Semnatic QUALIFIER validator says drop, then
137  at the feature level, it is repairable by dropping the
138  qualifier. The only DROP for a feature is lack of
139  a manditory qualifier which is handled later in this function.
140  -Karl 2/7/94
141  -----------------------------*/
142  if (retval == GB_FEAT_ERR_DROP) {
143  retval = GB_FEAT_ERR_REPAIRABLE;
144  }
145 
146  for (TQualVector::iterator cur = quals.begin(); cur != quals.end();) {
147  const string& qual_str = (*cur)->GetQual();
148  if (qual_str == "gsdb_id") {
149  ++cur;
150  continue;
151  }
152 
153  string qs = qual_str;
154  if (qs == "geo_loc_name") {
155  qs = "country";
156  }
158  fqual = CSeqFeatData::IsLegalQualifier(subtype, qual_type);
159 
160  if (! fqual) {
161  /* go back to check, is this a mandatory qualifier ? */
163  if (qual_type == cur_type) {
164  fqual = true;
165  break;
166  }
167  }
168 
169  if (! fqual) {
170  if (retval < GB_FEAT_ERR_REPAIRABLE) {
171  retval = GB_FEAT_ERR_REPAIRABLE;
172  }
173  if (error_msgs) {
175  }
176  if (perform_corrections) {
177  cur = quals.erase(cur);
178  continue;
179  }
180  }
181  }
182 
183  ++cur;
184  }
185 
186  if (! CSeqFeatData::GetMandatoryQualifiers(subtype).empty()) {
187  /* do they contain all the mandatory qualifiers? */
189  for (const auto& cur : quals) {
190  fqual = false;
191 
192  if (cur_type == CSeqFeatData::GetQualifierType(cur->GetQual())) {
193  fqual = true;
194  break;
195  }
196  }
197 
198  if (! fqual) {
199  if (error_msgs) {
200  string str = CSeqFeatData::GetQualifierAsString(cur_type);
202  }
203 
204  if (perform_corrections)
205  retval = GB_FEAT_ERR_DROP;
206  }
207  }
208  }
209  /* check optional qualifiers */
210 
211  return retval;
212 
213 } /* GBFeatKeyQualValid */
214 
215 /*-------------------------- SplitMultiValQual() ------------------------*/
216 /***************************************************************************
217  * SplitMultiValQual:
218  *
219  *
220  ****************************************************************************/
221 static int SplitMultiValQual(TQualVector& quals)
222 {
223  Int2 val /*, len -- UNUSED */;
224  int retval = GB_FEAT_ERR_NONE;
225 
226  for (auto& cur : quals) {
227  const string& qual_str = cur->GetQual();
228  val = GBQualSplit(qual_str.c_str());
229 
230  if (val == -1) {
231  continue;
232  }
233  if (! cur->IsSetVal()) {
234  continue;
235  }
236 
237  string val_str = cur->GetVal();
238  if (*val_str.begin() != '(') {
239  continue;
240  }
241  if (*val_str.rbegin() != ')') {
242  continue;
243  }
244 
245  val_str = val_str.substr(1, val_str.size() - 2);
246  size_t sep_pos = val_str.find(',');
247  if (sep_pos == string::npos) {
248  cur->SetVal(val_str);
249  continue;
250  }
251 
252  ErrPostEx(SEV_WARNING, ERR_QUALIFIER_MultiValue, "Splited qualifier %s", qual_str.c_str());
253 
254  cur->SetVal(val_str.substr(0, sep_pos));
255 
256  size_t offset = sep_pos + 1;
257  sep_pos = val_str.find(',', offset);
258  while (sep_pos != string::npos) {
259  CRef<CGb_qual> qual_new(new CGb_qual);
260  qual_new->SetQual(qual_str);
261  qual_new->SetVal(val_str.substr(offset, sep_pos - offset));
262 
263  if (qual_new->IsSetQual() && ! qual_new->GetQual().empty())
264  quals.push_back(qual_new);
265  }
266  }
267 
268  return retval;
269 
270 } /* SplitMultiValQual */
271 
291 };
292 
294 {
295  static map<CSeqFeatData::EQualifier, ETokenClass> QUAL_TYPE_TO_VAL_CLASS_MAP = {
431  };
432 
433 
434  auto val_class = QUAL_TYPE_TO_VAL_CLASS_MAP.find(qual_type);
435  if (val_class == QUAL_TYPE_TO_VAL_CLASS_MAP.end()) {
436  return eClass_unknown;
437  }
438 
439  return val_class->second;
440 }
441 
442 const Char* ParFlat_IntOrString[] = { "1", "2", "3" };
443 
444 const Char* ParFlat_LRBString[] = { "LEFT", "RIGHT", "BOTH" };
445 
447  "EXPERIMENTAL", "NOT_EXPERIMENTAL"
448 };
449 
451  "tandem",
452  "inverted",
453  "flanking",
454  "terminal",
455  "direct",
456  "dispersed",
457  "long_terminal_repeat",
458  "non_LTR_retrotransposon_polymeric_tract",
459  "X_element_combinatorial_repeat",
460  "Y_prime_element",
461  "telomeric_repeat",
462  "centromeric_repeat",
463  "engineered_foreign_repetitive_element",
464  "other"
465 };
466 
467 
468 /*-------------------------- GBQualSemanticValid() ------------------------*/
469 /***************************************************************************
470  * GBQualSemanticValid:
471  * -- returns GB_ERR level, outputs error messages if
472  * 'error_msgs', set
473  *
474  * -- routine also drop out any unknown qualifier, if
475  * 'perform_corrections' is set 10-11-93
476  *
477  ****************************************************************************/
478 static int GBQualSemanticValid(TQualVector& quals, bool error_msgs, bool perform_corrections)
479 {
480  int retval = GB_FEAT_ERR_NONE,
481  ret = 0;
482 
483  for (TQualVector::iterator cur = quals.begin(); cur != quals.end();) {
484  const string& qual_str = (*cur)->GetQual();
485  if (qual_str == "gsdb_id") {
486  ++cur;
487  continue;
488  }
489 
490  string qs = qual_str;
491  if (qs == "geo_loc_name") {
492  qs = "country";
493  }
495  if (qual_type == CSeqFeatData::eQual_bad) {
496  if (retval < GB_FEAT_ERR_REPAIRABLE) {
497  retval = GB_FEAT_ERR_REPAIRABLE;
498  }
499  if (error_msgs) {
501  }
502  if (perform_corrections) {
503  cur = quals.erase(cur);
504  } else
505  ++cur;
506  } else {
507  switch (GetQualifierClass(qual_type)) {
508  case eClass_pos_aa:
509  ret = CkQualPosaa(*(*cur), error_msgs);
510  if (ret > retval) {
511  retval = ret;
512  }
513  break;
514  case eClass_note:
515  ret = CkQualNote(*(*cur), error_msgs, perform_corrections);
516  if (ret > retval) {
517  retval = ret;
518  }
519  break;
520  case eClass_text:
521  ret = CkQualText(*(*cur), nullptr, false, error_msgs, perform_corrections);
522  if (ret > retval) {
523  retval = ret;
524  }
525  break;
526  case eClass_bracket_int:
527  ret = CkQualTokenType(*(*cur), error_msgs, ParFlat_BracketInt_type);
528  if (ret > retval) {
529  retval = ret;
530  }
531  break;
532  case eClass_seq_aa:
533  ret = CkQualSeqaa(*(*cur), error_msgs);
534  if (ret > retval) {
535  retval = ret;
536  }
537  break;
538  case eClass_int_or:
539  ret = CkQualMatchToken(*(*cur), error_msgs, ParFlat_IntOrString, sizeof(ParFlat_IntOrString) / sizeof(ParFlat_IntOrString[0]));
540  if (ret > retval) {
541  retval = ret;
542  }
543  break;
544  case eClass_site:
545  ret = CkQualSite(*(*cur), error_msgs);
546  if (ret > retval) {
547  retval = ret;
548  }
549  break;
550  case eClass_L_R_B:
551  ret = CkQualMatchToken(*(*cur), error_msgs, ParFlat_LRBString, sizeof(ParFlat_LRBString) / sizeof(ParFlat_LRBString[0]));
552  if (ret > retval) {
553  retval = ret;
554  }
555  break;
556  case eClass_ecnum:
557  ret = CkQualEcnum(*(*cur), error_msgs, perform_corrections);
558  if (ret > retval) {
559  retval = ret;
560  }
561  break;
562  case eClass_exper:
563  ret = CkQualMatchToken(*(*cur), error_msgs, ParFlat_ExpString, sizeof(ParFlat_ExpString) / sizeof(ParFlat_ExpString[0]));
564  if (ret > retval) {
565  retval = ret;
566  }
567  break;
568  case eClass_token:
569  ret = CkQualTokenType(*(*cur), error_msgs, ParFlat_Stoken_type);
570  if (ret > retval) {
571  retval = ret;
572  }
573  break;
574  case eClass_int:
575  ret = CkQualTokenType(*(*cur), error_msgs, ParFlat_Integer_type);
576  if (ret > retval) {
577  retval = ret;
578  }
579  break;
580  case eClass_number:
581  ret = CkQualTokenType(*(*cur), error_msgs, ParFlat_Number_type);
582  if (ret > retval) {
583  retval = ret;
584  }
585  break;
586  case eClass_rpt:
587  ret = CkQualMatchToken(*(*cur), error_msgs, ParFlat_RptString, sizeof(ParFlat_RptString) / sizeof(ParFlat_RptString[0]));
588  if (ret > retval) {
589  retval = ret;
590  }
591  break;
592  case eClass_flabel_base:
593  ret = CkQualTokenType(*(*cur), error_msgs, ParFlat_Stoken_type);
594  if (ret > retval) {
595  retval = ret;
596  }
597  break;
599  ret = CkQualTokenType(*(*cur), error_msgs, ParFlat_Stoken_type);
600  if (ret > retval) {
601  retval = ret;
602  }
603  break;
604  case eClass_none:
605  if ((*cur)->IsSetVal() && ! (*cur)->GetVal().empty()) {
606  if (error_msgs) {
607  ErrPostEx(SEV_ERROR, ERR_QUALIFIER_Xtratext, "/%s=%s", qual_str.c_str(), (*cur)->GetVal().c_str());
608  }
609  retval = GB_FEAT_ERR_REPAIRABLE;
610  if (perform_corrections) {
611  (*cur)->ResetVal();
612  }
613  }
614  default:
615  break;
616  } /* switch */
617 
618  if (ret == GB_FEAT_ERR_DROP && perform_corrections)
619  cur = quals.erase(cur);
620  else
621  ++cur;
622  } /* check qual's value */
623  }
624 
625  return retval;
626 
627 } /* GBQualSemanticValid */
628 
629 
630 /*------------------------------ CkQualPosSeqaa() -------------------------*/
631 /***************************************************************************
632  * CkQualPosSeqaa: (called by CkQaulPosaa and ChQualSeqaa)
633  *
634  * -- format (...aa:amino_acid)
635  * -- example aa:Phe)
636  * -Karl 1/28/94
637  ****************************************************************************/
638 
639 static int CkQualPosSeqaa(CGb_qual& cur, bool error_msgs, string& aa, const Char* eptr)
640 {
641  const Char* str;
642  int retval = GB_FEAT_ERR_NONE;
643 
645 
646  string caa = aa;
647 
648  size_t comma = caa.find(',');
649  if (comma != string::npos) {
650  caa = caa.substr(0, comma);
651  }
652 
653  if (aa == "OTHER" || CCleanup::ValidAminoAcid(caa) != 'X') {
654  str = eptr;
655 
656  while (*str != '\0' && (*str == ' ' || *str == ')'))
657  str++;
658 
659  if (*str == '\0') {
660  return retval; /* successful, format ok return */
661  } else {
662  if (error_msgs) {
663  ErrPostEx(SEV_ERROR, ERR_QUALIFIER_AA, "Extra text after end /%s=%s", cur.GetQual().c_str(), cur.GetVal().c_str());
664  }
665  retval = GB_FEAT_ERR_DROP;
666  }
667  } else {
668  if (error_msgs) {
669  ErrPostEx(SEV_ERROR, ERR_QUALIFIER_AA, "Bad aa abbreviation<%s>, /%s=%s", aa.c_str(), cur.GetQual().c_str(), cur.GetVal().c_str());
670  }
671  retval = GB_FEAT_ERR_DROP;
672  }
673 
674  return retval;
675 }
676 
677 
678 /*------------------------------ CkQualPosaa() -------------------------*/
679 /***************************************************************************
680  * CkQualPosaa:
681  *
682  * -- format (pos:base_range, aa:amino_acid)
683  * -- example /anticodon=(pos:34..36,aa:Phe)
684  * /anticodon=(pos: 34..36, aa: Phe)
685  * 10-12-93
686  ****************************************************************************/
687 static int CkQualPosaa(CGb_qual& cur, bool error_msgs)
688 {
689  const Char* eptr;
690  int retval = GB_FEAT_ERR_NONE;
691 
692  const Char* str = cur.GetVal().c_str();
693 
694  if (StringEquNI(str, "(pos:", 5)) {
695  str += 5;
696 
697  while (*str == ' ')
698  ++str;
699 
700  /*---I expect that we maight need to allow blanks here,
701  but not now... -Karl 1/28/94 */
702  if ((eptr = StringChr(str, ','))) {
703  while (str != eptr && (isdigit(*str) || *str == '.'))
704  str++;
705 
706  if (str == eptr) {
707  while (*str != '\0' && (*str == ',' || *str == ' '))
708  str++;
709 
710  if (StringEquNI(str, "aa:", 3)) {
711  str += 3;
712 
713  while (*str == ' ')
714  ++str;
715 
716  if ((eptr = StringChr(str, ')'))) {
717  string aa(str, eptr);
718  retval = CkQualPosSeqaa(cur, error_msgs, aa, eptr);
719  }
720  } /* if, aa: */ else {
721  if (error_msgs) {
722  ErrPostEx(SEV_ERROR, ERR_QUALIFIER_AA, "Missing aa: /%s=%s", cur.GetQual().c_str(), cur.GetVal().c_str());
723  }
724  retval = GB_FEAT_ERR_DROP;
725  }
726  }
727  } else {
728  if (error_msgs) {
729  ErrPostEx(SEV_ERROR, ERR_QUALIFIER_SeqPosComma, "Missing \',\' /%s=%s", cur.GetQual().c_str(), cur.GetVal().c_str());
730  /* ) match */
731  }
732  retval = GB_FEAT_ERR_DROP;
733  }
734  } /* if, (pos: */ else {
735  if (error_msgs) {
736  ErrPostEx(SEV_ERROR, ERR_QUALIFIER_Pos, "Missing (pos: /%s=%s", cur.GetQual().c_str(), cur.GetVal().c_str());
737  /* ) match */
738  }
739  retval = GB_FEAT_ERR_DROP;
740  }
741 
742  return retval;
743 
744 } /* CkQualPosaa */
745 
746 /*------------------------------ CkQualNote() --------------------------*/
747 /***************************************************************************
748 * CkQualNote:
749 * -- example: testfile gbp63.seq gbp88.seq, gbp76.seq
750 * /bound_moiety="repressor"
751 * /note="Dinucleotide repeat, polymorphic among these rat
752  strains:LOU/N>F344/N=BUF/N=MNR/N=WBB1/N=WBB2/N=MR/N=LER/N=ACI/N=SR/Jr=
753  SHR/N=WKY/N>BN/SsN=LEW/N (the size of the allelesindicated)."
754 * /note="guanine nucleotide-binding protein /hgml-locus_uid='LJ0088P'"
755 * /note=" /map='6p21.3' /hgml_locus_uid='LU0011B'"
756 *
757 * -- embedded qualifer
758 * -- convert all double quotes to single qutoes
759 * (this is unnecessary for the flat2asn parser program, because
760 * it only grep first close double quote when "ParseQualifiers" routine
761 * build GBQualPtr link list, but it would have post out message if
762 * any data was truncated) (I add the conversion because someone may
763 * use the routine which parsing the string different from the way I did)
764 * -- convert the '/' characters at the start of the embedded-qualifier
765 * token to '_'
766 * 12-20-93
767 ****************************************************************************/
768 static int CkQualNote(CGb_qual& cur, bool error_msgs, bool perform_corrections)
769 {
770 
771  bool has_embedded = false;
772  int retval;
773 
774  retval = CkQualText(cur, &has_embedded, true, error_msgs, perform_corrections);
775 
776  if (has_embedded) {
777 
778  string val_str = cur.GetVal();
779  std::replace(val_str.begin(), val_str.end(), '\"', '\'');
780  cur.SetVal(val_str);
781  }
782 
783  return retval;
784 
785 } /* CkQualNote */
786 
787 /*----------------------- ScanEmbedQual() -----------------------------*/
788 /****************************************************************************
789  * ScanEmbedQual:
790  * -- retun NULL if no embedded qualifiers found; otherwise, return the
791  * embedded qualifier.
792  * -- scan embedded valid qualifier
793  * 6-29-93
794  *****************************************************************************/
795 static bool ScanEmbedQual(const Char* value)
796 {
797  const Char* bptr;
798  const Char* ptr;
799 
800  if (value) {
801  for (bptr = value; *bptr != '\0';) {
802  for (; *bptr != '/' && *bptr != '\0'; bptr++)
803  continue;
804 
805  if (*bptr == '/') {
806  for (++bptr, ptr = bptr; *bptr != '=' && *bptr != ' ' && *bptr != '\0'; bptr++)
807  continue;
808 
809  string qual(ptr, bptr);
811  return true;
812  }
813  } /* for */
814  }
815 
816  return false;
817 
818 } /* ScanEmbedQual */
819 
820 /*------------------------------ CkQualText() -------------------------*/
821 /***************************************************************************
822  * CkQualText:
823  * -- return error severity
824  * -- also check if embedded qualifier
825  * -- format "text"
826  * if called from /note, ="" will cause qualifier to be dropped.
827  * all others no error, all other, if no qualifier, will add "" value
828  ****************************************************************************/
829 static int CkQualText(CGb_qual& cur,
830  bool* has_embedded,
831  bool from_note,
832  bool error_msgs,
833  bool perform_corrections)
834 {
835  const Char* bptr;
836  const Char* eptr;
837 
838  int retval = GB_FEAT_ERR_NONE;
839 
840  if (has_embedded) {
841  *has_embedded = false;
842  }
843  if (! cur.IsSetVal()) {
844  if (from_note) {
845  if (error_msgs) {
846  ErrPostEx(SEV_ERROR, ERR_QUALIFIER_EmptyNote, "/note with no text ");
847  }
848  return GB_FEAT_ERR_DROP;
849  } else {
850  retval = GB_FEAT_ERR_SILENT;
851  if (perform_corrections) {
852  cur.SetVal("\"\""); /* yup, a "" string is legal */
853  } else {
854  return retval;
855  }
856  }
857  }
858 
859  const Char* str = cur.GetVal().c_str();
860  while (*str != '\0' && (*str == ' ' || *str == '\"')) {
861  /* open double quote */
862  str++;
863  if (*(str - 1) == '\"') {
864  break; /* so does not continue through a "" string */
865  }
866  }
867  /* find first close double quote */
868  for (bptr = str; *str != '\0' && *str != '\"'; str++)
869  continue;
870  eptr = str;
871 
872  while (*str != '\0' && (*str == ' ' || *str == '\"'))
873  str++;
874 
875  if (*str != '\0') {
876  /* extra stuff is already rm in ParseQualifiers(). Tatiana*/
877  /* extra stuff, if perform corrections, remove it */
878  /* ERROR here sets retval*/
879  }
880 
881  string value(bptr, eptr);
882  /* Some check must be done for illegal characters in gbpq->val
883  for (s = value; *s != '\0'; s++) {
884  if (!IS_WHITESP(*s) && !IS_ALPHANUM(*s) && *s != '\"') {
885  if (error_msgs){
886  ErrPostEx(SEV_WARNING, ERR_QUALIFIER_IllegalCharacter,
887  "illegal char [%c] used in qualifier %s", s, gbqp ->qual);
888  }
889  return (retval > GB_FEAT_ERR_REPAIRABLE) ? retval : GB_FEAT_ERR_REPAIRABLE;
890  }
891  }
892  */
893 
894  return retval;
895 } /* CkQualText */
896 
897 /*------------------------- CkQualSeqaa() --------------------------*/
898 /***************************************************************************
899  * CkQualSeqaa:
900  * -- format (seq:"codon-sequence", aa:amino_acid)
901  * -- example /codon=(seq:"ttt",aa:Leu)
902  * /codon=(seq: "ttt", aa: Leu )
903  * 6-29-93
904  ***************************************************************************/
905 static int CkQualSeqaa(CGb_qual& cur, bool error_msgs)
906 {
907  int retval = GB_FEAT_ERR_NONE;
908 
909  const Char* str = cur.GetVal().c_str();
910  const Char* eptr = nullptr;
911 
912  if (StringEquNI(str, "(seq:", 5)) {
913  str += 5;
914 
915  while (*str == ' ')
916  ++str;
917 
918  if ((eptr = StringChr(str, ','))) {
919  while (str != eptr)
920  str++;
921 
922  while (*str != '\0' && (*str == ',' || *str == ' '))
923  str++;
924 
925  if (StringEquNI(str, "aa:", 3)) {
926  str += 3;
927 
928  while (*str == ' ')
929  ++str;
930 
931  if ((eptr = StringChr(str, ')'))) {
932  string aa(str, eptr);
933  retval = CkQualPosSeqaa(cur, error_msgs, aa, eptr);
934  }
935  } /* if, aa: */ else {
936  if (error_msgs) {
937  ErrPostEx(SEV_ERROR, ERR_QUALIFIER_AA, "Missing aa: /%s=%s", cur.GetQual().c_str(), cur.GetVal().c_str());
938  }
939  retval = GB_FEAT_ERR_DROP;
940  }
941  } else {
942  if (error_msgs) {
943  ErrPostEx(SEV_ERROR, ERR_QUALIFIER_SeqPosComma, "Missing \',\' /%s=%s", cur.GetQual().c_str(), cur.GetVal().c_str());
944  /* ) match */
945  }
946  retval = GB_FEAT_ERR_DROP;
947  }
948  } /* if, (seq: */ else {
949 
950 
951  if (error_msgs) {
952  ErrPostEx(SEV_ERROR, ERR_QUALIFIER_Seq, "Missing (seq: /%s=%s", cur.GetQual().c_str(), cur.GetVal().c_str());
953  /* ) match */
954  }
955  retval = GB_FEAT_ERR_DROP;
956  }
957 
958  return retval;
959 
960 } /* CkQualSeqaa */
961 
962 /*------------------------- () -------------------------*/
963 /*****************************************************************************
964  * CkQualMatchToken:
965  * 6-29-93
966  *****************************************************************************/
967 static int CkQualMatchToken(CGb_qual& cur, bool error_msgs, const Char* array_string[], Int2 totalstr)
968 {
969  const Char* bptr;
970  const Char* eptr;
971  const Char* str;
972 
973  int retval = GB_FEAT_ERR_NONE;
974 
975  if (! cur.IsSetVal()) {
976  if (error_msgs) {
977  ErrPostEx(SEV_ERROR, ERR_QUALIFIER_InvalidDataFormat, "NULL value for (%s)", cur.GetQual().c_str());
978  }
979  return GB_FEAT_ERR_DROP;
980  }
981  str = cur.GetVal().c_str();
982 
983  for (bptr = str; *str != '\0' && *str != ' '; str++)
984  continue;
985  eptr = str;
986 
987  while (*str != '\0' && *str == ' ')
988  str++;
989 
990  if (*str == '\0') {
991  string msg(bptr, eptr);
992  bool found = false;
993  for (Int2 i = 0; i < totalstr; ++i) {
994  if (NStr::EqualNocase(msg, array_string[i])) {
995  found = true;
996  break;
997  }
998  }
999 
1000  if (! found) {
1001  if (error_msgs) {
1002  ErrPostEx(SEV_ERROR, ERR_QUALIFIER_InvalidDataFormat, "Value not in list of legal values /%s=%s", cur.GetQual().c_str(), cur.GetVal().c_str());
1003  }
1004  retval = GB_FEAT_ERR_DROP;
1005  }
1006  } else {
1007  if (error_msgs) {
1008  ErrPostEx(SEV_ERROR, ERR_QUALIFIER_Too_many_tokens, "/%s=%s", cur.GetQual().c_str(), cur.GetVal().c_str());
1009  }
1010  retval = GB_FEAT_ERR_DROP;
1011  }
1012 
1013  return retval;
1014 
1015 } /* CkQualMatchToken */
1016 
1017 /*------------------------- CkQualEcnum() ---------------------------*/
1018 /***************************************************************************
1019  * CkQualEcnum:
1020  * -- Ec_num has text format,
1021  * but the text only allow digits, period, and hyphen (-)
1022  * 12-10-93
1023  ****************************************************************************/
1024 static int CkQualEcnum(CGb_qual& cur, bool error_msgs, bool perform_corrections)
1025 {
1026  const Char* str;
1027  int retval = GB_FEAT_ERR_NONE;
1028 
1029 
1030  retval = CkQualText(cur, nullptr, false, error_msgs, perform_corrections);
1031  if (retval == GB_FEAT_ERR_NONE) {
1032 
1033  str = cur.GetVal().c_str();
1034  /* open double quote */
1035  while (*str != '\0' && (*str == ' ' || *str == '\"'))
1036  str++;
1037 
1038  for (; *str != '\0' && *str != '\"'; str++)
1039  if (! isdigit(*str) && *str != '.' && *str != '-' && *str != 'n') {
1040  if (error_msgs) {
1041  ErrPostEx(SEV_ERROR, ERR_QUALIFIER_BadECnum, "At <%c>(%d) /%s=%s", *str, (int)*str, cur.GetQual().c_str(), cur.GetVal().c_str());
1042  }
1043  retval = GB_FEAT_ERR_DROP;
1044  break;
1045  }
1046  }
1047 
1048  return retval;
1049 
1050 } /* CkQualEcnum */
1051 
1052 /*------------------------- CkQualSite() --------------------------*/
1053 /***************************************************************************
1054  * CkQualSite:
1055  * -- format (5'site:bool, 3'site:bool)
1056  * -- example /cons_splice=(5'site:YES, 3'site:NO)
1057  * 6-29-93
1058  ***************************************************************************/
1059 static int CkQualSite(CGb_qual& cur, bool error_msgs)
1060 {
1061  int retval = GB_FEAT_ERR_NONE;
1062  const Char* bptr;
1063  const Char* str;
1064 
1065  bool ok = false;
1066  const Char* yes_or_no = "not \'YES\', \'NO\' or \'ABSENT\'";
1067 
1068  str = cur.GetVal().c_str();
1069  if (StringEquNI(str, "(5'site:", 8)) {
1070  bptr = str;
1071  str += 8;
1072 
1073  if (StringEquNI(str, "YES", 3) || StringEquNI(str, "NO", 2) ||
1074  StringEquNI(str, "ABSENT", 6)) {
1075 
1076  if (StringEquNI(str, "YES", 3))
1077  str += 3;
1078  else if (StringEquNI(str, "NO", 2))
1079  str += 2;
1080  else
1081  str += 6;
1082 
1083  for (; *str == ' '; str++)
1084  ;
1085  for (; *str == ','; str++)
1086  ;
1087  for (; *str == ' '; str++)
1088  ;
1089 
1090 
1091  if (StringEquNI(str, "3'site:", 7)) {
1092  str += 7;
1093 
1094  if (StringEquNI(str, "YES", 3) ||
1095  StringEquNI(str, "NO", 2) ||
1096  StringEquNI(str, "ABSENT", 6)) {
1097  if (StringEquNI(str, "YES", 3))
1098  str += 3;
1099  else if (StringEquNI(str, "NO", 2))
1100  str += 2;
1101  else
1102  str += 6;
1103 
1104  if (*str == ')') {
1105 
1106  while (*str != '\0' && (*str == ' ' || *str == ')'))
1107  str++;
1108 
1109  if (*str == '\0')
1110  ok = true;
1111  else {
1112  bptr = "extra characters";
1113  }
1114 
1115  } /* if, ")" */ else {
1116  }
1117  } /* if, yes or no */ else {
1118  bptr = yes_or_no;
1119  }
1120  } /* if, 3'site */ else {
1121  bptr = "3\' site";
1122  }
1123  } /* if, yes or no */ else {
1124  bptr = yes_or_no;
1125  }
1126  } /* if, 5'site */ else {
1127  bptr = "5\' site";
1128  }
1129 
1130  if (! ok) {
1131  if (error_msgs) {
1132  ErrPostEx(SEV_ERROR, ERR_QUALIFIER_Cons_splice, "%s /%s=%s", bptr, cur.GetQual().c_str(), cur.GetVal().c_str());
1133  }
1134  retval = GB_FEAT_ERR_DROP;
1135  }
1136  return retval;
1137 
1138 } /* CkQualSite */
1139 
1140 /*------------------------- CkQualTokenType() --------------------------*/
1141 /***************************************************************************
1142  * CkQualTokenType:
1143  * -- format single token
1144  * -- example ParFlat_Stoken_type /label=Albl_exonl /mod_base=m5c
1145  * ParFlat_BracketInt_type /citation=[3] or /citation= ([1],[3])
1146  * ParFlat_Integer_type /transl_table=4
1147  * ParFlat_Number_type /number=4b
1148  * -- not implemented yet, treat as ParFlat_Stoken_type:
1149  * -- feature_label or base_range
1150  * /rpt_unit=Alu_rpt1 /rpt_unit=202..245
1151  * -- Accession-number:feature-name or
1152  * Database_name:Acc_number:feature_label
1153  * /usedin=X10087:proteinx
1154  * 10-12-93
1155  ***************************************************************************/
1156 static int CkQualTokenType(CGb_qual& cur, bool error_msgs, Uint1 type)
1157 {
1158  const Char* bptr;
1159  const Char* eptr;
1160  const Char* str;
1161 
1162  bool token_there = false;
1163  int retval = GB_FEAT_ERR_NONE;
1164 
1165  str = cur.IsSetVal() ? cur.GetVal().c_str() : nullptr;
1166 
1167  if (str)
1168  if (*str != '\0') {
1169  token_there = true;
1170  }
1171  if (! token_there) {
1172  if (error_msgs) {
1173  ErrPostEx(SEV_ERROR, ERR_QUALIFIER_InvalidDataFormat, "Missing value /%s=...", cur.GetQual().c_str());
1174  }
1175  retval = GB_FEAT_ERR_DROP;
1176  } else {
1177  /* token there */
1178  for (bptr = str; *str != '\0' && *str != ' '; str++)
1179  continue;
1180  eptr = str;
1181 
1182  while (*str != '\0' && *str == ' ')
1183  str++;
1184 
1185  if (*str == '\0') {
1186  /*------single token found ----*/
1187  string token(bptr, eptr);
1188 
1189  switch (type) {
1191  /*-------this can be made to be much more rigorous --Karl ---*/
1192  str = CkBracketType(token.c_str());
1193  break;
1194  case ParFlat_Integer_type:
1195  for (str = token.c_str(); *str != '\0' && isdigit(*str); str++)
1196  continue;
1197  if (*str == '\0') {
1198  str = nullptr;
1199  }
1200  break;
1201  case ParFlat_Stoken_type:
1202  str = CkLabelType(token.c_str());
1203  break;
1204  case ParFlat_Number_type:
1205  str = CkNumberType(token.c_str());
1206  break;
1207  default:
1208  str = nullptr;
1209  break;
1210  }
1211 
1212  if (str) {
1213 #if 0
1214  switch (type) {
1216  bptr = "Invalid [integer] format";
1217  break;
1218  case ParFlat_Integer_type:
1219  bptr = "Not an integer number";
1220  break;
1221  case ParFlat_Stoken_type:
1222  bptr = "Invalid format";
1223  break;
1224  /*-- logically can not happen, as coded now -Karl 1/31/94 --*/
1225  default:
1226  bptr = "Bad qualifier value";
1227  break;
1228  }
1229 #endif
1230  if (error_msgs) {
1231  ErrPostEx(SEV_ERROR, ERR_QUALIFIER_InvalidDataFormat, "%s=%s, at %s", cur.GetQual().c_str(), cur.GetVal().c_str(), str);
1232  }
1233  retval = GB_FEAT_ERR_DROP;
1234  }
1235  } else {
1236  /*-- more than a single token found ---*/
1237  if (error_msgs) {
1238  ErrPostEx(SEV_ERROR, ERR_QUALIFIER_Xtratext, "extra text found /%s=%s, at %s", cur.GetQual().c_str(), cur.GetVal().c_str(), str);
1239  }
1240  retval = GB_FEAT_ERR_DROP;
1241  }
1242  } /* token there */
1243 
1244  return retval;
1245 
1246 } /* CkQualTokenType */
1247 
1248 
1249 /*------------------------ CkBracketType() --------------------*/
1250 /*****************************************************************************
1251  * CkBracketType:
1252  * checks /citation=([1],[3])
1253  * May be we should check for only single value here like
1254  * /citation=[digit]
1255  * -Tatiana 1/28/95
1256  ******************************************************************************/
1257 static const Char* CkBracketType(const Char* str)
1258 {
1259  if (! str)
1260  return "NULL value";
1261  if (*str == '[') {
1262  str++;
1263  if (! isdigit(*str)) {
1264  return str;
1265  } else {
1266  while (isdigit(*str)) {
1267  str++;
1268  }
1269  if (*str != ']') {
1270  return str;
1271  }
1272  str++;
1273  if (*str != '\0') {
1274  return str;
1275  }
1276  return nullptr;
1277  }
1278  } else {
1279  return str;
1280  }
1281 }
1282 
1283 /*------------------------ CkNumberType() --------------------*/
1284 /*****************************************************************************
1285  * CkNumberType:
1286  * checks /number=single_token - numbers and letters
1287  * /number=4 or /number=6b
1288  * -Tatiana 2/1/00
1289  ******************************************************************************/
1290 static const Char* CkNumberType(const Char* str)
1291 {
1292  for (; *str != '\0' && ! isalnum(*str); str++)
1293  continue;
1294  if (*str != '\0') {
1295  return nullptr;
1296  }
1297  return str;
1298 }
1299 
1300 /*------------------------ CkLabelType() --------------------*/
1301 /*****************************************************************************
1302  * CkLabelType:
1303  * checks /label=,feature_label> or /label=<base_range>
1304  * -Tatiana 1/28/95
1305  ******************************************************************************/
1306 static const Char* CkLabelType(const Char* str)
1307 {
1308  bool range = true, label = true;
1309  const Char* bptr;
1310 
1311  if (isdigit(*str)) {
1312  for (; isdigit(*str); str++)
1313  continue;
1314  if (*str == '.' && *(str + 1) == '.') {
1315  str += 2;
1316  if (! isdigit(*str)) {
1317  range = false;
1318  } else {
1319  while (isdigit(*str)) {
1320  str++;
1321  }
1322  }
1323  if (*str != '\0') {
1324  range = false;
1325  }
1326  } else {
1327  range = false;
1328  }
1329  }
1330  if (! range) {
1331  bptr = str;
1332  for (; *str != '\0' && ! isalpha(*str); str++)
1333  continue;
1334  if (*str == '\0') {
1335  label = false; /* must be at least one letter */
1336  }
1337  for (str = bptr; (*str != '\0' && isalpha(*str)) || isdigit(*str) || *str == '-' || *str == '_' || *str == '\'' || *str == '*';
1338  str++)
1339  continue;
1340  if (*str != '\0') {
1341  label = false;
1342  }
1343  }
1344  if (range || label) {
1345  return nullptr;
1346  } else {
1347  return str;
1348  }
1349 }
1350 
static char ValidAminoAcid(string_view abbrev)
Definition: cleanup.cpp:4974
@Gb_qual.hpp User-defined methods of the data storage class.
Definition: Gb_qual.hpp:61
bool IsLegalQualifier(EQualifier qual) const
Test wheather a certain qualifier is legal for the feature.
EQualifier
List of available qualifiers for feature keys.
@ eQual_environmental_sample
@ eQual_recombination_class
@ eQual_UniProtKB_evidence
@ eQual_culture_collection
@ eQual_ribosomal_slippage
@ eQual_mobile_element_type
@ eQual_artificial_location
const TQualifiers & GetMandatoryQualifiers(void) const
Get the list of all mandatory qualifiers for the feature.
static EQualifier GetQualifierType(CTempString qual)
convert qual string to enumerated value
static CTempString GetQualifierAsString(EQualifier qual)
Convert a qualifier from an enumerated value to a string representation or empty if not found.
const_iterator end() const
Definition: map.hpp:152
const_iterator find(const key_type &key) const
Definition: map.hpp:153
Definition: map.hpp:338
bool StringEquNI(const char *s1, const char *s2, size_t n)
Definition: ftacpp.hpp:131
static const char * str(char *buf, int n)
Definition: stats.c:84
int offset
Definition: replacements.h:160
#define SEV_WARNING
Definition: gicache.c:90
#define SEV_ERROR
Definition: gicache.c:91
#define ErrPostStr
Definition: ncbierr.hpp:68
#define StringChr
Definition: ncbistr.hpp:317
#define ErrPostEx(sev, err_code,...)
Definition: ncbierr.hpp:78
uint8_t Uint1
1-byte (8-bit) unsigned integer
Definition: ncbitype.h:99
int16_t Int2
2-byte (16-bit) signed integer
Definition: ncbitype.h:100
char Char
Alias for char.
Definition: ncbitype.h:93
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
static int CompareNocase(const CTempString s1, SIZE_TYPE pos, SIZE_TYPE n, const char *s2)
Case-insensitive compare of a substring with another string.
Definition: ncbistr.cpp:219
static void TruncateSpacesInPlace(string &str, ETrunc where=eTrunc_Both)
Truncate spaces in a string (in-place)
Definition: ncbistr.cpp:3201
static bool EqualNocase(const CTempString s1, SIZE_TYPE pos, SIZE_TYPE n, const char *s2)
Case-insensitive equality of a substring with another string.
Definition: ncbistr.hpp:5353
@ eTrunc_End
Truncate trailing spaces only.
Definition: ncbistr.hpp:2241
static const char label[]
const TVal & GetVal(void) const
Get the Val member data.
Definition: Gb_qual_.hpp:259
void SetQual(const TQual &value)
Assign a value to Qual data member.
Definition: Gb_qual_.hpp:221
bool IsSetQual(void) const
Check if a value has been assigned to Qual data member.
Definition: Gb_qual_.hpp:200
void SetVal(const TVal &value)
Assign a value to Val data member.
Definition: Gb_qual_.hpp:268
const TQual & GetQual(void) const
Get the Qual member data.
Definition: Gb_qual_.hpp:212
bool IsSetVal(void) const
Check if a value has been assigned to Val data member.
Definition: Gb_qual_.hpp:247
int i
range(_Ty, _Ty) -> range< _Ty >
constexpr bool empty(list< Ts... >) noexcept
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1227
int isalpha(Uchar c)
Definition: ncbictype.hpp:61
int isalnum(Uchar c)
Definition: ncbictype.hpp:62
int isdigit(Uchar c)
Definition: ncbictype.hpp:64
Definition: type.c:6
#define ParFlat_Stoken_type
Definition: xgbfeat.cpp:59
#define ERR_QUALIFIER_Pos
Definition: xgbfeat.cpp:50
USING_SCOPE(objects)
static int CkQualMatchToken(CGb_qual &cur, bool error_msgs, const Char *array_string[], Int2 totalstr)
Definition: xgbfeat.cpp:967
int XGBFeatKeyQualValid(CSeqFeatData::ESubtype subtype, TQualVector &quals, bool error_msgs, bool perform_corrections)
Definition: xgbfeat.cpp:127
static int CkQualPosaa(CGb_qual &cur, bool error_msgs)
Definition: xgbfeat.cpp:687
#define ERR_QUALIFIER_MultiValue
Definition: xgbfeat.cpp:46
static const Char * CkNumberType(const Char *str)
Definition: xgbfeat.cpp:1290
static int CkQualPosSeqaa(CGb_qual &cur, bool error_msgs, string &aa, const Char *eptr)
Definition: xgbfeat.cpp:639
#define ERR_FEATURE_QualWrongThisFeat
Definition: xgbfeat.cpp:39
#define ERR_QUALIFIER_UnknownSpelling
Definition: xgbfeat.cpp:47
static int CkQualText(CGb_qual &cur, bool *has_embedded, bool from_note, bool error_msgs, bool perform_corrections)
Definition: xgbfeat.cpp:829
const Char * ParFlat_IntOrString[]
Definition: xgbfeat.cpp:442
#define ParFlat_Number_type
Definition: xgbfeat.cpp:62
const Char * ParFlat_LRBString[]
Definition: xgbfeat.cpp:444
#define ERR_QUALIFIER_SeqPosComma
Definition: xgbfeat.cpp:49
#define ParFlat_SPLIT_IGNORE
Definition: xgbfeat.cpp:93
static const Char * CkLabelType(const Char *str)
Definition: xgbfeat.cpp:1306
#define ERR_QUALIFIER_AA
Definition: xgbfeat.cpp:54
#define ERR_QUALIFIER_Too_many_tokens
Definition: xgbfeat.cpp:45
#define ERR_QUALIFIER_BadECnum
Definition: xgbfeat.cpp:56
static int CkQualSeqaa(CGb_qual &cur, bool error_msgs)
Definition: xgbfeat.cpp:905
#define ERR_FEATURE_MissManQual
Definition: xgbfeat.cpp:38
static ETokenClass GetQualifierClass(CSeqFeatData::EQualifier qual_type)
Definition: xgbfeat.cpp:293
static Int2 GBQualSplit(const Char *qual)
Definition: xgbfeat.cpp:106
static int CkQualNote(CGb_qual &cur, bool error_msgs, bool perform_corrections)
Definition: xgbfeat.cpp:768
#define ParFlat_Integer_type
Definition: xgbfeat.cpp:61
#define ERR_QUALIFIER_EmptyNote
Definition: xgbfeat.cpp:51
static int CkQualEcnum(CGb_qual &cur, bool error_msgs, bool perform_corrections)
Definition: xgbfeat.cpp:1024
const Char * GBQual_names_split_ignore[4]
Definition: xgbfeat.cpp:94
ETokenClass
Definition: xgbfeat.cpp:272
@ eClass_int
Definition: xgbfeat.cpp:284
@ eClass_unknown
Definition: xgbfeat.cpp:290
@ eClass_token
Definition: xgbfeat.cpp:283
@ eClass_seq_aa
Definition: xgbfeat.cpp:276
@ eClass_pos_aa
Definition: xgbfeat.cpp:273
@ eClass_L_R_B
Definition: xgbfeat.cpp:279
@ eClass_rpt
Definition: xgbfeat.cpp:285
@ eClass_flabel_base
Definition: xgbfeat.cpp:286
@ eClass_none
Definition: xgbfeat.cpp:282
@ eClass_ecnum
Definition: xgbfeat.cpp:280
@ eClass_int_or
Definition: xgbfeat.cpp:277
@ eClass_flabel_dbname
Definition: xgbfeat.cpp:287
@ eClass_text
Definition: xgbfeat.cpp:274
@ eClass_note
Definition: xgbfeat.cpp:288
@ eClass_site
Definition: xgbfeat.cpp:278
@ eClass_bracket_int
Definition: xgbfeat.cpp:275
@ eClass_exper
Definition: xgbfeat.cpp:281
@ eClass_number
Definition: xgbfeat.cpp:289
static const Char * CkBracketType(const Char *str)
Definition: xgbfeat.cpp:1257
static int CkQualTokenType(CGb_qual &cur, bool error_msgs, Uint1 type)
Definition: xgbfeat.cpp:1156
static bool ScanEmbedQual(const Char *value)
Definition: xgbfeat.cpp:795
#define ParFlat_BracketInt_type
Definition: xgbfeat.cpp:60
static const Char * this_module
Definition: xgbfeat.cpp:27
#define ERR_QUALIFIER_InvalidDataFormat
Definition: xgbfeat.cpp:44
const Char * ParFlat_RptString[]
Definition: xgbfeat.cpp:450
#define ERR_QUALIFIER_Seq
Definition: xgbfeat.cpp:55
static int GBQualSemanticValid(TQualVector &quals, bool error_msgs, bool perform_corrections)
Definition: xgbfeat.cpp:478
static int SplitMultiValQual(TQualVector &quals)
Definition: xgbfeat.cpp:221
static int CkQualSite(CGb_qual &cur, bool error_msgs)
Definition: xgbfeat.cpp:1059
#define ERR_QUALIFIER_Xtratext
Definition: xgbfeat.cpp:48
#define ERR_QUALIFIER_Cons_splice
Definition: xgbfeat.cpp:57
const Char * ParFlat_ExpString[]
Definition: xgbfeat.cpp:446
#define GB_FEAT_ERR_SILENT
Definition: xgbfeat.h:20
std::vector< CRef< objects::CGb_qual > > TQualVector
Definition: xgbfeat.h:12
#define GB_FEAT_ERR_NONE
Definition: xgbfeat.h:19
#define GB_FEAT_ERR_REPAIRABLE
Definition: xgbfeat.h:21
#define GB_FEAT_ERR_DROP
Definition: xgbfeat.h:22
Modified on Mon May 13 04:32:08 2024 by modify_doxy.py rev. 669887