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

Go to the SVN repository for this file.

1 /* $Id: xgbparint.cpp 102974 2024-08-13 19:32:37Z 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(string_view msg, string_view 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;
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(string_view front, TTokenConstIt head, TTokenConstIt current)
192 {
193  string details = xgbparse_point(head, current);
194  Err_func(front, details);
195 }
196 
197 
198 static void xgbparse_error(string_view 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(
295  string_view msg,
296  const string& line,
297  unsigned int current_col)
298 {
299  string temp_string = line.substr(0, current_col + 1) + " ";
300  Err_func(msg, temp_string);
301 }
302 
303 
304 static unsigned advance_to(const char c, unsigned current_pos, const string& line)
305 {
306  int pos = current_pos;
307  while (pos < line.size()) {
308  if (line[pos] == c) {
309  return pos - 1;
310  }
311  ++pos;
312  }
313  return pos - 1;
314 }
315 
316 
317 static size_t sParseAccessionPrefix(string_view accession)
318 {
319  if (accession.empty()) {
320  return 0;
321  }
322 
323  auto IsAlpha = [](char c) { return isalpha(c); };
324 
325  auto it = find_if_not(begin(accession),
326  end(accession),
327  IsAlpha);
328 
329 
330  if (it == end(accession)) {
331  return 1;
332  }
333 
334  auto prefix_length = distance(begin(accession), it);
335  if (*it == '_') {
336  if (prefix_length != 2) {
337  return 1;
338  }
339  ++it;
340  it = find_if_not(it, end(accession), IsAlpha);
341  if (it == end(accession)) {
342  return 1;
343  }
344  prefix_length = distance(begin(accession), it);
345  if (prefix_length == 3 || prefix_length == 7) {
346  return prefix_length;
347  }
348  return 1;
349  } else if (accession.size() >= 3 &&
350  isdigit(accession[0]) &&
351  isdigit(accession[1]) &&
352  accession[2] == 'S') {
353  return 7;
354  }
355 
356  if (prefix_length == 1 ||
357  prefix_length == 2 ||
358  prefix_length == 4 ||
359  prefix_length == 6) {
360  return prefix_length;
361  }
362 
363  return 1;
364 }
365 
366 
367 static int sGetAccession(string& accession, unsigned int& current_col, const string& line, bool accver)
368 {
369  const auto length = line.size();
370  string_view tempString(line.c_str() + current_col, length - current_col);
371  auto prefixLength = sParseAccessionPrefix(tempString);
372  size_t accessionLength = prefixLength;
373 
374  tempString = tempString.substr(prefixLength);
375  auto notDigitPos = tempString.find_first_not_of("0123456789");
376  if (notDigitPos != string_view::npos) {
377  accessionLength += notDigitPos;
378  if (accver && tempString[notDigitPos] == '.') {
379  ++accessionLength;
380  if (tempString.size() > notDigitPos) {
381  tempString = tempString.substr(notDigitPos + 1);
382  notDigitPos = tempString.find_first_not_of("0123456789");
383  if (notDigitPos != string_view::npos) {
384  accessionLength += notDigitPos;
385  }
386  }
387  }
388  } else {
389  accessionLength = length - current_col;
390  }
391 
392  int retval = 0;
393  if (notDigitPos == string_view::npos || tempString[notDigitPos] != ':') {
394  xlex_error_func("ACCESSION missing \":\"", line, current_col);
395  ++retval;
396  --current_col;
397  }
398 
399  accession = string(line.c_str() + current_col, accessionLength);
400  current_col += accessionLength;
401  return retval;
402 }
403 
404 
405 /*------------- xgbparselex_ver() -----------------------*/
406 
407 static int xgbparselex_ver(string_view linein, TTokens& tokens, bool accver)
408 {
409  tokens.clear();
410  int retval = 0;
411  if (! linein.empty()) {
412  string line{ linein };
414  auto length = line.size();
415  unsigned current_col = 0;
416 
417  while (current_col < length) {
418 
419  if (isspace(line[current_col]) || line[current_col] == '~') {
420  ++current_col;
421  continue;
422  }
423 
424  STokenInfo current_token;
425  if (isdigit(line[current_col])) {
426  current_token.choice = ETokenType::eNumber;
427  CTempString tempString(line.c_str() + current_col, size_t(length - current_col));
428  auto not_digit_pos = tempString.find_first_not_of("0123456789");
429  auto num_digits = (not_digit_pos == string_view::npos) ? size_t(length - current_col) : not_digit_pos;
430  current_token.data = string(line.c_str() + current_col, num_digits);
431  tokens.push_back(current_token);
432  current_col += num_digits;
433  continue;
434  }
435 
436  bool skip_new_token = false;
437  switch (line[current_col]) {
438  case '\"':
439  current_token.choice = ETokenType::eString;
440  if (auto closing_quote_pos = line.find('\"', current_col + 1);
441  closing_quote_pos == string::npos) {
442  xlex_error_func("unterminated string", line, current_col);
443  retval++;
444  } else {
445  size_t len = closing_quote_pos - current_col + 1;
446  current_token.data = string(line.c_str(), +current_col);
447  current_col += len;
448  }
449  break;
450  /*------
451  * JOIN
452  *------*/
453  case 'j':
454  current_token.choice = ETokenType::eJoin;
455  if (! NStr::StartsWith(line.c_str() + current_col, "join")) {
456  xlex_error_func("\"join\" misspelled", line, current_col);
457  retval++;
458  current_col = advance_to('(', current_col, line);
459  } else {
460  current_col += 3;
461  }
462  break;
463 
464  /*------
465  * ORDER and ONE-OF
466  *------*/
467  case 'o':
468  if (! NStr::StartsWith(line.c_str() + current_col, "order")) {
469  if (! NStr::StartsWith(line.c_str() + current_col, "one-of")) {
470  xlex_error_func("\"order\" or \"one-of\" misspelled",
471  line,
472  current_col);
473  retval++;
474  current_col = advance_to('(', current_col, line);
475  } else {
476  current_token.choice = ETokenType::eOneOf;
477  current_col += 5;
478  }
479  } else {
480  current_token.choice = ETokenType::eOrder;
481  current_col += 4;
482  }
483  break;
484 
485  /*------
486  * REPLACE
487  *------*/
488  case 'r':
489  current_token.choice = ETokenType::eReplace;
490  if (! NStr::StartsWith(line.c_str() + current_col, "replace")) {
491  xlex_error_func("\"replace\" misspelled", line, current_col);
492  retval++;
493  current_col = advance_to('(', current_col, line);
494  } else {
495  current_col += 6;
496  }
497  break;
498 
499  /*------
500  * GAP or GROUP or GI
501  *------*/
502  case 'g':
503  if (NStr::StartsWith(line.c_str() + current_col, "gap") &&
504  (current_col < length - 3) &&
505  (line[current_col + 3] == '(' ||
506  line[current_col + 3] == ' ' ||
507  line[current_col + 3] == '\t' ||
508  line[current_col + 3] == '\0')) {
509  current_token.choice = ETokenType::eGap;
510  current_token.data = "gap";
511  if (NStr::StartsWith(line.c_str() + current_col + 3, "(unk", NStr::eNocase)) {
512  current_token.choice = ETokenType::eUnkGap;
513  tokens.push_back(current_token);
514 
515  current_token.choice = ETokenType::eLeft;
516  current_col += 4;
517  }
518  current_col += 2;
519  break;
520  }
521  if (NStr::StartsWith(line.c_str() + current_col, "gi|")) {
522  current_token.choice = ETokenType::eAccession;
523  current_col += 3;
524  for (; isdigit(line[current_col]); current_col++)
525  ;
526  break;
527  }
528  current_token.choice = ETokenType::eGroup;
529  if (! NStr::StartsWith(line.c_str() + current_col, "group")) {
530  xlex_error_func("\"group\" misspelled", line, current_col);
531  retval++;
532  current_col = advance_to('(', current_col, line);
533  } else {
534  current_col += 4;
535  }
536  break;
537 
538  /*------
539  * COMPLEMENT
540  *------*/
541  case 'c':
542  current_token.choice = ETokenType::eCompl;
543  if (! NStr::StartsWith(line.c_str() + current_col, "complement")) {
544  xlex_error_func("\"complement\" misspelled", line, current_col);
545  ++retval;
546  current_col = advance_to('(', current_col, line);
547  } else {
548  current_col += 9;
549  }
550  break;
551 
552  /*-------
553  * internal bases ignored
554  *---------*/
555  case 'b':
556  if (! NStr::StartsWith(line.c_str() + current_col, "bases")) {
557  current_token.choice = ETokenType::eAccession;
558  retval += sGetAccession(current_token.data, current_col, line, accver);
559  } else {
560  skip_new_token = true;
561  current_col += 4;
562  }
563  break;
564 
565  /*------
566  * ()^.,<> (bases (sites
567  *------*/
568  case '(':
569  if (NStr::StartsWith(line.c_str() + current_col, "(base")) {
570  current_token.choice = ETokenType::eJoin;
571  current_col += 4;
572  if (current_col < length - 1 && line[current_col + 1] == 's') {
573  current_col++;
574  }
575  tokens.push_back(current_token);
576  current_token.choice = ETokenType::eLeft;
577  } else if (NStr::StartsWith(line.c_str() + current_col, "(sites")) {
578  current_col += 5;
579  if (current_col < length - 1) {
580  if (line[current_col + 1] == ')') {
581  current_col++;
582  current_token.choice = ETokenType::eSites;
583  } else {
584  current_token.choice = ETokenType::eSites;
585  tokens.push_back(current_token);
586  current_token.choice = ETokenType::eJoin;
587  tokens.push_back(current_token);
588  current_token.choice = ETokenType::eLeft;
589  if (current_col < length - 1) {
590  if (line[current_col + 1] == ';') {
591  current_col++;
592  } else if (NStr::StartsWith(line.c_str() + current_col + 1, " ;")) {
593  current_col += 2;
594  }
595  }
596  }
597  }
598  } else {
599  current_token.choice = ETokenType::eLeft;
600  }
601  break;
602 
603  case ')':
604  current_token.choice = ETokenType::eRight;
605  break;
606 
607  case '^':
608  current_token.choice = ETokenType::eCaret;
609  break;
610 
611  case '-':
612  current_token.choice = ETokenType::eDotDot;
613  break;
614  case '.':
615  if (current_col == length - 1 || line[current_col + 1] != '.') {
616  current_token.choice = ETokenType::eSingleDot;
617  } else {
618  current_token.choice = ETokenType::eDotDot;
619  current_col++;
620  }
621  break;
622 
623  case '>':
624  current_token.choice = ETokenType::eGt;
625  break;
626 
627  case '<':
628  current_token.choice = ETokenType::eLt;
629  break;
630 
631  case ';':
632  case ',':
633  current_token.choice = ETokenType::eComma;
634  break;
635 
636  case 't':
637  if (! NStr::StartsWith(line.c_str() + current_col, "to")) {
638  current_token.choice = ETokenType::eAccession;
639  retval += sGetAccession(current_token.data, current_col, line, accver);
640  } else {
641  current_token.choice = ETokenType::eDotDot;
642  current_col++;
643  }
644  break;
645 
646  case 's':
647  if (! NStr::StartsWith(line.c_str() + current_col, "site")) {
648  current_token.choice = ETokenType::eAccession;
649  retval += sGetAccession(current_token.data, current_col, line, accver);
650  } else {
651  current_token.choice = ETokenType::eSites;
652  current_col += 3;
653  if (current_col < length - 1 && line[current_col + 1] == 's') {
654  current_col++;
655  }
656  if (current_col < length - 1) {
657  if (line[current_col + 1] == ';') {
658  current_col++;
659  } else if (NStr::StartsWith(line.c_str() + current_col + 1, " ;")) {
660  current_col += 2;
661  }
662  }
663  }
664  break;
665 
666  default:
667  current_token.choice = ETokenType::eAccession;
668  retval += sGetAccession(current_token.data, current_col, line, accver);
669  }
670 
671 
672  /*--move to past last "good" character---*/
673  ++current_col;
674  if (! skip_new_token) {
675  tokens.push_back(current_token);
676  }
677  }
678  }
679 
680  return retval;
681 }
682 
683 
684 /*----------------- xgbparse_better_be_done()-------------*/
685 static void xgbparse_better_be_done(int& numErrors, TTokenIt current_token, const TTokens& tokens, bool& keep_rawPt, int paren_count)
686 {
687  if (current_token != end(tokens)) {
688  while (current_token->choice == ETokenType::eRight) {
689  paren_count--;
690  ++current_token;
691  if (current_token == end(tokens)) {
692  if (paren_count) {
693  const string par_msg = "mismatched parentheses (" + to_string(paren_count) + ")";
694  xgbparse_error(par_msg, tokens, current_token);
695  keep_rawPt = true;
696  ++numErrors;
697  }
698  break;
699  }
700  }
701  }
702 
703  if (paren_count) {
704  xgbparse_error("text after last legal right parenthesis",
705  tokens,
706  current_token);
707  keep_rawPt = true;
708  ++numErrors;
709  }
710 
711  if (current_token != end(tokens)) {
712  xgbparse_error("text after end",
713  tokens,
714  current_token);
715  keep_rawPt = true;
716  ++numErrors;
717  }
718 }
719 
720 
721 /**********************************************************
722  *
723  * CRef<CSeq_loc> XGapToSeqLocEx(range, unknown):
724  *
725  * Gets the size of gap and constructs SeqLoc block with
726  * $(seqlitdbtag) value as Dbtag.db and Dbtag.tag.id = 0.
727  *
728  **********************************************************/
730 {
731  CRef<CSeq_loc> ret;
732 
733  if (range < 0)
734  return ret;
735 
736  ret.Reset(new CSeq_loc);
737  if (range == 0) {
738  ret->SetNull();
739  return ret;
740  }
741 
742  CSeq_interval& interval = ret->SetInt();
743  interval.SetFrom(0);
744  interval.SetTo(range - 1);
745 
746  CSeq_id& id = interval.SetId();
747  id.SetGeneral().SetDb(unknown ? unkseqlitdbtag : seqlitdbtag);
748  id.SetGeneral().SetTag().SetId(0);
749 
750  return ret;
751 }
752 
753 /**********************************************************/
754 static void xgbgap(TTokenIt& current_it, TTokenConstIt end_it, CRef<CSeq_loc>& loc, bool unknown)
755 {
756  auto it = next(current_it);
757 
758  if (distance(TTokenConstIt(it), end_it) < 2) {
759  return;
760  }
761 
762  if (it->choice != ETokenType::eLeft) {
763  return;
764  }
765  ++it;
766  if (it->choice != ETokenType::eNumber &&
767  it->choice != ETokenType::eRight) {
768  return;
769  }
770 
771  if (it->choice == ETokenType::eRight) {
772  loc->SetNull();
773  } else {
774  auto gapsize_it = it++;
775  if (it == end_it || it->choice != ETokenType::eRight) {
776  return;
777  }
778  auto pLoc = XGapToSeqLocEx(atoi(gapsize_it->data.c_str()), unknown);
779  if (! pLoc) {
780  return;
781  }
782  loc = pLoc;
783  }
784  current_it = next(it);
785 }
786 
787 /*------------------- sConvertIntToPoint()-----------*/
788 
789 static void sConvertIntToPoint(CSeq_loc& loc)
790 {
791  CRef<CSeq_point> point(new CSeq_point);
792 
793  point->SetPoint(loc.GetInt().GetFrom());
794 
795  if (loc.GetInt().IsSetId())
796  point->SetId(loc.SetInt().SetId());
797 
798  if (loc.GetInt().IsSetFuzz_from())
799  point->SetFuzz(loc.SetInt().SetFuzz_from());
800 
801  loc.SetPnt(*point);
802 }
803 
804 
805 static void xgbload_number(TSeqPos& numPt, CInt_fuzz& fuzz, bool& keep_rawPt, TTokenIt& currentPt, const TTokens& tokens, int& numErrors, int take_which)
806 {
807  int num_found = 0;
808  int fuzz_err = 0;
809  bool strange_sin_dot = false;
810  auto end_it = end(tokens);
811 
812  if (currentPt->choice == ETokenType::eCaret) {
813  xgbparse_error("duplicate carets", tokens, currentPt);
814  keep_rawPt = true;
815  ++numErrors;
816  ++currentPt;
817  fuzz_err = 1;
818  } else if (currentPt->choice == ETokenType::eGt ||
819  currentPt->choice == ETokenType::eLt) {
820  if (currentPt->choice == ETokenType::eGt)
822  else
824 
825  ++currentPt;
826  } else if (currentPt->choice == ETokenType::eLeft) {
827  strange_sin_dot = true;
828  ++currentPt;
829  fuzz.SetRange();
830 
831  if (currentPt->choice == ETokenType::eNumber) {
832  fuzz.SetRange().SetMin(atoi(currentPt->data.c_str()) - 1);
833  if (take_which == TAKE_FIRST) {
834  numPt = fuzz.GetRange().GetMin();
835  }
836  ++currentPt;
837  num_found = 1;
838  } else
839  fuzz_err = 1;
840 
841  if (currentPt->choice != ETokenType::eSingleDot)
842  fuzz_err = 1;
843  else {
844  ++currentPt;
845  if (currentPt->choice == ETokenType::eNumber) {
846  fuzz.SetRange().SetMax(atoi(currentPt->data.c_str()) - 1);
847  if (take_which == TAKE_SECOND) {
848  numPt = fuzz.GetRange().GetMax();
849  }
850  ++currentPt;
851  } else
852  fuzz_err = 1;
853 
854  if (currentPt->choice == ETokenType::eRight)
855  ++currentPt;
856  else
857  fuzz_err = 1;
858  }
859 
860  } else if (currentPt->choice != ETokenType::eNumber) {
861  /* this prevents endless cycling, unconditionally */
862  if (currentPt->choice != ETokenType::eOneOf && currentPt->choice != ETokenType::eOneOfNum)
863  ++currentPt;
864  num_found = -1;
865  }
866 
867  if (! strange_sin_dot) {
868  if (currentPt == end_it) {
869  xgbparse_error("unexpected end of interval tokens",
870  tokens,
871  currentPt);
872  keep_rawPt = true;
873  ++numErrors;
874  } else {
875  if (currentPt->choice == ETokenType::eNumber) {
876  numPt = atoi(currentPt->data.c_str()) - 1;
877  ++currentPt;
878  num_found = 1;
879  }
880  }
881  }
882 
883  if (fuzz_err) {
884  xgbparse_error("Incorrect uncertainty", tokens, currentPt);
885  keep_rawPt = true;
886  ++numErrors;
887  }
888 
889  if (num_found != 1) {
890  keep_rawPt = true;
891  /****************
892  *
893  * 10..one-of(13,15) type syntax here
894  *
895  ***************/
896  if (currentPt->choice == ETokenType::eOneOf || currentPt->choice == ETokenType::eOneOfNum) {
897  bool one_of_ok = true;
898  bool at_end_one_of = false;
899 
900  ++currentPt;
901  if (currentPt->choice != ETokenType::eLeft) {
902  one_of_ok = false;
903  } else {
904  ++currentPt;
905  }
906 
907  if (one_of_ok && currentPt->choice == ETokenType::eNumber) {
908  numPt = atoi(currentPt->data.c_str()) - 1;
909  ++currentPt;
910  } else {
911  one_of_ok = false;
912  }
913 
914  while (one_of_ok && ! at_end_one_of && currentPt != end_it) {
915  switch (currentPt->choice) {
916  default:
917  one_of_ok = false;
918  break;
919  case ETokenType::eComma:
920  case ETokenType::eNumber:
921  ++currentPt;
922  break;
923  case ETokenType::eRight:
924  ++currentPt;
925  at_end_one_of = true;
926  break;
927  }
928  }
929 
930  if (! one_of_ok && ! at_end_one_of) {
931  while (! at_end_one_of && currentPt != end_it) {
932  if (currentPt->choice == ETokenType::eRight)
933  at_end_one_of = true;
934  ++currentPt;
935  }
936  }
937 
938  if (! one_of_ok) {
939 
940  xgbparse_error("bad one-of() syntax as number",
941  tokens,
942  currentPt);
943  ++numErrors;
944  }
945  } else {
946  xgbparse_error("Number not found when expected",
947  tokens,
948  currentPt);
949  ++numErrors;
950  }
951  }
952 }
953 
954 
955 /*--------------- xgbint_ver ()--------------------*/
956 /* sometimes returns points */
957 static CRef<CSeq_loc> xgbint_ver(bool& keep_rawPt,
958  TTokenIt& currentPt,
959  const TTokens& tokens,
960  int& numErrors,
961  const TSeqIdList& seq_ids,
962  bool accver)
963 {
964  auto ret = Ref(new CSeq_loc());
965 
966  CRef<CSeq_id> new_id;
967  CRef<CInt_fuzz> new_fuzz;
968  auto end_it = end(tokens);
969 
970  if (currentPt->choice == ETokenType::eAccession) {
971  if (accver && currentPt->data.find('.') >= currentPt->data.size() - 1) {
972  xgbparse_error("Missing accession's version",
973  tokens,
974  currentPt);
975  }
976 
977  new_id = Ref(new CSeq_id(currentPt->data));
978 
979  ++currentPt;
980  if (currentPt == end_it) {
981  xgbparse_error("Nothing after accession",
982  tokens,
983  currentPt);
984  new_id.Reset();
985  keep_rawPt = true;
986  ++numErrors;
987  return CRef<CSeq_loc>();
988  }
989 
990  } else if (! seq_ids.empty()) {
991  new_id.Reset(new CSeq_id());
992  new_id->Assign(*(*seq_ids.begin()));
993  }
994 
995  if (currentPt->choice == ETokenType::eLt) {
996  new_fuzz.Reset(new CInt_fuzz);
997  new_fuzz->SetLim(CInt_fuzz::eLim_lt);
998 
999  ++currentPt;
1000  if (currentPt == end_it) {
1001  xgbparse_error("Nothing after \'<\'",
1002  tokens,
1003  currentPt);
1004  keep_rawPt = true;
1005  ++numErrors;
1006  return CRef<CSeq_loc>();
1007  }
1008  }
1009 
1010  if (! numErrors) {
1011  switch (currentPt->choice) {
1013  if (new_id.NotEmpty()) {
1014  xgbparse_error("duplicate accessions",
1015  tokens,
1016  currentPt);
1017  keep_rawPt = true;
1018  ++numErrors;
1019  return CRef<CSeq_loc>();
1020  }
1021  break;
1022  case ETokenType::eCaret:
1023  xgbparse_error("caret (^) before number",
1024  tokens,
1025  currentPt);
1026  keep_rawPt = true;
1027  ++numErrors;
1028  return CRef<CSeq_loc>();
1029  case ETokenType::eLt:
1030  if (new_id.NotEmpty()) {
1031  xgbparse_error("duplicate \'<\'",
1032  tokens,
1033  currentPt);
1034  keep_rawPt = true;
1035  ++numErrors;
1036  return CRef<CSeq_loc>();
1037  }
1038  break;
1039  case ETokenType::eGt:
1040  case ETokenType::eNumber:
1041  case ETokenType::eLeft:
1042 
1043  case ETokenType::eOneOfNum:
1044  if (new_fuzz.NotEmpty())
1045  ret->SetInt().SetFuzz_from(*new_fuzz);
1046  if (new_id.NotEmpty())
1047  ret->SetInt().SetId(*new_id);
1048 
1049  xgbload_number(ret->SetInt().SetFrom(), ret->SetInt().SetFuzz_from(), keep_rawPt, currentPt, tokens, numErrors, TAKE_FIRST);
1050 
1051  if (ret->GetInt().GetFuzz_from().Which() == CInt_fuzz::e_not_set)
1052  ret->SetInt().ResetFuzz_from();
1053 
1054  xgbcheck_range(ret->GetInt().GetFrom(), *new_id, keep_rawPt, numErrors, tokens, currentPt);
1055 
1056  if (numErrors) {
1057  return CRef<CSeq_loc>();
1058  }
1059 
1060  if (currentPt != end_it) {
1061  bool in_caret = false;
1062  switch (currentPt->choice) {
1063  default:
1064  case ETokenType::eJoin:
1065  case ETokenType::eCompl:
1067  case ETokenType::eOrder:
1068  case ETokenType::eGroup:
1070  xgbparse_error("problem with 2nd number",
1071  tokens,
1072  currentPt);
1073  keep_rawPt = true;
1074  ++numErrors;
1075  return CRef<CSeq_loc>();
1076  case ETokenType::eComma:
1077  case ETokenType::eRight: /* valid thing to leave on*/
1078  /*--------------but have a point, not an interval----*/
1079  sConvertIntToPoint(*ret);
1080  break;
1081 
1082  case ETokenType::eGt:
1083  case ETokenType::eLt:
1084  xgbparse_error("Missing \'..\'",
1085  tokens,
1086  currentPt);
1087  keep_rawPt = true;
1088  ++numErrors;
1089  return CRef<CSeq_loc>();
1090  case ETokenType::eCaret:
1091  if (ret->GetInt().IsSetFuzz_from()) {
1092  xgbparse_error("\'<\' then \'^\'",
1093  tokens,
1094  currentPt);
1095  keep_rawPt = true;
1096  ++numErrors;
1097  return CRef<CSeq_loc>();
1098  }
1099 
1100  ret->SetInt().SetFuzz_from().SetLim(CInt_fuzz::eLim_tl);
1101  ret->SetInt().SetFuzz_to().SetLim(CInt_fuzz::eLim_tl);
1102  in_caret = true;
1103  /*---no break on purpose ---*/
1105  case ETokenType::eDotDot:
1106  ++currentPt;
1107  if (currentPt == end_it) {
1108  xgbparse_error("unexpected end of usable tokens",
1109  tokens,
1110  currentPt);
1111  keep_rawPt = true;
1112  ++numErrors;
1113  return CRef<CSeq_loc>();
1114  }
1115  /*--no break on purpose here ---*/
1117  case ETokenType::eNumber:
1118  case ETokenType::eLeft:
1119 
1120  case ETokenType::eOneOfNum: /* unlikely, but ok */
1121  if (currentPt->choice == ETokenType::eRight) {
1122  if (ret->GetInt().IsSetFuzz_from()) {
1123  xgbparse_error("\'^\' then \'>\'",
1124  tokens,
1125  currentPt);
1126  keep_rawPt = true;
1127  ++numErrors;
1128  return CRef<CSeq_loc>();
1129  }
1130  }
1131 
1132  xgbload_number(ret->SetInt().SetTo(), ret->SetInt().SetFuzz_to(), keep_rawPt, currentPt, tokens, numErrors, TAKE_SECOND);
1133 
1134  if (ret->GetInt().GetFuzz_to().Which() == CInt_fuzz::e_not_set)
1135  ret->SetInt().ResetFuzz_to();
1136 
1137  xgbcheck_range(ret->GetInt().GetTo(), *new_id, keep_rawPt, numErrors, tokens, currentPt);
1138 
1139  /*----------
1140  * The caret location implies a place (point) between two location.
1141  * This is not exactly captured by the ASN.1, but pretty close
1142  *-------*/
1143  if (in_caret) {
1144  TSeqPos to = ret->GetInt().GetTo();
1145 
1146  sConvertIntToPoint(*ret);
1147  CSeq_point& point = ret->SetPnt();
1148  if (point.GetPoint() + 1 == to) {
1149  point.SetPoint(to); /* was essentailly correct */
1150  } else {
1151  point.SetFuzz().SetRange().SetMax(to);
1152  point.SetFuzz().SetRange().SetMin(point.GetPoint());
1153  }
1154  }
1155 
1156  if (ret->IsInt() &&
1157  ret->GetInt().GetFrom() == ret->GetInt().GetTo() &&
1158  ! ret->GetInt().IsSetFuzz_from() &&
1159  ! ret->GetInt().IsSetFuzz_to()) {
1160  /*-------if interval really a point, make is so ----*/
1161  sConvertIntToPoint(*ret);
1162  }
1163  } /* end switch */
1164  } else {
1165  sConvertIntToPoint(*ret);
1166  }
1167  break;
1168  default:
1169  xgbparse_error("No number when expected",
1170  tokens,
1171  currentPt);
1172  keep_rawPt = true;
1173  ++numErrors;
1174  return CRef<CSeq_loc>();
1175  }
1176  }
1177 
1178  return ret;
1179 }
1180 
1181 
1182 class CGBLocException : exception
1183 {
1184 };
1185 
1186 static CRef<CSeq_loc> xgbloc_ver(bool& keep_rawPt, int& parenPt, TTokenIt& currentPt, const TTokens& tokens, int& numErrors, const TSeqIdList& seq_ids, bool accver)
1187 {
1188  CRef<CSeq_loc> retval;
1189 
1190  bool add_nulls = false;
1191  auto current_token = currentPt;
1192  bool did_complement = false;
1193  bool in_sites;
1194  auto end_it = end(tokens);
1195 
1196  try {
1197  do {
1198  in_sites = false;
1199  switch (current_token->choice) {
1200  case ETokenType::eCompl:
1201  ++currentPt;
1202  if (currentPt == end_it) {
1203  xgbparse_error("unexpected end of usable tokens",
1204  tokens,
1205  currentPt);
1206  throw CGBLocException();
1207  }
1208  if (currentPt->choice != ETokenType::eLeft) {
1209  xgbparse_error("Missing \'(\'", /* paran match ) */
1210  tokens,
1211  currentPt);
1212  throw CGBLocException();
1213  }
1214 
1215  ++parenPt;
1216  ++currentPt;
1217  if (currentPt == end_it) {
1218  xgbparse_error("illegal null contents",
1219  tokens,
1220  currentPt);
1221  throw CGBLocException();
1222  }
1223 
1224  if (currentPt->choice == ETokenType::eRight) { /* paran match ( */
1225  xgbparse_error("Premature \')\'",
1226  tokens,
1227  currentPt);
1228  throw CGBLocException();
1229  }
1230  retval = xgbloc_ver(keep_rawPt, parenPt, currentPt, tokens, numErrors, seq_ids, accver);
1231 
1232  if (retval.NotEmpty())
1233  retval = sequence::SeqLocRevCmpl(*retval, nullptr);
1234 
1235  did_complement = true;
1236  if (currentPt != end_it) {
1237  if (currentPt->choice != ETokenType::eRight) {
1238  xgbparse_error("Missing \')\'",
1239  tokens,
1240  currentPt);
1241  throw CGBLocException();
1242  }
1243  --parenPt;
1244  ++currentPt;
1245  } else {
1246  xgbparse_error("Missing \')\'",
1247  tokens,
1248  currentPt);
1249  throw CGBLocException();
1250  }
1251  break;
1252  /* REAL LOCS */
1253  case ETokenType::eJoin:
1254  retval = Ref(new CSeq_loc());
1255  retval->SetMix();
1256  break;
1257  case ETokenType::eOrder:
1258  retval = Ref(new CSeq_loc);
1259  retval->SetMix();
1260  add_nulls = true;
1261  break;
1262  case ETokenType::eGroup:
1263  retval = Ref(new CSeq_loc);
1264  retval->SetMix();
1265  keep_rawPt = true;
1266  break;
1267  case ETokenType::eOneOf:
1268  retval = Ref(new CSeq_loc);
1269  retval->SetEquiv();
1270  break;
1271 
1272  /* ERROR */
1273  case ETokenType::eString:
1274  xgbparse_error("string in loc",
1275  tokens,
1276  current_token);
1277  throw CGBLocException();
1278  /*--- no break on purpose---*/
1279  default:
1280  case ETokenType::eUnknown:
1281  case ETokenType::eRight:
1282  case ETokenType::eDotDot:
1283  case ETokenType::eComma:
1285  xgbparse_error("illegal initial loc token",
1286  tokens,
1287  currentPt);
1288  throw CGBLocException();
1289 
1290  /* Interval, occurs on recursion */
1291  case ETokenType::eGap:
1292  xgbgap(currentPt, end_it, retval, false);
1293  break;
1294  case ETokenType::eUnkGap:
1295  xgbgap(currentPt, end_it, retval, true);
1296  break;
1297 
1299  case ETokenType::eCaret:
1300  case ETokenType::eGt:
1301  case ETokenType::eLt:
1302  case ETokenType::eNumber:
1303  case ETokenType::eLeft:
1304  case ETokenType::eOneOfNum:
1305  retval = xgbint_ver(keep_rawPt, currentPt, tokens, numErrors, seq_ids, accver);
1306  break;
1307 
1308  case ETokenType::eReplace:
1309  /*-------illegal at this level --*/
1310  xgbparse_error("illegal replace",
1311  tokens,
1312  currentPt);
1313  throw CGBLocException();
1314  case ETokenType::eSites:
1315  in_sites = true;
1316  ++currentPt;
1317  break;
1318  }
1319  } while (in_sites && currentPt != end_it);
1320 
1321  if (! numErrors && ! did_complement && retval &&
1322  ! retval->IsNull() && ! retval->IsInt() && ! retval->IsPnt()) {
1323  /*--------
1324  * ONLY THE CHOICE has been set. the "join", etc. only has been noted
1325  *----*/
1326  ++currentPt;
1327  if (currentPt == end_it) {
1328  xgbparse_error("unexpected end of interval tokens",
1329  tokens,
1330  currentPt);
1331  throw CGBLocException();
1332  }
1333 
1334  if (currentPt->choice != ETokenType::eLeft) {
1335  xgbparse_error("Missing \'(\'",
1336  tokens,
1337  currentPt); /* paran match ) */
1338  throw CGBLocException();
1339  }
1340 
1341  ++parenPt;
1342  ++currentPt;
1343  if (currentPt == end_it) {
1344  xgbparse_error("illegal null contents",
1345  tokens,
1346  currentPt);
1347  throw CGBLocException();
1348  }
1349 
1350  if (currentPt->choice == ETokenType::eRight) { /* paran match ( */
1351  xgbparse_error("Premature \')\'",
1352  tokens,
1353  currentPt);
1354  throw CGBLocException();
1355  }
1356 
1357  while (! numErrors && currentPt != end_it) {
1358  if (currentPt->choice == ETokenType::eRight) {
1359  while (currentPt != end_it &&
1360  currentPt->choice == ETokenType::eRight) {
1361  --parenPt;
1362  }
1363  break;
1364  }
1365 
1366  if (currentPt == end_it)
1367  break;
1368 
1369  CRef<CSeq_loc> next_loc = xgbloc_ver(keep_rawPt, parenPt, currentPt, tokens, numErrors, seq_ids, accver);
1370  if (next_loc.NotEmpty()) {
1371  if (retval->IsMix())
1372  retval->SetMix().AddSeqLoc(*next_loc);
1373  else // equiv
1374  retval->SetEquiv().Add(*next_loc);
1375  }
1376 
1377  if (currentPt == end_it || currentPt->choice == ETokenType::eRight)
1378  break;
1379 
1380  if (currentPt->choice == ETokenType::eComma) {
1381  ++currentPt;
1382  if (add_nulls) {
1383  CRef<CSeq_loc> null_loc(new CSeq_loc);
1384  null_loc->SetNull();
1385 
1386  if (retval->IsMix())
1387  retval->SetMix().AddSeqLoc(*null_loc);
1388  else // equiv
1389  retval->SetEquiv().Add(*null_loc);
1390  }
1391  } else {
1392  xgbparse_error("Illegal token after interval",
1393  tokens,
1394  currentPt);
1395  throw CGBLocException();
1396  }
1397  }
1398 
1399  if (currentPt == end_it) {
1400  xgbparse_error("unexpected end of usable tokens",
1401  tokens,
1402  currentPt);
1403  throw CGBLocException();
1404  }
1405 
1406  if (currentPt->choice != ETokenType::eRight) {
1407  xgbparse_error("Missing \')\'" /* paran match ) */,
1408  tokens,
1409  currentPt);
1410  throw CGBLocException();
1411  }
1412  --parenPt;
1413  ++currentPt;
1414  }
1415  } catch (CGBLocException&) {
1416  keep_rawPt = true;
1417  ++numErrors;
1418  if (retval) {
1419  retval->Reset();
1420  retval->SetWhole().Assign(*(*seq_ids.begin()));
1421  }
1422  }
1423 
1424  return retval;
1425 }
1426 
1427 
1428 static CRef<CSeq_loc> xgbreplace_ver(bool& keep_rawPt, int& parenPt, TTokenIt& currentPt, const TTokens& tokens, int& numErrors, const TSeqIdList& seq_ids, bool accver)
1429 {
1430  CRef<CSeq_loc> ret;
1431 
1432  keep_rawPt = true;
1433  ++currentPt;
1434 
1435  if (currentPt->choice == ETokenType::eLeft) {
1436  ++currentPt;
1437  ret = xgbloc_ver(keep_rawPt, parenPt, currentPt, tokens, numErrors, seq_ids, accver);
1438 
1439  if (currentPt == end(tokens)) {
1440  xgbparse_error("unexpected end of interval tokens",
1441  tokens,
1442  currentPt);
1443  keep_rawPt = true;
1444  ++numErrors;
1445  } else if (currentPt->choice != ETokenType::eComma) {
1446  xgbparse_error("Missing comma after first location in replace",
1447  tokens,
1448  currentPt);
1449  ++numErrors;
1450  }
1451  } else {
1452  xgbparse_error("Missing \'(\'" /* paran match ) */
1453  ,
1454  tokens,
1455  currentPt);
1456  ++numErrors;
1457  }
1458 
1459  return ret;
1460 }
1461 
1462 
1463 /*---------- xgbparseint_ver()-----*/
1464 
1465 CRef<CSeq_loc> xgbparseint_ver(string_view raw_intervals, bool& keep_rawPt, int& numErrors, const TSeqIdList& seq_ids, bool accver)
1466 {
1467  keep_rawPt = false;
1468 
1469  TTokens tokens;
1470  numErrors = xgbparselex_ver(raw_intervals, tokens, accver);
1471 
1472  if (tokens.empty()) {
1473  numErrors = 1;
1474  return CRef<CSeq_loc>();
1475  }
1476 
1477  if (numErrors) {
1478  keep_rawPt = true;
1479  return CRef<CSeq_loc>();
1480  }
1481 
1482  CRef<CSeq_loc> ret;
1483  xfind_one_of_num(tokens);
1484  auto head_token = tokens.begin();
1485  auto current_token = head_token;
1486  auto end_it = tokens.end();
1487 
1488  int paren_count = 0;
1489  bool in_sites;
1490  do {
1491  in_sites = false;
1492  if (current_token != end_it) {
1493  switch (current_token->choice) {
1494  case ETokenType::eJoin:
1495  case ETokenType::eOrder:
1496  case ETokenType::eGroup:
1497  case ETokenType::eOneOf:
1498  case ETokenType::eCompl:
1499  ret = xgbloc_ver(keep_rawPt, paren_count, current_token, tokens, numErrors, seq_ids, accver);
1500  /* need to check that out of tokens here */
1501  xgbparse_better_be_done(numErrors, current_token, tokens, keep_rawPt, paren_count);
1502  break;
1503 
1504  case ETokenType::eString:
1505  xgbparse_error("string in loc", tokens, current_token);
1506  keep_rawPt = true;
1507  ++numErrors;
1508  /* no break on purpose */
1510  case ETokenType::eUnknown:
1511  default:
1512  case ETokenType::eRight:
1513  case ETokenType::eDotDot:
1514  case ETokenType::eComma:
1516  xgbparse_error("illegal initial token", tokens, current_token);
1517  keep_rawPt = true;
1518  ++numErrors;
1519  ++current_token;
1520  break;
1521 
1523  /*--- no warn, but strange ---*/
1524  /*-- no break on purpose ---*/
1525 
1526  case ETokenType::eCaret:
1527  case ETokenType::eGt:
1528  case ETokenType::eLt:
1529  case ETokenType::eNumber:
1530  case ETokenType::eLeft:
1531  case ETokenType::eOneOfNum:
1532  ret = xgbint_ver(keep_rawPt, current_token, tokens, numErrors, seq_ids, accver);
1533  /* need to check that out of tokens here */
1534  xgbparse_better_be_done(numErrors, current_token, tokens, keep_rawPt, paren_count);
1535  break;
1536 
1537  case ETokenType::eReplace:
1538  ret = xgbreplace_ver(keep_rawPt, paren_count, current_token, tokens, numErrors, seq_ids, accver);
1539  keep_rawPt = true;
1540  /*---all errors handled within this function ---*/
1541  break;
1542  case ETokenType::eSites:
1543  in_sites = true;
1544  ++current_token;
1545  break;
1546  }
1547  }
1548  } while (in_sites && current_token != end_it);
1549 
1550  if (numErrors) {
1551  return CRef<CSeq_loc>();
1552  }
1553 
1554  return ret;
1555 }
1556 
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
std::list< CRef< objects::CSeq_id > > TSeqIdList
Definition: ftablock.h:58
void Nlm_ErrSetContext(const char *module, const char *fname, int line)
Definition: ftaerr.cpp:452
void Nlm_ErrPostStr(ErrSev sev, int lev1, int lev2, string_view str)
Definition: ftaerr.cpp:594
static DLIST_TYPE *DLIST_NAME() next(DLIST_LIST_TYPE *list, DLIST_TYPE *item)
Definition: dlist.tmpl.h:56
char data[12]
Definition: iconv.c:80
#define SEV_ERROR
Definition: gicache.c:91
unsigned int TSeqPos
Type for sequence locations and lengths.
Definition: ncbimisc.hpp:875
string
Definition: cgiapp.hpp:690
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
static void TruncateSpacesInPlace(string &str, ETrunc where=eTrunc_Both)
Truncate whitespace in a string (in-place)
Definition: ncbistr.cpp:3192
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:5406
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
@ 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.
static SLJIT_INLINE sljit_ins msg(sljit_gpr r, sljit_s32 d, sljit_gpr x, sljit_gpr b)
string data
Definition: xgbparint.cpp:85
ETokenType choice
Definition: xgbparint.cpp:84
USING_SCOPE(objects)
static void do_xgbparse_error(string_view msg, string_view details)
Definition: xgbparint.cpp:97
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:1186
static void sConvertIntToPoint(CSeq_loc &loc)
Definition: xgbparint.cpp:789
static void xlex_error_func(string_view msg, const string &line, unsigned int current_col)
Definition: xgbparint.cpp:294
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:957
static string xgbparse_point(TTokenConstIt head, TTokenConstIt current)
Definition: xgbparint.cpp:124
static int xgbparselex_ver(string_view linein, TTokens &tokens, bool accver)
Definition: xgbparint.cpp:407
static void xgbgap(TTokenIt &current_it, TTokenConstIt end_it, CRef< CSeq_loc > &loc, bool unknown)
Definition: xgbparint.cpp:754
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_range_data
Definition: xgbparint.cpp:106
const char * seqlitdbtag
Definition: xgbparint.cpp:55
static CRef< CSeq_loc > XGapToSeqLocEx(Int4 range, bool unknown)
Definition: xgbparint.cpp:729
static void xgbparse_error(string_view front, TTokenConstIt head, TTokenConstIt current)
Definition: xgbparint.cpp:191
static void xgbparse_better_be_done(int &numErrors, TTokenIt current_token, const TTokens &tokens, bool &keep_rawPt, int paren_count)
Definition: xgbparint.cpp:685
static int sGetAccession(string &accession, unsigned int &current_col, const string &line, bool accver)
Definition: xgbparint.cpp:367
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:1428
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:805
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:304
static X_gbparse_errfunc Err_func
Definition: xgbparint.cpp:104
CRef< CSeq_loc > xgbparseint_ver(string_view raw_intervals, bool &keep_rawPt, int &numErrors, const TSeqIdList &seq_ids, bool accver)
Definition: xgbparint.cpp:1465
static X_gbparse_rangefunc Range_func
Definition: xgbparint.cpp:105
#define ERR_FEATURE_LocationParsing_validatr
Definition: xgbparint.cpp:95
static size_t sParseAccessionPrefix(string_view accession)
Definition: xgbparint.cpp:317
Int4(* X_gbparse_rangefunc)(void *, const objects::CSeq_id &id)
Definition: xgbparint.h:17
void(* X_gbparse_errfunc)(string_view, string_view)
Definition: xgbparint.h:16
Modified on Fri Sep 20 14:57:37 2024 by modify_doxy.py rev. 669887