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

Go to the SVN repository for this file.

1 /* $Id: xgbparint.cpp 101058 2023-10-24 13:28:57Z stakhovv $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * File Name: xgbparint.cpp
27  *
28  * Author: Alexey Dobronadezhdin (translated from gbparint.c made by Karl Sirotkin)
29  *
30  */
31 
32 #include <ncbi_pch.hpp>
33 
34 #include <corelib/ncbimisc.hpp>
40 #include "ftacpp.hpp"
41 #include "ftaerr.hpp"
42 #include "xgbparint.h"
43 
44 #ifdef THIS_FILE
45 # undef THIS_FILE
46 #endif
47 #define THIS_FILE "xgbparint.cpp"
48 
49 #define TAKE_FIRST 1
50 #define TAKE_SECOND 2
51 
54 
55 const char* seqlitdbtag = "SeqLit";
56 const char* unkseqlitdbtag = "UnkSeqLit";
57 
58 enum class ETokenType {
59  eUnknown,
60  eJoin,
61  eCompl,
62  eLeft,
63  eRight,
64  eCaret,
65  eDotDot,
66  eAccession,
67  eGt,
68  eLt,
69  eComma,
70  eNumber,
71  eOrder,
72  eSingleDot,
73  eGroup,
74  eOneOf,
75  eReplace,
76  eSites,
77  eString,
78  eOneOfNum,
79  eGap,
80  eUnkGap
81 };
82 
83 struct STokenInfo {
85  string data;
86 };
87 
88 using TTokens = list<STokenInfo>;
89 using TTokenIt = TTokens::iterator;
90 using TTokenConstIt = TTokens::const_iterator;
91 
92 
93 /*--------- do_xgbparse_error () ---------------*/
94 
95 #define ERR_FEATURE_LocationParsing_validatr 1, 5
96 
97 static void do_xgbparse_error(const char* msg, const char* details)
98 {
99  string errmsg = string(msg) + " at " + string(details);
100  Nlm_ErrSetContext("validatr", __FILE__, __LINE__);
102 }
103 
106 static void* xgbparse_range_data = nullptr;
107 
108 /*----------- xinstall_gbparse_error_handler ()-------------*/
109 
111 {
112  Err_func = new_func;
113 }
114 
115 /*----------- xinstall_gbparse_range_func ()-------------*/
116 
118 {
119  Range_func = new_func;
120  xgbparse_range_data = data;
121 }
122 
123 /*------ xgbparse_point ()----*/
125 {
126  string temp;
127  auto end_it = next(current);
128  for (auto it = head; it != end_it; ++it) {
129  switch (it->choice) {
130  case ETokenType::eJoin:
131  temp += "join";
132  break;
133  case ETokenType::eCompl:
134  temp += "complement";
135  break;
136  case ETokenType::eLeft:
137  temp += "(";
138  break;
139  case ETokenType::eRight:
140  temp += ")";
141  break;
142  case ETokenType::eCaret:
143  temp += "^";
144  break;
145  case ETokenType::eDotDot:
146  temp += "..";
147  break;
149  case ETokenType::eNumber:
150  case ETokenType::eString:
151  temp += it->data;
152  break;
153  case ETokenType::eGt:
154  temp += ">";
155  break;
156  case ETokenType::eLt:
157  temp += "<";
158  break;
159  case ETokenType::eComma:
160  temp += ",";
161  break;
162  case ETokenType::eOrder:
163  temp += "order";
164  break;
166  temp += ".";
167  break;
168  case ETokenType::eGroup:
169  temp += "group";
170  break;
171  case ETokenType::eOneOf:
173  temp += "one-of";
174  break;
176  temp += "replace";
177  break;
179  default:
180  break;
181  }
182  temp += " ";
183  if (it == current)
184  break;
185  }
186 
187  return temp;
188 }
189 
190 
191 static void xgbparse_error(const char* front, TTokenConstIt head, TTokenConstIt current)
192 {
193  string details = xgbparse_point(head, current);
194  Err_func(front, details.c_str());
195 }
196 
197 
198 static void xgbparse_error(const char* front, const TTokens& tokens, TTokenConstIt current)
199 {
200  xgbparse_error(front, begin(tokens), current);
201 }
202 
203 
204 /*------------------ xgbcheck_range()-------------*/
205 static void xgbcheck_range(TSeqPos num, const CSeq_id& id, bool& keep_rawPt, int& numErrors, const TTokens& tokens, TTokenConstIt current)
206 {
207  if (! Range_func) {
208  return;
209  }
210 
211  const auto len = (*Range_func)(xgbparse_range_data, id);
212  if (len != -1 && num >= (Uint4)len) {
213  xgbparse_error("range error", tokens, current);
214  keep_rawPt = true;
215  ++numErrors;
216  }
217 }
218 
219 
220 /*--------- xfind_one_of_num()------------*/
221 /*
222 Consider these for locations:
223  misc_signal join(57..one-of(67,75),one-of(100,110)..200)
224  misc_signal join(57..one-of(67,75),one-of(100,110..120),200)
225  misc_signal join(57..one-of(67,75),one-of(100,110..115)..200)
226 
227  misc_signal join(57..one-of(67,75),one-of(100,110),200)
228 
229 In the first three, the one-of() is functioning as an alternative set
230 of numbers, in the last, as an alternative set of locations (even
231 though the locations are points).
232 [yes the one-of(100,110..115).. is illegal]
233 
234  here is one more case:one-of(18,30)..470 so if the location
235  starts with a one-of, it also needs to be checked.
236 
237 To deal with this, the ETokenType::eOneOf token type will be changed
238 by the following function to ETokenType::eOneOfNum, in the three cases.
239 
240 note that this change is not necessary in this case:
241  join(100..200,300..one-of(400,500)), as after a ".." token,
242  it has to be a number.
243 
244 */
245 
246 static void xfind_one_of_num(list<STokenInfo>& tokens)
247 {
248  if (tokens.size() == 1) {
249  return;
250  }
251  auto current_it = begin(tokens);
252  if (current_it->choice == ETokenType::eOneOf) {
253  for (auto scanner_it = next(current_it);
254  scanner_it != end(tokens);
255  ++scanner_it) {
256  if (scanner_it->choice == ETokenType::eRight) {
257  ++scanner_it;
258  if (scanner_it != end(tokens) &&
259  scanner_it->choice == ETokenType::eDotDot) {
260  current_it->choice = ETokenType::eOneOfNum;
261  }
262  break;
263  }
264  }
265  }
266 
267  for (auto current_it = begin(tokens);
268  current_it != end(tokens);
269  ++current_it) {
270  if (current_it->choice == ETokenType::eComma ||
271  current_it->choice == ETokenType::eLeft) {
272  auto scanner_it = next(current_it);
273  if (scanner_it != end(tokens)) {
274  if (scanner_it->choice == ETokenType::eOneOf) {
275  ++scanner_it;
276  while (scanner_it != end(tokens)) {
277  if (scanner_it->choice == ETokenType::eRight) {
278  ++scanner_it;
279  if (scanner_it != end(tokens) &&
280  scanner_it->choice == ETokenType::eDotDot) {
281  current_it->choice = ETokenType::eOneOfNum;
282  }
283  break;
284  }
285  ++scanner_it;
286  }
287  }
288  }
289  }
290  }
291 }
292 
293 
294 static void xlex_error_func(const char* msg,
295  const string& line,
296  const int current_col)
297 {
298  string temp_string = line.substr(0, current_col + 1) + " ";
299  Err_func(msg, temp_string.c_str());
300 }
301 
302 
303 static unsigned advance_to(const char c, unsigned current_pos, const string& line)
304 {
305  int pos = current_pos;
306  while (pos < line.size()) {
307  if (line[pos] == c) {
308  return pos - 1;
309  }
310  ++pos;
311  }
312  return pos - 1;
313 }
314 
315 
316 static size_t sParseAccessionPrefix(const CTempString& accession)
317 {
318  if (accession.empty()) {
319  return 0;
320  }
321 
322  auto IsAlpha = [](char c) { return isalpha(c); };
323 
324  auto it = find_if_not(begin(accession),
325  end(accession),
326  IsAlpha);
327 
328 
329  if (it == end(accession)) {
330  return 1;
331  }
332 
333  auto prefix_length = distance(begin(accession), it);
334  if (*it == '_') {
335  if (prefix_length != 2) {
336  return 1;
337  }
338  ++it;
339  it = find_if_not(it, end(accession), IsAlpha);
340  if (it == end(accession)) {
341  return 1;
342  }
343  prefix_length = distance(begin(accession), it);
344  if (prefix_length == 3 || prefix_length == 7) {
345  return prefix_length;
346  }
347  return 1;
348  } else if (accession.size() >= 3 &&
349  isdigit(accession[0]) &&
350  isdigit(accession[1]) &&
351  accession[2] == 'S') {
352  return 7;
353  }
354 
355  if (prefix_length == 1 ||
356  prefix_length == 2 ||
357  prefix_length == 4 ||
358  prefix_length == 6) {
359  return prefix_length;
360  }
361 
362  return 1;
363 }
364 
365 
366 static int sGetAccession(string& accession, unsigned int& current_col, const string& line, bool accver)
367 {
368  const auto length = line.size();
369  CTempString tempString(line.c_str() + current_col, length - current_col);
370  auto prefixLength = sParseAccessionPrefix(tempString);
371  size_t accessionLength = prefixLength;
372 
373  tempString = tempString.substr(prefixLength);
374  auto notDigitPos = tempString.find_first_not_of("0123456789");
375  if (notDigitPos != NPOS) {
376  accessionLength += notDigitPos;
377  if (accver && tempString[notDigitPos] == '.') {
378  ++accessionLength;
379  if (tempString.size() > notDigitPos) {
380  tempString = tempString.substr(notDigitPos + 1);
381  notDigitPos = tempString.find_first_not_of("0123456789");
382  if (notDigitPos != NPOS) {
383  accessionLength += notDigitPos;
384  }
385  }
386  }
387  } else {
388  accessionLength = length - current_col;
389  }
390 
391  int retval = 0;
392  if (notDigitPos == NPOS || tempString[notDigitPos] != ':') {
393  xlex_error_func("ACCESSION missing \":\"", line, current_col);
394  ++retval;
395  --current_col;
396  }
397 
398  accession = string(line.c_str() + current_col, accessionLength);
399  current_col += accessionLength;
400  return retval;
401 }
402 
403 
404 /*------------- xgbparselex_ver() -----------------------*/
405 
406 static int xgbparselex_ver(const char* linein, TTokens& tokens, bool accver)
407 {
408  tokens.clear();
409  int retval = 0;
410  if (*linein) {
411  string line{ linein };
413  auto length = line.size();
414  unsigned current_col = 0;
415 
416  while (current_col < length) {
417 
418  if (isspace(line[current_col]) || line[current_col] == '~') {
419  ++current_col;
420  continue;
421  }
422 
423  STokenInfo current_token;
424  if (isdigit(line[current_col])) {
425  current_token.choice = ETokenType::eNumber;
426  CTempString tempString(line.c_str() + current_col, size_t(length - current_col));
427  auto not_digit_pos = tempString.find_first_not_of("0123456789");
428  auto num_digits = (not_digit_pos == NPOS) ? size_t(length - current_col) : not_digit_pos;
429  current_token.data = string(line.c_str() + current_col, num_digits);
430  tokens.push_back(current_token);
431  current_col += num_digits;
432  continue;
433  }
434 
435  bool skip_new_token = false;
436  switch (line[current_col]) {
437  case '\"':
438  current_token.choice = ETokenType::eString;
439  if (auto closing_quote_pos = line.find('\"', current_col + 1);
440  closing_quote_pos == string::npos) {
441  xlex_error_func("unterminated string", line, current_col);
442  retval++;
443  } else {
444  size_t len = closing_quote_pos - current_col + 1;
445  current_token.data = string(line.c_str(), +current_col);
446  current_col += len;
447  }
448  break;
449  /*------
450  * JOIN
451  *------*/
452  case 'j':
453  current_token.choice = ETokenType::eJoin;
454  if (! NStr::StartsWith(line.c_str() + current_col, "join")) {
455  xlex_error_func("\"join\" misspelled", line, current_col);
456  retval++;
457  current_col = advance_to('(', current_col, line);
458  } else {
459  current_col += 3;
460  }
461  break;
462 
463  /*------
464  * ORDER and ONE-OF
465  *------*/
466  case 'o':
467  if (! NStr::StartsWith(line.c_str() + current_col, "order")) {
468  if (! NStr::StartsWith(line.c_str() + current_col, "one-of")) {
469  xlex_error_func("\"order\" or \"one-of\" misspelled",
470  line,
471  current_col);
472  retval++;
473  current_col = advance_to('(', current_col, line);
474  } else {
475  current_token.choice = ETokenType::eOneOf;
476  current_col += 5;
477  }
478  } else {
479  current_token.choice = ETokenType::eOrder;
480  current_col += 4;
481  }
482  break;
483 
484  /*------
485  * REPLACE
486  *------*/
487  case 'r':
488  current_token.choice = ETokenType::eReplace;
489  if (! NStr::StartsWith(line.c_str() + current_col, "replace")) {
490  xlex_error_func("\"replace\" misspelled", line, current_col);
491  retval++;
492  current_col = advance_to('(', current_col, line);
493  } else {
494  current_col += 6;
495  }
496  break;
497 
498  /*------
499  * GAP or GROUP or GI
500  *------*/
501  case 'g':
502  if (NStr::StartsWith(line.c_str() + current_col, "gap") &&
503  (current_col < length - 3) &&
504  (line[current_col + 3] == '(' ||
505  line[current_col + 3] == ' ' ||
506  line[current_col + 3] == '\t' ||
507  line[current_col + 3] == '\0')) {
508  current_token.choice = ETokenType::eGap;
509  current_token.data = "gap";
510  if (NStr::StartsWith(line.c_str() + current_col + 3, "(unk", NStr::eNocase)) {
511  current_token.choice = ETokenType::eUnkGap;
512  tokens.push_back(current_token);
513 
514  current_token.choice = ETokenType::eLeft;
515  current_col += 4;
516  }
517  current_col += 2;
518  break;
519  }
520  if (NStr::StartsWith(line.c_str() + current_col, "gi|")) {
521  current_token.choice = ETokenType::eAccession;
522  current_col += 3;
523  for (; isdigit(line[current_col]); current_col++)
524  ;
525  break;
526  }
527  current_token.choice = ETokenType::eGroup;
528  if (! NStr::StartsWith(line.c_str() + current_col, "group")) {
529  xlex_error_func("\"group\" misspelled", line, current_col);
530  retval++;
531  current_col = advance_to('(', current_col, line);
532  } else {
533  current_col += 4;
534  }
535  break;
536 
537  /*------
538  * COMPLEMENT
539  *------*/
540  case 'c':
541  current_token.choice = ETokenType::eCompl;
542  if (! NStr::StartsWith(line.c_str() + current_col, "complement")) {
543  xlex_error_func("\"complement\" misspelled", line, current_col);
544  ++retval;
545  current_col = advance_to('(', current_col, line);
546  } else {
547  current_col += 9;
548  }
549  break;
550 
551  /*-------
552  * internal bases ignored
553  *---------*/
554  case 'b':
555  if (! NStr::StartsWith(line.c_str() + current_col, "bases")) {
556  current_token.choice = ETokenType::eAccession;
557  retval += sGetAccession(current_token.data, current_col, line, accver);
558  } else {
559  skip_new_token = true;
560  current_col += 4;
561  }
562  break;
563 
564  /*------
565  * ()^.,<> (bases (sites
566  *------*/
567  case '(':
568  if (NStr::StartsWith(line.c_str() + current_col, "(base")) {
569  current_token.choice = ETokenType::eJoin;
570  current_col += 4;
571  if (current_col < length - 1 && line[current_col + 1] == 's') {
572  current_col++;
573  }
574  tokens.push_back(current_token);
575  current_token.choice = ETokenType::eLeft;
576  } else if (NStr::StartsWith(line.c_str() + current_col, "(sites")) {
577  current_col += 5;
578  if (current_col < length - 1) {
579  if (line[current_col + 1] == ')') {
580  current_col++;
581  current_token.choice = ETokenType::eSites;
582  } else {
583  current_token.choice = ETokenType::eSites;
584  tokens.push_back(current_token);
585  current_token.choice = ETokenType::eJoin;
586  tokens.push_back(current_token);
587  current_token.choice = ETokenType::eLeft;
588  if (current_col < length - 1) {
589  if (line[current_col + 1] == ';') {
590  current_col++;
591  } else if (NStr::StartsWith(line.c_str() + current_col + 1, " ;")) {
592  current_col += 2;
593  }
594  }
595  }
596  }
597  } else {
598  current_token.choice = ETokenType::eLeft;
599  }
600  break;
601 
602  case ')':
603  current_token.choice = ETokenType::eRight;
604  break;
605 
606  case '^':
607  current_token.choice = ETokenType::eCaret;
608  break;
609 
610  case '-':
611  current_token.choice = ETokenType::eDotDot;
612  break;
613  case '.':
614  if (current_col == length - 1 || line[current_col + 1] != '.') {
615  current_token.choice = ETokenType::eSingleDot;
616  } else {
617  current_token.choice = ETokenType::eDotDot;
618  current_col++;
619  }
620  break;
621 
622  case '>':
623  current_token.choice = ETokenType::eGt;
624  break;
625 
626  case '<':
627  current_token.choice = ETokenType::eLt;
628  break;
629 
630  case ';':
631  case ',':
632  current_token.choice = ETokenType::eComma;
633  break;
634 
635  case 't':
636  if (! NStr::StartsWith(line.c_str() + current_col, "to")) {
637  current_token.choice = ETokenType::eAccession;
638  retval += sGetAccession(current_token.data, current_col, line, accver);
639  } else {
640  current_token.choice = ETokenType::eDotDot;
641  current_col++;
642  }
643  break;
644 
645  case 's':
646  if (! NStr::StartsWith(line.c_str() + current_col, "site")) {
647  current_token.choice = ETokenType::eAccession;
648  retval += sGetAccession(current_token.data, current_col, line, accver);
649  } else {
650  current_token.choice = ETokenType::eSites;
651  current_col += 3;
652  if (current_col < length - 1 && line[current_col + 1] == 's') {
653  current_col++;
654  }
655  if (current_col < length - 1) {
656  if (line[current_col + 1] == ';') {
657  current_col++;
658  } else if (NStr::StartsWith(line.c_str() + current_col + 1, " ;")) {
659  current_col += 2;
660  }
661  }
662  }
663  break;
664 
665  default:
666  current_token.choice = ETokenType::eAccession;
667  retval += sGetAccession(current_token.data, current_col, line, accver);
668  }
669 
670 
671  /*--move to past last "good" character---*/
672  ++current_col;
673  if (! skip_new_token) {
674  tokens.push_back(current_token);
675  }
676  }
677  }
678 
679  return retval;
680 }
681 
682 
683 /*----------------- xgbparse_better_be_done()-------------*/
684 static void xgbparse_better_be_done(int& numErrors, TTokenIt current_token, const TTokens& tokens, bool& keep_rawPt, int paren_count)
685 {
686  if (current_token != end(tokens)) {
687  while (current_token->choice == ETokenType::eRight) {
688  paren_count--;
689  ++current_token;
690  if (current_token == end(tokens)) {
691  if (paren_count) {
692  const string par_msg = "mismatched parentheses (" + to_string(paren_count) + ")";
693  xgbparse_error(par_msg.c_str(),
694  tokens,
695  current_token);
696  keep_rawPt = true;
697  ++numErrors;
698  }
699  break;
700  }
701  }
702  }
703 
704  if (paren_count) {
705  xgbparse_error("text after last legal right parenthesis",
706  tokens,
707  current_token);
708  keep_rawPt = true;
709  ++numErrors;
710  }
711 
712  if (current_token != end(tokens)) {
713  xgbparse_error("text after end",
714  tokens,
715  current_token);
716  keep_rawPt = true;
717  ++numErrors;
718  }
719 }
720 
721 
722 /**********************************************************
723  *
724  * CRef<CSeq_loc> XGapToSeqLocEx(range, unknown):
725  *
726  * Gets the size of gap and constructs SeqLoc block with
727  * $(seqlitdbtag) value as Dbtag.db and Dbtag.tag.id = 0.
728  *
729  **********************************************************/
731 {
732  CRef<CSeq_loc> ret;
733 
734  if (range < 0)
735  return ret;
736 
737  ret.Reset(new CSeq_loc);
738  if (range == 0) {
739  ret->SetNull();
740  return ret;
741  }
742 
743  CSeq_interval& interval = ret->SetInt();
744  interval.SetFrom(0);
745  interval.SetTo(range - 1);
746 
747  CSeq_id& id = interval.SetId();
748  id.SetGeneral().SetDb(unknown ? unkseqlitdbtag : seqlitdbtag);
749  id.SetGeneral().SetTag().SetId(0);
750 
751  return ret;
752 }
753 
754 /**********************************************************/
755 static void xgbgap(TTokenIt& current_it, TTokenConstIt end_it, CRef<CSeq_loc>& loc, bool unknown)
756 {
757  auto it = next(current_it);
758 
759  if (distance(TTokenConstIt(it), end_it) < 2) {
760  return;
761  }
762 
763  if (it->choice != ETokenType::eLeft) {
764  return;
765  }
766  ++it;
767  if (it->choice != ETokenType::eNumber &&
768  it->choice != ETokenType::eRight) {
769  return;
770  }
771 
772  if (it->choice == ETokenType::eRight) {
773  loc->SetNull();
774  } else {
775  auto gapsize_it = it++;
776  if (it == end_it || it->choice != ETokenType::eRight) {
777  return;
778  }
779  auto pLoc = XGapToSeqLocEx(atoi(gapsize_it->data.c_str()), unknown);
780  if (! pLoc) {
781  return;
782  }
783  loc = pLoc;
784  }
785  current_it = next(it);
786 }
787 
788 /*------------------- sConvertIntToPoint()-----------*/
789 
790 static void sConvertIntToPoint(CSeq_loc& loc)
791 {
792  CRef<CSeq_point> point(new CSeq_point);
793 
794  point->SetPoint(loc.GetInt().GetFrom());
795 
796  if (loc.GetInt().IsSetId())
797  point->SetId(loc.SetInt().SetId());
798 
799  if (loc.GetInt().IsSetFuzz_from())
800  point->SetFuzz(loc.SetInt().SetFuzz_from());
801 
802  loc.SetPnt(*point);
803 }
804 
805 
806 static void xgbload_number(TSeqPos& numPt, CInt_fuzz& fuzz, bool& keep_rawPt, TTokenIt& currentPt, const TTokens& tokens, int& numErrors, int take_which)
807 {
808  int num_found = 0;
809  int fuzz_err = 0;
810  bool strange_sin_dot = false;
811  auto end_it = end(tokens);
812 
813  if (currentPt->choice == ETokenType::eCaret) {
814  xgbparse_error("duplicate carets", tokens, currentPt);
815  keep_rawPt = true;
816  ++numErrors;
817  ++currentPt;
818  fuzz_err = 1;
819  } else if (currentPt->choice == ETokenType::eGt ||
820  currentPt->choice == ETokenType::eLt) {
821  if (currentPt->choice == ETokenType::eGt)
823  else
825 
826  ++currentPt;
827  } else if (currentPt->choice == ETokenType::eLeft) {
828  strange_sin_dot = true;
829  ++currentPt;
830  fuzz.SetRange();
831 
832  if (currentPt->choice == ETokenType::eNumber) {
833  fuzz.SetRange().SetMin(atoi(currentPt->data.c_str()) - 1);
834  if (take_which == TAKE_FIRST) {
835  numPt = fuzz.GetRange().GetMin();
836  }
837  ++currentPt;
838  num_found = 1;
839  } else
840  fuzz_err = 1;
841 
842  if (currentPt->choice != ETokenType::eSingleDot)
843  fuzz_err = 1;
844  else {
845  ++currentPt;
846  if (currentPt->choice == ETokenType::eNumber) {
847  fuzz.SetRange().SetMax(atoi(currentPt->data.c_str()) - 1);
848  if (take_which == TAKE_SECOND) {
849  numPt = fuzz.GetRange().GetMax();
850  }
851  ++currentPt;
852  } else
853  fuzz_err = 1;
854 
855  if (currentPt->choice == ETokenType::eRight)
856  ++currentPt;
857  else
858  fuzz_err = 1;
859  }
860 
861  } else if (currentPt->choice != ETokenType::eNumber) {
862  /* this prevents endless cycling, unconditionally */
863  if (currentPt->choice != ETokenType::eOneOf && currentPt->choice != ETokenType::eOneOfNum)
864  ++currentPt;
865  num_found = -1;
866  }
867 
868  if (! strange_sin_dot) {
869  if (currentPt == end_it) {
870  xgbparse_error("unexpected end of interval tokens",
871  tokens,
872  currentPt);
873  keep_rawPt = true;
874  ++numErrors;
875  } else {
876  if (currentPt->choice == ETokenType::eNumber) {
877  numPt = atoi(currentPt->data.c_str()) - 1;
878  ++currentPt;
879  num_found = 1;
880  }
881  }
882  }
883 
884  if (fuzz_err) {
885  xgbparse_error("Incorrect uncertainty", tokens, currentPt);
886  keep_rawPt = true;
887  ++numErrors;
888  }
889 
890  if (num_found != 1) {
891  keep_rawPt = true;
892  /****************
893  *
894  * 10..one-of(13,15) type syntax here
895  *
896  ***************/
897  if (currentPt->choice == ETokenType::eOneOf || currentPt->choice == ETokenType::eOneOfNum) {
898  bool one_of_ok = true;
899  bool at_end_one_of = false;
900 
901  ++currentPt;
902  if (currentPt->choice != ETokenType::eLeft) {
903  one_of_ok = false;
904  } else {
905  ++currentPt;
906  }
907 
908  if (one_of_ok && currentPt->choice == ETokenType::eNumber) {
909  numPt = atoi(currentPt->data.c_str()) - 1;
910  ++currentPt;
911  } else {
912  one_of_ok = false;
913  }
914 
915  while (one_of_ok && ! at_end_one_of && currentPt != end_it) {
916  switch (currentPt->choice) {
917  default:
918  one_of_ok = false;
919  break;
920  case ETokenType::eComma:
921  case ETokenType::eNumber:
922  ++currentPt;
923  break;
924  case ETokenType::eRight:
925  ++currentPt;
926  at_end_one_of = true;
927  break;
928  }
929  }
930 
931  if (! one_of_ok && ! at_end_one_of) {
932  while (! at_end_one_of && currentPt != end_it) {
933  if (currentPt->choice == ETokenType::eRight)
934  at_end_one_of = true;
935  ++currentPt;
936  }
937  }
938 
939  if (! one_of_ok) {
940 
941  xgbparse_error("bad one-of() syntax as number",
942  tokens,
943  currentPt);
944  ++numErrors;
945  }
946  } else {
947  xgbparse_error("Number not found when expected",
948  tokens,
949  currentPt);
950  ++numErrors;
951  }
952  }
953 }
954 
955 
956 /*--------------- xgbint_ver ()--------------------*/
957 /* sometimes returns points */
958 static CRef<CSeq_loc> xgbint_ver(bool& keep_rawPt,
959  TTokenIt& currentPt,
960  const TTokens& tokens,
961  int& numErrors,
962  const TSeqIdList& seq_ids,
963  bool accver)
964 {
965  auto ret = Ref(new CSeq_loc());
966 
967  CRef<CSeq_id> new_id;
968  CRef<CInt_fuzz> new_fuzz;
969  auto end_it = end(tokens);
970 
971  if (currentPt->choice == ETokenType::eAccession) {
972  if (accver && currentPt->data.find('.') >= currentPt->data.size() - 1) {
973  xgbparse_error("Missing accession's version",
974  tokens,
975  currentPt);
976  }
977 
978  new_id = Ref(new CSeq_id(currentPt->data));
979 
980  ++currentPt;
981  if (currentPt == end_it) {
982  xgbparse_error("Nothing after accession",
983  tokens,
984  currentPt);
985  new_id.Reset();
986  keep_rawPt = true;
987  ++numErrors;
988  return CRef<CSeq_loc>();
989  }
990 
991  } else if (! seq_ids.empty()) {
992  new_id.Reset(new CSeq_id());
993  new_id->Assign(*(*seq_ids.begin()));
994  }
995 
996  if (currentPt->choice == ETokenType::eLt) {
997  new_fuzz.Reset(new CInt_fuzz);
998  new_fuzz->SetLim(CInt_fuzz::eLim_lt);
999 
1000  ++currentPt;
1001  if (currentPt == end_it) {
1002  xgbparse_error("Nothing after \'<\'",
1003  tokens,
1004  currentPt);
1005  keep_rawPt = true;
1006  ++numErrors;
1007  return CRef<CSeq_loc>();
1008  }
1009  }
1010 
1011  if (! numErrors) {
1012  switch (currentPt->choice) {
1014  if (new_id.NotEmpty()) {
1015  xgbparse_error("duplicate accessions",
1016  tokens,
1017  currentPt);
1018  keep_rawPt = true;
1019  ++numErrors;
1020  return CRef<CSeq_loc>();
1021  }
1022  break;
1023  case ETokenType::eCaret:
1024  xgbparse_error("caret (^) before number",
1025  tokens,
1026  currentPt);
1027  keep_rawPt = true;
1028  ++numErrors;
1029  return CRef<CSeq_loc>();
1030  case ETokenType::eLt:
1031  if (new_id.NotEmpty()) {
1032  xgbparse_error("duplicate \'<\'",
1033  tokens,
1034  currentPt);
1035  keep_rawPt = true;
1036  ++numErrors;
1037  return CRef<CSeq_loc>();
1038  }
1039  break;
1040  case ETokenType::eGt:
1041  case ETokenType::eNumber:
1042  case ETokenType::eLeft:
1043 
1044  case ETokenType::eOneOfNum:
1045  if (new_fuzz.NotEmpty())
1046  ret->SetInt().SetFuzz_from(*new_fuzz);
1047  if (new_id.NotEmpty())
1048  ret->SetInt().SetId(*new_id);
1049 
1050  xgbload_number(ret->SetInt().SetFrom(), ret->SetInt().SetFuzz_from(), keep_rawPt, currentPt, tokens, numErrors, TAKE_FIRST);
1051 
1052  if (ret->GetInt().GetFuzz_from().Which() == CInt_fuzz::e_not_set)
1053  ret->SetInt().ResetFuzz_from();
1054 
1055  xgbcheck_range(ret->GetInt().GetFrom(), *new_id, keep_rawPt, numErrors, tokens, currentPt);
1056 
1057  if (numErrors) {
1058  return CRef<CSeq_loc>();
1059  }
1060 
1061  if (currentPt != end_it) {
1062  bool in_caret = false;
1063  switch (currentPt->choice) {
1064  default:
1065  case ETokenType::eJoin:
1066  case ETokenType::eCompl:
1068  case ETokenType::eOrder:
1069  case ETokenType::eGroup:
1071  xgbparse_error("problem with 2nd number",
1072  tokens,
1073  currentPt);
1074  keep_rawPt = true;
1075  ++numErrors;
1076  return CRef<CSeq_loc>();
1077  case ETokenType::eComma:
1078  case ETokenType::eRight: /* valid thing to leave on*/
1079  /*--------------but have a point, not an interval----*/
1080  sConvertIntToPoint(*ret);
1081  break;
1082 
1083  case ETokenType::eGt:
1084  case ETokenType::eLt:
1085  xgbparse_error("Missing \'..\'",
1086  tokens,
1087  currentPt);
1088  keep_rawPt = true;
1089  ++numErrors;
1090  return CRef<CSeq_loc>();
1091  case ETokenType::eCaret:
1092  if (ret->GetInt().IsSetFuzz_from()) {
1093  xgbparse_error("\'<\' then \'^\'",
1094  tokens,
1095  currentPt);
1096  keep_rawPt = true;
1097  ++numErrors;
1098  return CRef<CSeq_loc>();
1099  }
1100 
1101  ret->SetInt().SetFuzz_from().SetLim(CInt_fuzz::eLim_tl);
1102  ret->SetInt().SetFuzz_to().SetLim(CInt_fuzz::eLim_tl);
1103  in_caret = true;
1104  /*---no break on purpose ---*/
1106  case ETokenType::eDotDot:
1107  ++currentPt;
1108  if (currentPt == end_it) {
1109  xgbparse_error("unexpected end of usable tokens",
1110  tokens,
1111  currentPt);
1112  keep_rawPt = true;
1113  ++numErrors;
1114  return CRef<CSeq_loc>();
1115  }
1116  /*--no break on purpose here ---*/
1118  case ETokenType::eNumber:
1119  case ETokenType::eLeft:
1120 
1121  case ETokenType::eOneOfNum: /* unlikely, but ok */
1122  if (currentPt->choice == ETokenType::eRight) {
1123  if (ret->GetInt().IsSetFuzz_from()) {
1124  xgbparse_error("\'^\' then \'>\'",
1125  tokens,
1126  currentPt);
1127  keep_rawPt = true;
1128  ++numErrors;
1129  return CRef<CSeq_loc>();
1130  }
1131  }
1132 
1133  xgbload_number(ret->SetInt().SetTo(), ret->SetInt().SetFuzz_to(), keep_rawPt, currentPt, tokens, numErrors, TAKE_SECOND);
1134 
1135  if (ret->GetInt().GetFuzz_to().Which() == CInt_fuzz::e_not_set)
1136  ret->SetInt().ResetFuzz_to();
1137 
1138  xgbcheck_range(ret->GetInt().GetTo(), *new_id, keep_rawPt, numErrors, tokens, currentPt);
1139 
1140  /*----------
1141  * The caret location implies a place (point) between two location.
1142  * This is not exactly captured by the ASN.1, but pretty close
1143  *-------*/
1144  if (in_caret) {
1145  TSeqPos to = ret->GetInt().GetTo();
1146 
1147  sConvertIntToPoint(*ret);
1148  CSeq_point& point = ret->SetPnt();
1149  if (point.GetPoint() + 1 == to) {
1150  point.SetPoint(to); /* was essentailly correct */
1151  } else {
1152  point.SetFuzz().SetRange().SetMax(to);
1153  point.SetFuzz().SetRange().SetMin(point.GetPoint());
1154  }
1155  }
1156 
1157  if (ret->IsInt() &&
1158  ret->GetInt().GetFrom() == ret->GetInt().GetTo() &&
1159  ! ret->GetInt().IsSetFuzz_from() &&
1160  ! ret->GetInt().IsSetFuzz_to()) {
1161  /*-------if interval really a point, make is so ----*/
1162  sConvertIntToPoint(*ret);
1163  }
1164  } /* end switch */
1165  } else {
1166  sConvertIntToPoint(*ret);
1167  }
1168  break;
1169  default:
1170  xgbparse_error("No number when expected",
1171  tokens,
1172  currentPt);
1173  keep_rawPt = true;
1174  ++numErrors;
1175  return CRef<CSeq_loc>();
1176  }
1177  }
1178 
1179  return ret;
1180 }
1181 
1182 
1183 class CGBLocException : exception
1184 {
1185 };
1186 
1187 static CRef<CSeq_loc> xgbloc_ver(bool& keep_rawPt, int& parenPt, TTokenIt& currentPt, const TTokens& tokens, int& numErrors, const TSeqIdList& seq_ids, bool accver)
1188 {
1189  CRef<CSeq_loc> retval;
1190 
1191  bool add_nulls = false;
1192  auto current_token = currentPt;
1193  bool did_complement = false;
1194  bool in_sites;
1195  auto end_it = end(tokens);
1196 
1197  try {
1198  do {
1199  in_sites = false;
1200  switch (current_token->choice) {
1201  case ETokenType::eCompl:
1202  ++currentPt;
1203  if (currentPt == end_it) {
1204  xgbparse_error("unexpected end of usable tokens",
1205  tokens,
1206  currentPt);
1207  throw CGBLocException();
1208  }
1209  if (currentPt->choice != ETokenType::eLeft) {
1210  xgbparse_error("Missing \'(\'", /* paran match ) */
1211  tokens,
1212  currentPt);
1213  throw CGBLocException();
1214  }
1215 
1216  ++parenPt;
1217  ++currentPt;
1218  if (currentPt == end_it) {
1219  xgbparse_error("illegal null contents",
1220  tokens,
1221  currentPt);
1222  throw CGBLocException();
1223  }
1224 
1225  if (currentPt->choice == ETokenType::eRight) { /* paran match ( */
1226  xgbparse_error("Premature \')\'",
1227  tokens,
1228  currentPt);
1229  throw CGBLocException();
1230  }
1231  retval = xgbloc_ver(keep_rawPt, parenPt, currentPt, tokens, numErrors, seq_ids, accver);
1232 
1233  if (retval.NotEmpty())
1234  retval = sequence::SeqLocRevCmpl(*retval, nullptr);
1235 
1236  did_complement = true;
1237  if (currentPt != end_it) {
1238  if (currentPt->choice != ETokenType::eRight) {
1239  xgbparse_error("Missing \')\'",
1240  tokens,
1241  currentPt);
1242  throw CGBLocException();
1243  }
1244  --parenPt;
1245  ++currentPt;
1246  } else {
1247  xgbparse_error("Missing \')\'",
1248  tokens,
1249  currentPt);
1250  throw CGBLocException();
1251  }
1252  break;
1253  /* REAL LOCS */
1254  case ETokenType::eJoin:
1255  retval = Ref(new CSeq_loc());
1256  retval->SetMix();
1257  break;
1258  case ETokenType::eOrder:
1259  retval = Ref(new CSeq_loc);
1260  retval->SetMix();
1261  add_nulls = true;
1262  break;
1263  case ETokenType::eGroup:
1264  retval = Ref(new CSeq_loc);
1265  retval->SetMix();
1266  keep_rawPt = true;
1267  break;
1268  case ETokenType::eOneOf:
1269  retval = Ref(new CSeq_loc);
1270  retval->SetEquiv();
1271  break;
1272 
1273  /* ERROR */
1274  case ETokenType::eString:
1275  xgbparse_error("string in loc",
1276  tokens,
1277  current_token);
1278  throw CGBLocException();
1279  /*--- no break on purpose---*/
1280  default:
1281  case ETokenType::eUnknown:
1282  case ETokenType::eRight:
1283  case ETokenType::eDotDot:
1284  case ETokenType::eComma:
1286  xgbparse_error("illegal initial loc token",
1287  tokens,
1288  currentPt);
1289  throw CGBLocException();
1290 
1291  /* Interval, occurs on recursion */
1292  case ETokenType::eGap:
1293  xgbgap(currentPt, end_it, retval, false);
1294  break;
1295  case ETokenType::eUnkGap:
1296  xgbgap(currentPt, end_it, retval, true);
1297  break;
1298 
1300  case ETokenType::eCaret:
1301  case ETokenType::eGt:
1302  case ETokenType::eLt:
1303  case ETokenType::eNumber:
1304  case ETokenType::eLeft:
1305  case ETokenType::eOneOfNum:
1306  retval = xgbint_ver(keep_rawPt, currentPt, tokens, numErrors, seq_ids, accver);
1307  break;
1308 
1309  case ETokenType::eReplace:
1310  /*-------illegal at this level --*/
1311  xgbparse_error("illegal replace",
1312  tokens,
1313  currentPt);
1314  throw CGBLocException();
1315  case ETokenType::eSites:
1316  in_sites = true;
1317  ++currentPt;
1318  break;
1319  }
1320  } while (in_sites && currentPt != end_it);
1321 
1322  if (! numErrors && ! did_complement && retval &&
1323  ! retval->IsNull() && ! retval->IsInt() && ! retval->IsPnt()) {
1324  /*--------
1325  * ONLY THE CHOICE has been set. the "join", etc. only has been noted
1326  *----*/
1327  ++currentPt;
1328  if (currentPt == end_it) {
1329  xgbparse_error("unexpected end of interval tokens",
1330  tokens,
1331  currentPt);
1332  throw CGBLocException();
1333  }
1334 
1335  if (currentPt->choice != ETokenType::eLeft) {
1336  xgbparse_error("Missing \'(\'",
1337  tokens,
1338  currentPt); /* paran match ) */
1339  throw CGBLocException();
1340  }
1341 
1342  ++parenPt;
1343  ++currentPt;
1344  if (currentPt == end_it) {
1345  xgbparse_error("illegal null contents",
1346  tokens,
1347  currentPt);
1348  throw CGBLocException();
1349  }
1350 
1351  if (currentPt->choice == ETokenType::eRight) { /* paran match ( */
1352  xgbparse_error("Premature \')\'",
1353  tokens,
1354  currentPt);
1355  throw CGBLocException();
1356  }
1357 
1358  while (! numErrors && currentPt != end_it) {
1359  if (currentPt->choice == ETokenType::eRight) {
1360  while (currentPt != end_it &&
1361  currentPt->choice == ETokenType::eRight) {
1362  --parenPt;
1363  }
1364  break;
1365  }
1366 
1367  if (currentPt == end_it)
1368  break;
1369 
1370  CRef<CSeq_loc> next_loc = xgbloc_ver(keep_rawPt, parenPt, currentPt, tokens, numErrors, seq_ids, accver);
1371  if (next_loc.NotEmpty()) {
1372  if (retval->IsMix())
1373  retval->SetMix().AddSeqLoc(*next_loc);
1374  else // equiv
1375  retval->SetEquiv().Add(*next_loc);
1376  }
1377 
1378  if (currentPt == end_it || currentPt->choice == ETokenType::eRight)
1379  break;
1380 
1381  if (currentPt->choice == ETokenType::eComma) {
1382  ++currentPt;
1383  if (add_nulls) {
1384  CRef<CSeq_loc> null_loc(new CSeq_loc);
1385  null_loc->SetNull();
1386 
1387  if (retval->IsMix())
1388  retval->SetMix().AddSeqLoc(*null_loc);
1389  else // equiv
1390  retval->SetEquiv().Add(*null_loc);
1391  }
1392  } else {
1393  xgbparse_error("Illegal token after interval",
1394  tokens,
1395  currentPt);
1396  throw CGBLocException();
1397  }
1398  }
1399 
1400  if (currentPt == end_it) {
1401  xgbparse_error("unexpected end of usable tokens",
1402  tokens,
1403  currentPt);
1404  throw CGBLocException();
1405  }
1406 
1407  if (currentPt->choice != ETokenType::eRight) {
1408  xgbparse_error("Missing \')\'" /* paran match ) */,
1409  tokens,
1410  currentPt);
1411  throw CGBLocException();
1412  }
1413  --parenPt;
1414  ++currentPt;
1415  }
1416  } catch (CGBLocException&) {
1417  keep_rawPt = true;
1418  ++numErrors;
1419  if (retval) {
1420  retval->Reset();
1421  retval->SetWhole().Assign(*(*seq_ids.begin()));
1422  }
1423  }
1424 
1425  return retval;
1426 }
1427 
1428 
1429 static CRef<CSeq_loc> xgbreplace_ver(bool& keep_rawPt, int& parenPt, TTokenIt& currentPt, const TTokens& tokens, int& numErrors, const TSeqIdList& seq_ids, bool accver)
1430 {
1431  CRef<CSeq_loc> ret;
1432 
1433  keep_rawPt = true;
1434  ++currentPt;
1435 
1436  if (currentPt->choice == ETokenType::eLeft) {
1437  ++currentPt;
1438  ret = xgbloc_ver(keep_rawPt, parenPt, currentPt, tokens, numErrors, seq_ids, accver);
1439 
1440  if (currentPt == end(tokens)) {
1441  xgbparse_error("unexpected end of interval tokens",
1442  tokens,
1443  currentPt);
1444  keep_rawPt = true;
1445  ++numErrors;
1446  } else if (currentPt->choice != ETokenType::eComma) {
1447  xgbparse_error("Missing comma after first location in replace",
1448  tokens,
1449  currentPt);
1450  ++numErrors;
1451  }
1452  } else {
1453  xgbparse_error("Missing \'(\'" /* paran match ) */
1454  ,
1455  tokens,
1456  currentPt);
1457  ++numErrors;
1458  }
1459 
1460  return ret;
1461 }
1462 
1463 
1464 /*---------- xgbparseint_ver()-----*/
1465 
1466 CRef<CSeq_loc> xgbparseint_ver(const char* raw_intervals, bool& keep_rawPt, int& numErrors, const TSeqIdList& seq_ids, bool accver)
1467 {
1468  keep_rawPt = false;
1469 
1470  TTokens tokens;
1471  numErrors = xgbparselex_ver(raw_intervals, tokens, accver);
1472 
1473  if (tokens.empty()) {
1474  numErrors = 1;
1475  return CRef<CSeq_loc>();
1476  }
1477 
1478  if (numErrors) {
1479  keep_rawPt = true;
1480  return CRef<CSeq_loc>();
1481  }
1482 
1483  CRef<CSeq_loc> ret;
1484  xfind_one_of_num(tokens);
1485  auto head_token = tokens.begin();
1486  auto current_token = head_token;
1487  auto end_it = tokens.end();
1488 
1489  int paren_count = 0;
1490  bool in_sites;
1491  do {
1492  in_sites = false;
1493  if (current_token != end_it) {
1494  switch (current_token->choice) {
1495  case ETokenType::eJoin:
1496  case ETokenType::eOrder:
1497  case ETokenType::eGroup:
1498  case ETokenType::eOneOf:
1499  case ETokenType::eCompl:
1500  ret = xgbloc_ver(keep_rawPt, paren_count, current_token, tokens, numErrors, seq_ids, accver);
1501  /* need to check that out of tokens here */
1502  xgbparse_better_be_done(numErrors, current_token, tokens, keep_rawPt, paren_count);
1503  break;
1504 
1505  case ETokenType::eString:
1506  xgbparse_error("string in loc", tokens, current_token);
1507  keep_rawPt = true;
1508  ++numErrors;
1509  /* no break on purpose */
1511  case ETokenType::eUnknown:
1512  default:
1513  case ETokenType::eRight:
1514  case ETokenType::eDotDot:
1515  case ETokenType::eComma:
1517  xgbparse_error("illegal initial token", tokens, current_token);
1518  keep_rawPt = true;
1519  ++numErrors;
1520  ++current_token;
1521  break;
1522 
1524  /*--- no warn, but strange ---*/
1525  /*-- no break on purpose ---*/
1526 
1527  case ETokenType::eCaret:
1528  case ETokenType::eGt:
1529  case ETokenType::eLt:
1530  case ETokenType::eNumber:
1531  case ETokenType::eLeft:
1532  case ETokenType::eOneOfNum:
1533  ret = xgbint_ver(keep_rawPt, current_token, tokens, numErrors, seq_ids, accver);
1534  /* need to check that out of tokens here */
1535  xgbparse_better_be_done(numErrors, current_token, tokens, keep_rawPt, paren_count);
1536  break;
1537 
1538  case ETokenType::eReplace:
1539  ret = xgbreplace_ver(keep_rawPt, paren_count, current_token, tokens, numErrors, seq_ids, accver);
1540  keep_rawPt = true;
1541  /*---all errors handled within this function ---*/
1542  break;
1543  case ETokenType::eSites:
1544  in_sites = true;
1545  ++current_token;
1546  break;
1547  }
1548  }
1549  } while (in_sites && current_token != end_it);
1550 
1551  if (numErrors) {
1552  return CRef<CSeq_loc>();
1553  }
1554 
1555  return ret;
1556 }
1557 
CTempString implements a light-weight string on top of a storage buffer whose lifetime management is ...
Definition: tempstr.hpp:65
#define head
Definition: ct_nlmzip_i.h:138
static DLIST_TYPE *DLIST_NAME() next(DLIST_LIST_TYPE *list, DLIST_TYPE *item)
Definition: dlist.tmpl.h:56
std::list< CRef< objects::CSeq_id > > TSeqIdList
Definition: ftablock.h:57
void Nlm_ErrSetContext(const char *module, const char *fname, int line)
Definition: ftaerr.cpp:460
void Nlm_ErrPostEx(ErrSev sev, int lev1, int lev2, const char *fmt,...)
Definition: ftaerr.cpp:500
#define SEV_ERROR
Definition: gicache.c:91
unsigned int TSeqPos
Type for sequence locations and lengths.
Definition: ncbimisc.hpp:875
string
Definition: cgiapp.hpp:687
virtual void Assign(const CSerialObject &source, ESerialRecursionMode how=eRecursive)
Optimized implementation of CSerialObject::Assign, which is not so efficient.
Definition: Seq_id.cpp:318
void SetMix(TMix &v)
Definition: Seq_loc.hpp:987
void SetWhole(TWhole &v)
Definition: Seq_loc.hpp:982
void SetPnt(TPnt &v)
Definition: Seq_loc.hpp:985
void SetInt(TInt &v)
Definition: Seq_loc.hpp:983
void SetEquiv(TEquiv &v)
Definition: Seq_loc.hpp:988
void SetNull(void)
Override all setters to incorporate cache invalidation.
Definition: Seq_loc.hpp:960
CSeq_loc * SeqLocRevCmpl(const CSeq_loc &loc, CScope *scope)
Get reverse complement of the seq-loc (?)
CRef< C > Ref(C *object)
Helper functions to get CRef<> and CConstRef<> objects.
Definition: ncbiobj.hpp:2015
void Reset(void)
Reset reference object.
Definition: ncbiobj.hpp:773
bool NotEmpty(void) const THROWS_NONE
Check if CRef is not empty – pointing to an object and has a non-null value.
Definition: ncbiobj.hpp:726
#define NCBI_FALLTHROUGH
int32_t Int4
4-byte (32-bit) signed integer
Definition: ncbitype.h:102
uint32_t Uint4
4-byte (32-bit) unsigned integer
Definition: ncbitype.h:103
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
#define NPOS
Definition: ncbistr.hpp:133
static void TruncateSpacesInPlace(string &str, ETrunc where=eTrunc_Both)
Truncate spaces in a string (in-place)
Definition: ncbistr.cpp:3197
bool empty(void) const
Return true if the represented string is empty (i.e., the length is zero)
Definition: tempstr.hpp:334
static bool StartsWith(const CTempString str, const CTempString start, ECase use_case=eCase)
Check if a string starts with a specified prefix value.
Definition: ncbistr.hpp:5411
CTempString substr(size_type pos) const
Obtain a substring from this string, beginning at a given offset.
Definition: tempstr.hpp:776
size_type find_first_not_of(const CTempString match, size_type pos=0) const
Find the first occurrence of any character not in the matching string within the current string,...
Definition: tempstr.hpp:553
size_type size(void) const
Return the length of the represented array.
Definition: tempstr.hpp:327
@ eNocase
Case insensitive compare.
Definition: ncbistr.hpp:1206
void SetMin(TMin value)
Assign a value to Min data member.
Definition: Int_fuzz_.hpp:528
TRange & SetRange(void)
Select the variant.
Definition: Int_fuzz_.cpp:165
TMin GetMin(void) const
Get the Min member data.
Definition: Int_fuzz_.hpp:519
void SetMax(TMax value)
Assign a value to Max data member.
Definition: Int_fuzz_.hpp:481
TLim & SetLim(void)
Select the variant.
Definition: Int_fuzz_.hpp:649
TMax GetMax(void) const
Get the Max member data.
Definition: Int_fuzz_.hpp:472
const TRange & GetRange(void) const
Get the variant data.
Definition: Int_fuzz_.cpp:159
@ eLim_gt
greater than
Definition: Int_fuzz_.hpp:211
@ eLim_lt
less than
Definition: Int_fuzz_.hpp:212
@ eLim_tl
space to left of position
Definition: Int_fuzz_.hpp:214
@ e_not_set
No variant selected.
Definition: Int_fuzz_.hpp:225
void SetTo(TTo value)
Assign a value to To data member.
void SetPoint(TPoint value)
Assign a value to Point data member.
Definition: Seq_point_.hpp:312
void SetId(TId &value)
Assign a value to Id data member.
Definition: Seq_point_.cpp:61
bool IsMix(void) const
Check if variant Mix is selected.
Definition: Seq_loc_.hpp:552
TPoint GetPoint(void) const
Get the Point member data.
Definition: Seq_point_.hpp:303
void SetId(TId &value)
Assign a value to Id data member.
TFrom GetFrom(void) const
Get the From member data.
void SetFuzz(TFuzz &value)
Assign a value to Fuzz data member.
Definition: Seq_point_.cpp:71
void SetFrom(TFrom value)
Assign a value to From data member.
virtual void Reset(void)
Reset the whole object.
Definition: Seq_loc_.cpp:59
bool IsSetId(void) const
WARNING: this used to be optional Check if a value has been assigned to Id data member.
bool IsInt(void) const
Check if variant Int is selected.
Definition: Seq_loc_.hpp:528
const TInt & GetInt(void) const
Get the variant data.
Definition: Seq_loc_.cpp:194
bool IsNull(void) const
Check if variant Null is selected.
Definition: Seq_loc_.hpp:504
bool IsSetFuzz_from(void) const
Check if a value has been assigned to Fuzz_from data member.
bool IsPnt(void) const
Check if variant Pnt is selected.
Definition: Seq_loc_.hpp:540
int len
range(_Ty, _Ty) -> range< _Ty >
constexpr auto front(list< Head, As... >, T=T()) noexcept -> Head
ETokenType
Token type.
int isalpha(Uchar c)
Definition: ncbictype.hpp:61
int isspace(Uchar c)
Definition: ncbictype.hpp:69
int isdigit(Uchar c)
Definition: ncbictype.hpp:64
Miscellaneous common-use basic types and functionality.
string data
Definition: xgbparint.cpp:85
ETokenType choice
Definition: xgbparint.cpp:84
USING_SCOPE(objects)
static CRef< CSeq_loc > xgbloc_ver(bool &keep_rawPt, int &parenPt, TTokenIt &currentPt, const TTokens &tokens, int &numErrors, const TSeqIdList &seq_ids, bool accver)
Definition: xgbparint.cpp:1187
static void sConvertIntToPoint(CSeq_loc &loc)
Definition: xgbparint.cpp:790
static CRef< CSeq_loc > xgbint_ver(bool &keep_rawPt, TTokenIt &currentPt, const TTokens &tokens, int &numErrors, const TSeqIdList &seq_ids, bool accver)
Definition: xgbparint.cpp:958
static string xgbparse_point(TTokenConstIt head, TTokenConstIt current)
Definition: xgbparint.cpp:124
CRef< CSeq_loc > xgbparseint_ver(const char *raw_intervals, bool &keep_rawPt, int &numErrors, const TSeqIdList &seq_ids, bool accver)
Definition: xgbparint.cpp:1466
static void xgbgap(TTokenIt &current_it, TTokenConstIt end_it, CRef< CSeq_loc > &loc, bool unknown)
Definition: xgbparint.cpp:755
static void xfind_one_of_num(list< STokenInfo > &tokens)
Definition: xgbparint.cpp:246
#define TAKE_SECOND
Definition: xgbparint.cpp:50
list< STokenInfo > TTokens
Definition: xgbparint.cpp:88
#define TAKE_FIRST
Definition: xgbparint.cpp:49
static void xgbparse_error(const char *front, TTokenConstIt head, TTokenConstIt current)
Definition: xgbparint.cpp:191
static void do_xgbparse_error(const char *msg, const char *details)
Definition: xgbparint.cpp:97
static void * xgbparse_range_data
Definition: xgbparint.cpp:106
const char * seqlitdbtag
Definition: xgbparint.cpp:55
static size_t sParseAccessionPrefix(const CTempString &accession)
Definition: xgbparint.cpp:316
static CRef< CSeq_loc > XGapToSeqLocEx(Int4 range, bool unknown)
Definition: xgbparint.cpp:730
static void xgbparse_better_be_done(int &numErrors, TTokenIt current_token, const TTokens &tokens, bool &keep_rawPt, int paren_count)
Definition: xgbparint.cpp:684
static int sGetAccession(string &accession, unsigned int &current_col, const string &line, bool accver)
Definition: xgbparint.cpp:366
TTokens::const_iterator TTokenConstIt
Definition: xgbparint.cpp:90
static CRef< CSeq_loc > xgbreplace_ver(bool &keep_rawPt, int &parenPt, TTokenIt &currentPt, const TTokens &tokens, int &numErrors, const TSeqIdList &seq_ids, bool accver)
Definition: xgbparint.cpp:1429
static void xgbload_number(TSeqPos &numPt, CInt_fuzz &fuzz, bool &keep_rawPt, TTokenIt &currentPt, const TTokens &tokens, int &numErrors, int take_which)
Definition: xgbparint.cpp:806
static void xlex_error_func(const char *msg, const string &line, const int current_col)
Definition: xgbparint.cpp:294
void xinstall_gbparse_error_handler(X_gbparse_errfunc new_func)
Definition: xgbparint.cpp:110
const char * unkseqlitdbtag
Definition: xgbparint.cpp:56
void xinstall_gbparse_range_func(void *data, X_gbparse_rangefunc new_func)
Definition: xgbparint.cpp:117
static void xgbcheck_range(TSeqPos num, const CSeq_id &id, bool &keep_rawPt, int &numErrors, const TTokens &tokens, TTokenConstIt current)
Definition: xgbparint.cpp:205
TTokens::iterator TTokenIt
Definition: xgbparint.cpp:89
static unsigned advance_to(const char c, unsigned current_pos, const string &line)
Definition: xgbparint.cpp:303
static X_gbparse_errfunc Err_func
Definition: xgbparint.cpp:104
static int xgbparselex_ver(const char *linein, TTokens &tokens, bool accver)
Definition: xgbparint.cpp:406
static X_gbparse_rangefunc Range_func
Definition: xgbparint.cpp:105
#define ERR_FEATURE_LocationParsing_validatr
Definition: xgbparint.cpp:95
Int4(* X_gbparse_rangefunc)(void *, const objects::CSeq_id &id)
Definition: xgbparint.h:17
void(* X_gbparse_errfunc)(const Char *, const Char *)
Definition: xgbparint.h:16
Modified on Thu Nov 30 04:54:15 2023 by modify_doxy.py rev. 669887