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