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

Go to the SVN repository for this file.

1 /* $Id: Suspect_rule.cpp 98741 2022-12-29 18:00:10Z gotvyans $
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  * Author: J. Chen
27  *
28  * File Description:
29  * suspect product name check against rule
30  *
31  * Remark:
32  * This code was originally generated by application DATATOOL
33  * using the following specifications:
34  * 'macro.asn'.
35  */
36 
37 
38 #include <ncbi_pch.hpp>
40 #include <util/compile_time.hpp>
41 
43 BEGIN_objects_SCOPE // namespace ncbi::objects::
44 
45 
46 static bool IsStringConstraintEmpty(const CString_constraint* constraint)
47 {
48  if (!constraint) {
49  return true;
50  }
51  if (constraint->GetIs_all_caps() || constraint->GetIs_all_lower()|| constraint->GetIs_all_punct()) {
52  return false;
53  }
54  if (!constraint->CanGetMatch_text() || constraint->GetMatch_text().empty()) {
55  return true;
56  }
57  return false;
58 }
59 
60 
61 static const string SkipWeasel(const string& str)
62 {
63  static constexpr std::array<string_view, 10> weasels = {
64  "candidate",
65  "hypothetical",
66  "novel",
67  "possible",
68  "potential",
69  "predicted,"
70  "probable",
71  "putative",
72  "uncharacterized",
73  "unique",
74  };
75 
76  if (str.empty()) {
77  return kEmptyStr;
78  }
79  string ret_str;
80  vector <string> arr;
81  arr = NStr::Split(str, " ", arr, 0);
82  if (arr.size() == 1) {
83  return str;
84  }
85  int i;
86  unsigned len, len_w;
87  bool find_w;
88  for (i=0; i< (int)(arr.size() - 1); i++) {
89  len = arr[i].size();
90  find_w = false;
91  for(auto& it: weasels) {
92  len_w = it.size();
93  if (len != len_w || !NStr::EqualNocase(arr[i], 0, len, it)) {
94  continue;
95  }
96  else {
97  find_w = true;
98  break;
99  }
100  }
101  if (!find_w) {
102  break;
103  }
104  }
105  for ( ; i< (int)(arr.size()-1); i++) {
106  ret_str += arr[i] + ' ';
107  }
108  ret_str += arr[arr.size()-1];
109  return (ret_str);
110 }
111 
112 
113 bool IsAllCaps(const string& str)
114 {
115  string up_str = str;
116  //if (up_str.find_first_not_of(alpha_str) != string::npos) return false;
117  up_str = NStr::ToUpper(up_str);
118  if (up_str == str) return true;
119  else return false;
120 }
121 
122 
123 bool IsAllLowerCase(const string& str)
124 {
125  string low_str = str;
126  //if (low_str.find_first_not_of(alpha_str) != string::npos) return false;
127  low_str = NStr::ToLower(low_str);
128  if (low_str == str) return true;
129  else return false;
130 }
131 
132 
133 bool IsAllPunctuation(const string& str)
134 {
135  for (unsigned i=0; i< str.size(); i++) {
136  if (!ispunct(str[i])) return false;
137  }
138  return true;
139 }
140 
141 
142 static bool CaseNCompareEqual(string str1, string str2, unsigned len1, bool case_sensitive)
143 {
144  if (!len1) {
145  return false;
146  }
147  string comp_str1, comp_str2;
148  comp_str1 = str1.substr(0, len1);
149  comp_str2 = str2.substr(0, len1);
150  if (case_sensitive) {
151  return (comp_str1 == comp_str2);
152  }
153  else {
154  return (NStr::EqualNocase(comp_str1, 0, len1, comp_str2));
155  }
156 }
157 
158 
159 static bool AdvancedStringCompare(const string& str, const string& str_match, const CString_constraint* str_cons, bool is_start, unsigned* ini_target_match_len = 0)
160 {
161  if (!str_cons) {
162  return true;
163  }
164 
165  size_t pos_match = 0, pos_str = 0;
166  bool wd_case, whole_wd, word_start_m, word_start_s;
167  bool match = true, recursive_match = false;
168  unsigned len_m = str_match.size(), len_s = str.size(), target_match_len=0;
169  string cp_m, cp_s;
170  bool ig_space = str_cons->GetIgnore_space();
171  bool ig_punct = str_cons->GetIgnore_punct();
172  bool str_case = str_cons->GetCase_sensitive();
173  EString_location loc = str_cons->GetMatch_location();
174  unsigned len1, len2;
175  char ch1, ch2;
176  vector <string> word_word;
177  bool has_word = !(str_cons->GetIgnore_words().Get().empty());
178  string strtmp;
179  ITERATE (list <CRef <CWord_substitution> >, it, str_cons->GetIgnore_words().Get()) {
180  strtmp = ((*it)->CanGetWord()) ? (*it)->GetWord() : kEmptyStr;
181  word_word.push_back(strtmp);
182  }
183 
184  unsigned i;
185  while (match && pos_match < len_m && pos_str < len_s && !recursive_match) {
186  cp_m = str_match.substr(pos_match);
187  cp_s = str.substr(pos_str);
188 
189  /* first, check to see if we're skipping synonyms */
190  i=0;
191  if (has_word) {
192  ITERATE (list <CRef <CWord_substitution> >, it, str_cons->GetIgnore_words().Get()) {
193  wd_case = (*it)->GetCase_sensitive();
194  whole_wd = (*it)->GetWhole_word();
195  len1 = word_word[i].size();
196  //text match
197  if (CaseNCompareEqual(word_word[i++], cp_m, len1, wd_case)) {
198  word_start_m = (!pos_match && is_start) || !isalpha(str_match[pos_match - 1]);
199  ch1 = (cp_m.size() <= len1) ? ' ' : cp_m[len1];
200 
201  // whole word mch
202  if (!whole_wd || (!isalpha(ch1) && word_start_m)) {
203  if ( !(*it)->CanGetSynonyms() || (*it)->GetSynonyms().empty()) {
204  if (AdvancedStringCompare(cp_s, cp_m.substr(len1), str_cons, word_start_m, &target_match_len)) {
205  recursive_match = true;
206  break;
207  }
208  }
209  else {
210  ITERATE (list <string>, sit, (*it)->GetSynonyms()) {
211  len2 = (*sit).size();
212 
213  // text match
214  if (CaseNCompareEqual(*sit, cp_s, len2, wd_case)) {
215  word_start_s = (!pos_str && is_start) || !isalpha(str[pos_str - 1]);
216  ch2 = (cp_s.size() <= len2) ? ' ' : cp_s[len2];
217  // whole word match
218  if (!whole_wd || (!isalpha(ch2) && word_start_s)) {
219  if (AdvancedStringCompare(cp_s.substr(len2), cp_m.substr(len1), str_cons, word_start_m & word_start_s, &target_match_len)) {
220  recursive_match = true;
221  break;
222  }
223  }
224  }
225  }
226  }
227  }
228  }
229  }
230  }
231 
232  if (!recursive_match) {
233  if (CaseNCompareEqual(cp_m, cp_s, 1, str_case)) {
234  pos_match++;
235  pos_str++;
236  target_match_len++;
237  }
238  else if ( ig_space && (isspace(cp_m[0]) || isspace(cp_s[0])) ) {
239  if (isspace(cp_m[0])) {
240  pos_match++;
241  }
242  if (isspace(cp_s[0])) {
243  pos_str++;
244  target_match_len++;
245  }
246  }
247  else if (ig_punct && ( ispunct(cp_m[0]) || ispunct(cp_s[0]) )) {
248  if (ispunct(cp_m[0])) {
249  pos_match++;
250  }
251  if (ispunct(cp_s[0])) {
252  pos_str++;
253  target_match_len++;
254  }
255  }
256  else {
257  match = false;
258  }
259  }
260  }
261 
262  if (match && !recursive_match) {
263  while (pos_str < str.size() && ((ig_space && isspace(str[pos_str])) || (ig_punct && ispunct(str[pos_str])))) {
264  pos_str++;
265  target_match_len++;
266  }
267  while (pos_match < str_match.size() && ((ig_space && isspace(str_match[pos_match])) || (ig_punct && ispunct(str_match[pos_match])))) {
268  pos_match++;
269  }
270 
271  if (pos_match < str_match.size()) {
272  match = false;
273  }
274  else if ((loc == eString_location_ends || loc == eString_location_equals) && pos_str < len_s) {
275  match = false;
276  }
277  else if (str_cons->GetWhole_word() && (!is_start || (pos_str < len_s && isalpha (str[pos_str])))) {
278  match = false;
279  }
280  }
281  if (match && ini_target_match_len) {
282  *ini_target_match_len += target_match_len;
283  }
284  return match;
285 }
286 
287 
288 static bool AdvancedStringMatch(const string& str, const CString_constraint* str_cons)
289 {
290  if (!str_cons) {
291  return true;
292  }
293  bool rval = false;
294  string match_text = str_cons->CanGetMatch_text() ? str_cons->GetMatch_text() : kEmptyStr;
295 
296  if (AdvancedStringCompare(str, match_text, str_cons, true)) {
297  return true;
298  }
299  else if (str_cons->GetMatch_location() == eString_location_starts || str_cons->GetMatch_location() == eString_location_equals) {
300  return false;
301  }
302  else {
303  size_t pos = 1;
304  unsigned len = str.size();
305  while (!rval && pos < len) {
306  if (str_cons->GetWhole_word()) {
307  while (pos < len && isalpha (str[pos-1])) pos++;
308  }
309  if (pos < len) {
310  if (AdvancedStringCompare(str.substr(pos), match_text, str_cons, true)) rval = true;
311  else pos++;
312  }
313  }
314  }
315  return rval;
316 }
317 
318 
319 static bool DisallowCharacter(const char ch, bool disallow_slash)
320 {
321  if (isalpha(ch) || isdigit(ch) || ch == '_' || ch == '-') {
322  return true;
323  }
324  else if (disallow_slash && ch == '/') {
325  return true;
326  }
327  return false;
328 }
329 
330 
331 static string StripUnimportantCharacters(const string& str, bool strip_space, bool strip_punct)
332 {
333  if (str.empty()) {
334  return kEmptyStr;
335  }
336  string result;
337  result.reserve(str.size());
338  string::const_iterator it = str.begin();
339  do {
340  if ((strip_space && isspace(*it)) || (strip_punct && ispunct(*it))) {
341  }
342  else {
343  result += *it;
344  }
345  } while (++it != str.end());
346 
347  return result;
348 }
349 
350 
351 static bool IsWholeWordMatch(const string& start, const size_t& found, const unsigned& match_len, bool disallow_slash = false)
352 {
353  bool rval = true;
354  unsigned after_idx;
355 
356  if (!match_len) {
357  rval = true;
358  }
359  else if (start.empty() || found == string::npos) {
360  rval = false;
361  }
362  else {
363  if (found) {
364  if (DisallowCharacter(start[found-1], disallow_slash)) {
365  return false;
366  }
367  }
368  after_idx = found + match_len;
369  if (after_idx < start.size() && DisallowCharacter(start[after_idx], disallow_slash)) {
370  rval = false;
371  }
372  }
373  return rval;
374 }
375 
376 
377 static bool GetSpanFromHyphenInString(const string& str, const size_t& hyphen, string& first, string& second)
378 {
379  if (!hyphen) {
380  return false;
381  }
382 
383  /* find range start */
384  size_t cp = str.substr(0, hyphen-1).find_last_not_of(' ');
385  if (cp != string::npos) {
386  cp = str.substr(0, cp).find_last_not_of(" ,;");
387  }
388  if (cp == string::npos) {
389  cp = 0;
390  }
391 
392  unsigned len = hyphen - cp;
393  first = str.substr(cp, len);
395 
396  /* find range end */
397  cp = str.find_first_not_of(' ', hyphen+1);
398  if (cp != string::npos) {
399  cp = str.find_first_not_of(" ,;");
400  }
401  if (cp == string::npos) {
402  cp = str.size() -1;
403  }
404 
405  len = cp - hyphen;
406  if (!isspace (str[cp])) {
407  len--;
408  }
409  second = str.substr(hyphen+1, len);
411 
412  bool rval = true;
413  if (first.empty() || second.empty()) {
414  rval = false;
415  }
416  else if (!isdigit (first[first.size() - 1]) || !isdigit (second[second.size() - 1])) {
417  /* if this is a span, then neither end point can end with anything other than a number */
418  rval = false;
419  }
420  if (!rval) {
421  first = second = kEmptyStr;
422  }
423  return rval;
424 }
425 
426 
427 static bool StringIsPositiveAllDigits(const string& str)
428 {
429  if (str.find_first_not_of(digit_str) != string::npos) {
430  return false;
431  }
432  return true;
433 }
434 
435 
436 static bool IsStringInSpan(const string& str, const string& first, const string& second)
437 {
438  string new_first, new_second, new_str;
439  if (str.empty()) {
440  return false;
441  }
442  else if (str == first || str == second) {
443  return true;
444  }
445  else if (first.empty() || second.empty()) {
446  return false;
447  }
448 
449  int str_num, first_num, second_num;
450  str_num = first_num = second_num = 0;
451  bool rval = false;
452  size_t prefix_len;
453  string comp_str1, comp_str2;
456  str_num = NStr::StringToUInt (str);
457  first_num = NStr::StringToUInt (first);
458  second_num = NStr::StringToUInt (second);
459  if ((str_num > first_num && str_num < second_num) || (str_num > second_num && str_num < first_num)) {
460  rval = true;
461  }
462  }
463  }
464  else if (StringIsPositiveAllDigits(second)) {
465  prefix_len = first.find_first_of(digit_str) + 1;
466 
467  new_str = str.substr(prefix_len - 1);
468  new_first = first.substr(prefix_len - 1);
469  comp_str1 = str.substr(0, prefix_len);
470  comp_str2 = first.substr(0, prefix_len);
471  if (comp_str1 == comp_str2 && StringIsPositiveAllDigits (new_str) && StringIsPositiveAllDigits (new_first)) {
472  first_num = NStr::StringToUInt(new_first);
473  second_num = NStr::StringToUInt (second);
474  str_num = NStr::StringToUInt (str);
475  if ((str_num > first_num && str_num < second_num) || (str_num > second_num && str_num < first_num)) {
476  rval = true;
477  }
478  }
479  }
480  else {
481  /* determine length of prefix */
482  prefix_len = 0;
483  while (prefix_len < first.size() && prefix_len < second.size() && first[prefix_len] == second[prefix_len]) {
484  prefix_len ++;
485  }
486  prefix_len ++;
487 
488  comp_str1 = str.substr(0, prefix_len);
489  comp_str2 = first.substr(0, prefix_len);
490  if (prefix_len <= first.size() && prefix_len <= second.size() && isdigit (first[prefix_len-1]) && isdigit (second[prefix_len-1]) && comp_str1 == comp_str2) {
491  new_first = first.substr(prefix_len);
492  new_second = second.substr(prefix_len);
493  new_str = str.substr(prefix_len);
494  if (StringIsPositiveAllDigits (new_first) && StringIsPositiveAllDigits (new_second) && StringIsPositiveAllDigits (new_str)) {
495  first_num = NStr::StringToUInt(new_first);
496  second_num = NStr::StringToUInt (new_second);
497  str_num = NStr::StringToUInt (new_str);
498  if ((str_num > first_num && str_num < second_num) || (str_num > second_num && str_num < first_num)) {
499  rval = true;
500  }
501  }
502  else {
503  /* determine whether there is a suffix */
504  size_t idx1, idx2, idx_str;
505  string suf1, suf2, sub_str;
506  idx1 = first.find_first_not_of(digit_str);
507  suf1 = first.substr(prefix_len + idx1);
508  idx2 = second.find_first_not_of(digit_str);
509  suf2 = second.substr(prefix_len + idx2);
510  idx_str = str.find_first_not_of(digit_str);
511  sub_str = str.substr(prefix_len + idx_str);
512  if (suf1 == suf2 && suf1 == sub_str) {
513  /* suffixes match */
514  first_num = NStr::StringToUInt(CTempString(first).substr(prefix_len, idx1));
515  second_num = NStr::StringToUInt(CTempString(second).substr(prefix_len, idx2));
516  str_num = NStr::StringToUInt(CTempString(str).substr(prefix_len, idx_str));
517  if ((str_num > first_num && str_num < second_num) || (str_num > second_num && str_num < first_num)) {
518  rval = true;
519  }
520  }
521  }
522  }
523  }
524  return rval;
525 }
526 
527 
528 static bool IsStringInSpanInList(const string& str, const string& list)
529 {
530  if (list.empty() || str.empty()) {
531  return false;
532  }
533 
534  size_t idx = str.find_first_not_of(alpha_str);
535  if (idx == string::npos) {
536  return false;
537  }
538 
539  idx = str.substr(idx).find_first_not_of(digit_str);
540 
541  /* find ranges */
542  size_t hyphen = list.find('-');
543  bool rval = false;
544  string range_start, range_end;
545  while (hyphen != string::npos && !rval) {
546  if (!hyphen) {
547  hyphen = list.substr(1).find('-');
548  }
549  else {
550  if (GetSpanFromHyphenInString(list, hyphen, range_start, range_end)) {
551  if (IsStringInSpan(str, range_start, range_end)) {
552  rval = true;
553  }
554  }
555  hyphen = list.find('-', hyphen + 1);
556  }
557  }
558  return rval;
559 }
560 
561 
562 static bool DoesSingleStringMatchConstraint(const string& str, const CString_constraint* str_cons)
563 {
564  bool rval = false;
565  string tmp_match;
566  CString_constraint tmp_cons;
567 
568  string this_str(str);
569  if (!str_cons) {
570  return true;
571  }
572  if (str.empty()) {
573  return false;
574  }
575  if (IsStringConstraintEmpty(str_cons)) {
576  rval = true;
577  }
578  else {
579  if (str_cons->GetIgnore_weasel()) {
580  this_str = SkipWeasel(str);
581  }
582  if (str_cons->GetIs_all_caps() && !IsAllCaps(this_str)) {
583  rval = false;
584  }
585  else if (str_cons->GetIs_all_lower() && !IsAllLowerCase(this_str)) {
586  rval = false;
587  }
588  else if (str_cons->GetIs_all_punct() && !IsAllPunctuation(this_str)) {
589  rval = false;
590  }
591  else if (!str_cons->CanGetMatch_text() ||str_cons->GetMatch_text().empty()) {
592  rval = true;
593  }
594  else {
595  tmp_cons.Assign(*str_cons);
596  tmp_match = tmp_cons.CanGetMatch_text() ? tmp_cons.GetMatch_text() : kEmptyStr;
597  if (str_cons->GetIgnore_weasel()) {
598  tmp_cons.SetMatch_text(SkipWeasel(str_cons->GetMatch_text()));
599  }
600  if ((str_cons->GetMatch_location() != eString_location_inlist) && str_cons->CanGetIgnore_words()) {
601  tmp_cons.SetMatch_text(tmp_match);
602  rval = AdvancedStringMatch(str, &tmp_cons);
603  }
604  else {
605  string search(this_str), pattern(tmp_cons.GetMatch_text());
606  bool ig_space = str_cons->GetIgnore_space();
607  bool ig_punct = str_cons->GetIgnore_punct();
608  if ( (str_cons->GetMatch_location() != eString_location_inlist) && (ig_space || ig_punct)) {
609  search = StripUnimportantCharacters(search, ig_space, ig_punct);
610  pattern = StripUnimportantCharacters(pattern, ig_space, ig_punct);
611  }
612 
613  size_t pFound = str_cons->GetCase_sensitive() ? search.find(pattern) : NStr::FindNoCase(search, pattern);
614  switch (str_cons->GetMatch_location()) {
616  if (string::npos == pFound) {
617  rval = false;
618  }
619  else if (str_cons->GetWhole_word()) {
620  rval = IsWholeWordMatch (search, pFound, pattern.size());
621  while (!rval && pFound != string::npos) {
622  pFound = (str_cons->GetCase_sensitive()) ?
623  search.find(pattern, pFound+1):
624  NStr::FindNoCase(search, pattern, pFound+1);
625  rval = (pFound != string::npos)?
626  IsWholeWordMatch (search, pFound, pattern.size()):
627  false;
628  }
629  }
630  else {
631  rval = true;
632  }
633  break;
635  if (!pFound) {
636  rval = (str_cons->GetWhole_word()) ? IsWholeWordMatch (search, pFound, pattern.size()) : true;
637  }
638  break;
640  while (pFound != string::npos && !rval) {
641  if ((pFound + pattern.size()) == search.size()) {
642  rval = str_cons->GetWhole_word() ? IsWholeWordMatch (search, pFound, pattern.size()): true;
643  /* stop the search, we're at the end of the string */
644  pFound = string::npos;
645  }
646  else {
647  if (pattern.empty()) {
648  pFound = false;
649  }
650  else {
651  pFound = str_cons->GetCase_sensitive() ? search.find(pattern, pFound+1) : NStr::FindNoCase(search, pattern, pFound+1);
652  }
653  }
654  }
655  break;
657  if (str_cons->GetCase_sensitive() && search==pattern) {
658  rval= true;
659  }
660  else if (!str_cons->GetCase_sensitive() && NStr::EqualNocase(search, pattern)) {
661  rval = true;
662  }
663  break;
665  pFound = (str_cons->GetCase_sensitive())?
666  pattern.find(search) : NStr::FindNoCase(pattern, search);
667  if (pFound == string::npos) {
668  rval = false;
669  }
670  else {
671  rval = IsWholeWordMatch(pattern, pFound, search.size(), true);
672  while (!rval && pFound != string::npos) {
673  pFound = (str_cons->GetCase_sensitive()) ? CTempString(pattern).substr(pFound + 1).find(search) : NStr::FindNoCase(CTempString(pattern).substr(pFound + 1), search);
674  if (pFound != string::npos) {
675  rval = IsWholeWordMatch(pattern, pFound, str.size(), true);
676  }
677  }
678  }
679  if (!rval) {
680  /* look for spans */
681  rval = IsStringInSpanInList (search, pattern);
682  }
683  break;
684  default: break;
685  }
686  }
687  }
688  }
689  return rval;
690 }
691 
692 
694 {
695  // CSearch_func: only about string
696  const CSearch_func& func = GetFind();
697  if (func.Empty() || !func.Match(str)) {
698  return false;
699  }
700  if (CanGetExcept()) {
701  const CSearch_func& exc_func = GetExcept();
702  if (!exc_func.Empty() && exc_func.Match(str)) {
703  return false;
704  }
705  }
706  if (CanGetFeat_constraint()) {
707  const CConstraint_choice_set& conset = GetFeat_constraint();
708  for (auto& it: conset.Get()) {
709  if (it->Which() != CConstraint_choice::e_String) {
710  cerr << "Bad suspect rule constraint!\n";
711  continue;
712  }
713  const CString_constraint& constr = it->GetString();
714  bool b = DoesSingleStringMatchConstraint (str, &constr);
715  if (constr.GetNot_present()) {
716  b = !b;
717  }
718  if (!b) {
719  return false;
720  }
721  }
722  }
723  return true;
724 }
725 
726 
727 bool CSuspect_rule::ApplyToString(string& val) const
728 {
729  return ApplyToString(val, CMatchString(val));
730 }
731 
733 
734 {
736  return false;
737  }
738 
740  if (IsSetFind() && GetFind().IsString_constraint()) {
741  constraint.Reset(&GetFind().GetString_constraint());
742  }
743  return GetReplace().ApplyToString(result, str, constraint);
744 }
745 
746 
748 {
749  string str = "Unknown replacement function";
750  const CReplace_func& func = repl.GetReplace_func();
751  if (func.Which() == CReplace_func::e_Simple_replace) {
752  const CSimple_replace& simple = func.GetSimple_replace();
753  str = "replace ";
754  str += simple.GetWhole_string() ? "entire name with " : "with ";
755  str += simple.CanGetReplace() ? "'" + simple.GetReplace() + "'": "''";
756  str += simple.GetWeasel_to_putative() ? ", retain and normalize 'putative' synonym" : kEmptyStr;
757  }
758  else if (func.Which() == CReplace_func::e_Haem_replace) {
759  str = "replace '" + func.GetHaem_replace() + "' with 'heme' if whole word, 'hem' otherwise";
760  }
761  str += repl.GetMove_to_note() ? ", move original to note" : kEmptyStr;
762  return str;
763 }
764 
765 
767 {
768  if (cons.CanGetMatch_text()) {
769  string loc_word;
770  switch (cons.GetMatch_location()) {
772  loc_word = cons.GetNot_present() ? "does not contain" : "contains";
773  break;
775  loc_word = cons.GetNot_present() ? "does not equal" : "equals";
776  break;
778  loc_word = cons.GetNot_present() ? "does not start with" : "starts with";
779  break;
781  loc_word = cons.GetNot_present() ? "does not end with" : "ends with";
782  break;
784  loc_word = cons.GetNot_present() ? "is not one of" : "is one of";
785  break;
786  }
787  string sub_words;
788  if (cons.CanGetIgnore_words()) {
789  ITERATE (list<CRef<CWord_substitution> >, it, cons.GetIgnore_words().Get()) {
790  string syns;
791  if ((*it)->CanGetSynonyms() && !(*it)->GetSynonyms().empty()) {
792  const CWord_substitution::TSynonyms& synonyms = (*it)->GetSynonyms();
793  ITERATE (CWord_substitution::TSynonyms, sn, synonyms) {
794  if (!syns.empty()) {
795  CWord_substitution::TSynonyms::const_iterator z = sn;
796  syns += (++z == synonyms.end()) ? " and " : ", ";
797  }
798  syns += "\'" + *sn + "\'";
799  }
800  sub_words += sub_words.empty() ? "" : ", ";
801  sub_words += "allow '" + ((*it)->CanGetWord() ? (*it)->GetWord() : "") + "' to be replaced by " + syns;
802  if ((*it)->GetCase_sensitive()) sub_words += ", case-sensitive";
803  if ((*it)->GetWhole_word()) sub_words += ", whole word";
804  }
805  }
806  }
807  string params;
808  params += cons.GetCase_sensitive() ? "case-sensitive" : kEmptyStr;
809  params += cons.GetWhole_word() ? params.empty() ? "whole word" : ", whole word" : kEmptyStr;
810  params += cons.GetIgnore_space() ? params.empty() ? "ignore spaces" : ", ignore spaces" : kEmptyStr;
811  params += cons.GetIgnore_punct() ? params.empty() ? "ignore punctuation" : ", ignore punctuation" : kEmptyStr;
812  params += cons.GetIgnore_weasel() ? params.empty() ? "ignore \'putative\' synonyms" : ", ignore \'putative\' synonyms" : kEmptyStr;
813 
814  string str = loc_word + " '" + cons.GetMatch_text() + "'";
815  str += params.empty() ? kEmptyStr : " (" + params + ")";
816  str += cons.GetIs_all_caps() ? ", all letters are uppercase" : kEmptyStr;
817  str += cons.GetIs_all_lower() ? ", all letters are lowercase" : kEmptyStr;
818  str += cons.GetIs_all_punct() ? ", all characters are punctuation" : kEmptyStr;
819  return str;
820  }
821  return kEmptyStr;
822 }
823 
824 
826 {
827  string summ;
828  switch (func.Which()) {
832  return "may contain plural";
834  return "contains " + NStr::IntToString(func.GetN_or_more_brackets_or_parentheses()) + " or more brackets or parentheses";
836  return "Three or more numbers together";
838  return "contains underscore";
840  return "is '" + func.GetPrefix_and_numbers() + "' followed by numbers";
842  return "is all capital letters";
844  return "contains unbalanced brackets or parentheses";
846  return "is longer than " + NStr::IntToString(func.GetToo_long()) + " characters";
848  //if (short_version) summ = "contains " + strtmp;
849  return "contains \'" + func.GetHas_term() + "\' at start or separated from other letters by numbers, spaces, or punctuation, but does not also contain 'domain'";
850  default:
851  break;
852  }
853  return "Unknown search function";
854 }
855 
856 
858 {
859  switch (pos.Which()) {
861  return "exactly " + NStr::IntToString(pos.GetDist_from_end());
863  return "no more than " + NStr::IntToString(pos.GetMax_dist_from_end());
865  return "no less than " + NStr::IntToString(pos.GetMin_dist_from_end());
866  default:
867  break;
868  }
869  return kEmptyStr;
870 }
871 
872 
874 {
875  string partial;
876  EPartial_constraint partial5 = loc.GetPartial5();
877  EPartial_constraint partial3 = loc.GetPartial3();
878  if (partial5 == ePartial_constraint_either && partial3 != ePartial_constraint_either) {
879  partial = partial3 == ePartial_constraint_partial ? " that are 3\' partial" : " that are 3\' complete";
880  }
881  else if (partial3 == ePartial_constraint_either && partial5 != ePartial_constraint_either) {
882  partial = partial5 == ePartial_constraint_partial ? " that are 5\' partial" : " that are 5\' complete";
883  }
884  else if (partial5 == ePartial_constraint_partial && partial3 == ePartial_constraint_partial) {
885  partial = " that are partial on both ends";
886  }
887  else if (partial5 == ePartial_constraint_complete && partial3 == ePartial_constraint_complete) {
888  partial = " that are complete on both ends";
889  }
890  else if (partial5 == ePartial_constraint_complete && partial3 == ePartial_constraint_partial) {
891  partial = " that are 5' complete and 3' partial";
892  }
893  else if (partial5 == ePartial_constraint_partial && partial3 == ePartial_constraint_complete) {
894  partial = " that are 5' partial and 3' complete";
895  }
896  string location_type;
898  location_type = " with single interval";
899  }
901  location_type = " with joined intervals";
902  }
904  location_type = " with ordered intervals";
905  }
906  string dist5;
907  if (loc.CanGetEnd5()) {
908  dist5 = SummarizeEndDistance(loc.GetEnd5());
909  dist5 = dist5.empty() ? dist5 : " with 5\' end " + dist5;
910  }
911  string dist3;
912  if (loc.CanGetEnd3()) {
913  dist3 = SummarizeEndDistance(loc.GetEnd3());
914  dist3 = dist3.empty() ? dist3 : " with 3\' end " + dist3;
915  }
916  string seq_word;
917  if (loc.GetSeq_type() == eSeqtype_constraint_nuc) {
918  seq_word = "nucleotide sequences";
919  }
920  else if (loc.GetSeq_type() == eSeqtype_constraint_prot) {
921  seq_word = "protein sequences";
922  }
923  string strand;
924  if (loc.GetStrand() == eStrand_constraint_plus) {
925  strand = " on plus strands";
926  }
927  else if (loc.GetStrand() == eStrand_constraint_minus) {
928  strand = " on minus strands";
929  }
930  if (partial.empty() && location_type.empty() && dist5.empty() && dist3.empty() && seq_word.empty() && strand.empty()) {
931  return kEmptyStr;
932  }
933  string str = "only objects";
934 
935  if (strand.empty() && !seq_word.empty()) {
936  str += " on " + seq_word;
937  }
938  else if (!strand.empty()) {
939  str += strand;
940  str += seq_word.empty() ? kEmptyStr : " of " + seq_word;
941  }
942  str += partial;
943  str += location_type;
944  str += dist5;
945  str += dist3;
946  return str;
947 }
948 
949 
951 {
952  string str = "Invalid field type";
953  switch (vnp.Which()) {
954  case CField_type::e_not_set: return "missing field";
956 return "e_Source_qual";
957  //return SummarizeSourceQual (vnp.GetSource_qual());
959  {
960  const CFeature_field& ff = vnp.GetFeature_field();
962  return "missing field";
963  }
964  else {
965  string label = ENUM_METHOD_NAME(EMacro_feature_type)()->FindName(ff.GetType(), false);
966  //string label = thisInfo.feattype_name[ff.GetType()];
967  //if (label.empty()) {
968  // return "Unknown feature";
969  //}
970  //else str = FeatureFieldLabel (label, ff.GetField());
971  return label.empty() ? "Unknown feature" : label;
972  }
973 
974  }
976 return "e_Cds_gene_prot";
977  //str = thisInfo.cgp_field_name[vnp.GetCds_gene_prot()];
978  //if (str.empty()) str = "Invalid CDS-Gene-Prot Field";
980 return "e_Molinfo_field";
981  //str = GetSequenceQualName (vnp.GetMolinfo_field());
982  //if (str.empty()) str = "Invalid Sequence Qual Field";
983  case CField_type::e_Pub:
984 return "e_Pub";
985  //str = thisInfo.pubfield_label[vnp.GetPub()];
986  //if (str.empty()) str = "Invalid field type";
988 return "e_Rna_field";
989  //str = SummarizeRnaQual (vnp.GetRna_field());
991 return "e_Struc_comment_field";
992  //str = SummarizeStructuredCommentField (vnp.GetStruc_comment_field());
994 return "e_Dblink";
995  //str = thisInfo.dblink_names[(int)vnp.GetDblink()];
996  case CField_type::e_Misc:
997 return "e_Misc";
998  //str = thisInfo.miscfield_names[(int)vnp.GetMisc()];
999  }
1000  return str;
1001 }
1002 
1003 
1005 {
1006  string summ = SummarizeStringConstraint(field.GetString_constraint());
1007  string label = SummarizeFieldType(field.GetField());
1008  return summ.empty() || label.empty() ? kEmptyStr : "where " + label + " " + summ;
1009 }
1010 
1011 
1013 {
1014  return kEmptyStr;
1015 }
1016 
1017 
1019 {
1020  switch (choice.Which()) {
1022  { string tmp = SummarizeStringConstraint(choice.GetString());
1023  return tmp.empty() ? kEmptyStr : "where object text " + tmp;
1024  }
1026  return SummarizeLocationConstraint(choice.GetLocation()) + " [[LOCATION CONSTRAINT]]";
1028  return SummarizeSourceConstraint (choice.GetSource()) + " [[SOURCE CONSTRAINT]]";
1030  //phrase = SummarizeCDSGeneProtQualConstraint (cons_choice.GetCdsgeneprot_qual());
1031  return "[[CDS Gene Prot QUAL CONSTRAINT]]";
1033  return "[[CDS Gene Prot PSEUDO CONSTRAINT]]";
1034  //phrase = SummarizeCDSGeneProtPseudoConstraint (cons_choice.GetCdsgeneprot_pseudo());
1036  return "[[SEQUENCE CONSTRAINT]]";
1037  //phrase = SummarizeSequenceConstraint (cons_choice.GetSequence());
1039  return "[[PUB CONSTRAINT]]";
1040  //phrase = SummarizePublicationConstraint (cons_choice.GetPub());
1042  return SummarizeFieldConstraint(choice.GetField());
1044  return "[[MOLINFO CONSTRAINT]]";
1045  //phrase = SummarizeMolinfoFieldConstraint (cons_choice.GetMolinfo());
1047  return "[[FIELD MISSING CONSTRAINT]]";
1048  //phrase = SummarizeMissingFieldConstraint (cons_choice.GetField_missing());
1050  return "[[TRANSLATION CONSTRAINT]]";
1051  //phrase = SummarizeTranslationConstraint (cons_choice.GetTranslation());
1052  break;
1053  default:
1054  break;
1055  }
1056  return kEmptyStr;
1057 }
1058 
1059 
1061 {
1062  string str;
1063  ITERATE (list<CRef<CConstraint_choice> >, it, cons.Get()) {
1064  string tmp = SummarizeConstraint(**it);
1065  str += tmp.empty() || str.empty() ? kEmptyStr : " and ";
1066  str += tmp;
1067  }
1068  return str;
1069 }
1070 
1071 
1073 {
1074  static const char* rule_type[] = {
1075  "None",
1076  "Typo",
1077  "Putative Typo",
1078  "Quick fix",
1079  "Organelles not appropriate in prokaryote",
1080  "Suspicious phrase; should this be nonfunctional?",
1081  "May contain database identifier more appropriate in note; remove from product name",
1082  "Remove organism from product name",
1083  "Possible parsing error or incorrect formatting; remove inappropriate symbols",
1084  "Implies evolutionary relationship; change to -like protein",
1085  "Consider adding 'protein' to the end of the product name",
1086  "Correct the name or use 'hypothetical protein'",
1087  "Use American spelling",
1088  "Use short product name instead of descriptive phrase",
1089  "use protein instead of gene as appropriate"
1090  };
1091  return rule_type[GetRule_type()];
1092 }
1093 
1094 
1096 {
1097  string type = GetRuleTypeName();
1098  string descr = IsSetDescription() ? GetDescription() : kEmptyStr;
1099  string find = SummarizeSearchFunc(GetFind());
1100  string except = CanGetExcept() ? SummarizeSearchFunc(GetExcept()) : kEmptyStr;
1101  string replace = CanGetReplace() ? SummarizeReplaceRule(GetReplace()) : kEmptyStr;
1103 
1104  string out = find;
1105  if (!except.empty()) out += " but not " + except;
1106  if (!feat_constraint.empty()) out += ", " + feat_constraint;
1107  if (!replace.empty()) out += ", " + replace;
1108  if (!type.empty()) out += " (" + type + ")";
1109  if (!descr.empty()) out += " Description: " + descr;
1110  return out;
1111 
1112 // debug output
1113 /*
1114  string out = "Type: " + GetRuleTypeName();
1115  out += descr.empty() ? kEmptyStr : "\n\t\tDescr: " + descr;
1116  out += find.empty() ? kEmptyStr : "\n\t\tFind: " + find;
1117  out += except.empty() ? kEmptyStr : "\n\t\tExcept: " + except;
1118  out += feat_constraint.empty() ? kEmptyStr : "\n\t\tFeat-Constr: " + feat_constraint;
1119  out += replace.empty() ? kEmptyStr : "\n\t\tReplace: " + replace;
1120  return out;
1121 */
1122 }
1123 
1124 
1125 END_objects_SCOPE // namespace ncbi::objects::
bool IsAllPunctuation(const string &str)
static bool CaseNCompareEqual(string str1, string str2, unsigned len1, bool case_sensitive)
static bool DoesSingleStringMatchConstraint(const string &str, const CString_constraint *str_cons)
bool IsAllCaps(const string &str)
static bool IsWholeWordMatch(const string &start, const size_t &found, const unsigned &match_len, bool disallow_slash=false)
static bool DisallowCharacter(const char ch, bool disallow_slash)
static const string SkipWeasel(const string &str)
static bool GetSpanFromHyphenInString(const string &str, const size_t &hyphen, string &first, string &second)
static bool IsStringInSpanInList(const string &str, const string &list)
static bool IsStringConstraintEmpty(const CString_constraint *constraint)
static bool AdvancedStringCompare(const string &str, const string &str_match, const CString_constraint *str_cons, bool is_start, unsigned *ini_target_match_len=0)
static bool StringIsPositiveAllDigits(const string &str)
bool IsAllLowerCase(const string &str)
static string StripUnimportantCharacters(const string &str, bool strip_space, bool strip_punct)
static bool IsStringInSpan(const string &str, const string &first, const string &second)
static bool AdvancedStringMatch(const string &str, const CString_constraint *str_cons)
User-defined methods of the data storage class.
CConstRef –.
Definition: ncbiobj.hpp:1266
CRef –.
Definition: ncbiobj.hpp:618
bool ApplyToString(string &result, const CMatchString &str, CConstRef< CString_constraint > find) const
bool Match(const CMatchString &str) const
bool Empty() const
Definition: Search_func.cpp:52
CSource_constraint –.
void SetMatch_text(const TMatch_text &value)
string SummarizeLocationConstraint(const CLocation_constraint &) const
string SummarizeEndDistance(const CLocation_pos_constraint &) const
string GetRuleTypeName(void) const
string SummarizeSourceConstraint(const CSource_constraint &) const
bool ApplyToString(string &result, const CMatchString &str) const
bool StringMatchesSuspectProductRule(const CMatchString &str) const
string SummarizeRule(void) const
string SummarizeConstraintSet(const CConstraint_choice_set &) const
string SummarizeConstraint(const CConstraint_choice &) const
string SummarizeSearchFunc(const CSearch_func &) const
string SummarizeFieldType(const CField_type &) const
string SummarizeStringConstraint(const CString_constraint &) const
string SummarizeReplaceRule(const CReplace_rule &) const
string SummarizeFieldConstraint(const CField_constraint &) const
CTempString implements a light-weight string on top of a storage buffer whose lifetime management is ...
Definition: tempstr.hpp:65
std::ofstream out("events_result.xml")
main entry point for tests
static DLIST_TYPE *DLIST_NAME() first(DLIST_LIST_TYPE *list)
Definition: dlist.tmpl.h:46
static const char * str(char *buf, int n)
Definition: stats.c:84
static char tmp[3200]
Definition: utf8.c:42
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
#define NULL
Definition: ncbistd.hpp:225
virtual void Assign(const CSerialObject &source, ESerialRecursionMode how=eRecursive)
Set object to copy of another one.
#define ENUM_METHOD_NAME(EnumName)
Definition: serialbase.hpp:994
void Reset(void)
Reset reference object.
Definition: ncbiobj.hpp:1439
#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 kEmptyStr
Definition: ncbistr.hpp:123
static list< string > & Split(const CTempString str, const CTempString delim, list< string > &arr, TSplitFlags flags=0, vector< SIZE_TYPE > *token_pos=NULL)
Split a string using specified delimiters.
Definition: ncbistr.cpp:3461
static SIZE_TYPE FindNoCase(const CTempString str, const CTempString pattern, SIZE_TYPE start, SIZE_TYPE end, EOccurrence which=eFirst)
Find the pattern in the specified range of a string using a case insensitive search.
Definition: ncbistr.cpp:2993
static void TruncateSpacesInPlace(string &str, ETrunc where=eTrunc_Both)
Truncate spaces in a string (in-place)
Definition: ncbistr.cpp:3201
static string IntToString(int value, TNumToStringFlags flags=0, int base=10)
Convert int to string.
Definition: ncbistr.hpp:5084
static unsigned int StringToUInt(const CTempString str, TStringToNumFlags flags=0, int base=10)
Convert string to unsigned int.
Definition: ncbistr.cpp:642
CTempString substr(size_type pos) const
Obtain a substring from this string, beginning at a given offset.
Definition: tempstr.hpp:776
static bool EqualNocase(const CTempString s1, SIZE_TYPE pos, SIZE_TYPE n, const char *s2)
Case-insensitive equality of a substring with another string.
Definition: ncbistr.hpp:5353
size_type find(const CTempString match, size_type pos=0) const
Find the first instance of the entire matching string within the current string, beginning at an opti...
Definition: tempstr.hpp:655
static string & ToUpper(string &str)
Convert string to upper case – string& version.
Definition: ncbistr.cpp:424
static string & ToLower(string &str)
Convert string to lower case – string& version.
Definition: ncbistr.cpp:405
static const char label[]
TCase_sensitive GetCase_sensitive(void) const
Get the Case_sensitive member data.
TToo_long GetToo_long(void) const
Get the variant data.
const TIgnore_words & GetIgnore_words(void) const
Get the Ignore_words member data.
TStrand GetStrand(void) const
Get the Strand member data.
TIgnore_space GetIgnore_space(void) const
Get the Ignore_space member data.
E_Choice Which(void) const
Which variant is currently selected.
const TLocation & GetLocation(void) const
Get the variant data.
const TField & GetField(void) const
Get the variant data.
const TSimple_replace & GetSimple_replace(void) const
Get the variant data.
TMatch_location GetMatch_location(void) const
Get the Match_location member data.
const TPrefix_and_numbers & GetPrefix_and_numbers(void) const
Get the variant data.
const TReplace & GetReplace(void) const
Get the Replace member data.
E_Choice Which(void) const
Which variant is currently selected.
const TString & GetString(void) const
Get the variant data.
const THaem_replace & GetHaem_replace(void) const
Get the variant data.
bool CanGetReplace(void) const
Check if it is safe to call GetReplace method.
TIs_all_caps GetIs_all_caps(void) const
Get the Is_all_caps member data.
bool CanGetFeat_constraint(void) const
Check if it is safe to call GetFeat_constraint method.
bool IsSetDescription(void) const
Check if a value has been assigned to Description data member.
TWhole_string GetWhole_string(void) const
Get the Whole_string member data.
TPartial3 GetPartial3(void) const
Get the Partial3 member data.
TWhole_word GetWhole_word(void) const
Get the Whole_word member data.
TRule_type GetRule_type(void) const
Get the Rule_type member data.
const TDescription & GetDescription(void) const
Get the Description member data.
TIgnore_weasel GetIgnore_weasel(void) const
Get the Ignore_weasel member data.
const TField & GetField(void) const
Get the Field member data.
TMove_to_note GetMove_to_note(void) const
Get the Move_to_note member data.
const TExcept & GetExcept(void) const
Get the Except member data.
TDist_from_end GetDist_from_end(void) const
Get the variant data.
const TFeature_field & GetFeature_field(void) const
Get the variant data.
EMacro_feature_type
feature values
TIgnore_punct GetIgnore_punct(void) const
Get the Ignore_punct member data.
const TEnd5 & GetEnd5(void) const
Get the End5 member data.
TLocation_type GetLocation_type(void) const
Get the Location_type member data.
const TFind & GetFind(void) const
Get the Find member data.
E_Choice Which(void) const
Which variant is currently selected.
EPartial_constraint
Access to EPartial_constraint's attributes (values, names) as defined in spec.
const TFeat_constraint & GetFeat_constraint(void) const
Get the Feat_constraint member data.
EString_location
simple constraints
E_Choice Which(void) const
Which variant is currently selected.
TN_or_more_brackets_or_parentheses GetN_or_more_brackets_or_parentheses(void) const
Get the variant data.
TSeq_type GetSeq_type(void) const
Get the Seq_type member data.
const TMatch_text & GetMatch_text(void) const
Get the Match_text member data.
const TString_constraint & GetString_constraint(void) const
Get the String_constraint member data.
bool CanGetEnd5(void) const
Check if it is safe to call GetEnd5 method.
TPartial5 GetPartial5(void) const
Get the Partial5 member data.
TNot_present GetNot_present(void) const
Get the Not_present member data.
TMax_dist_from_end GetMax_dist_from_end(void) const
Get the variant data.
bool IsSetFind(void) const
Check if a value has been assigned to Find data member.
const THas_term & GetHas_term(void) const
Get the variant data.
TIs_all_punct GetIs_all_punct(void) const
Get the Is_all_punct member data.
E_Choice Which(void) const
Which variant is currently selected.
bool CanGetEnd3(void) const
Check if it is safe to call GetEnd3 method.
bool CanGetExcept(void) const
Check if it is safe to call GetExcept method.
TIs_all_lower GetIs_all_lower(void) const
Get the Is_all_lower member data.
TWeasel_to_putative GetWeasel_to_putative(void) const
Get the Weasel_to_putative member data.
const Tdata & Get(void) const
Get the member data.
const TReplace & GetReplace(void) const
Get the Replace member data.
const TReplace_func & GetReplace_func(void) const
Get the Replace_func member data.
const TSource & GetSource(void) const
Get the variant data.
bool IsSetReplace(void) const
Check if a value has been assigned to Replace data member.
bool CanGetReplace(void) const
Check if it is safe to call GetReplace method.
const TString_constraint & GetString_constraint(void) const
Get the variant data.
TType GetType(void) const
Get the Type member data.
E_Choice Which(void) const
Which variant is currently selected.
TMin_dist_from_end GetMin_dist_from_end(void) const
Get the variant data.
const Tdata & Get(void) const
Get the member data.
bool CanGetMatch_text(void) const
Check if it is safe to call GetMatch_text method.
bool CanGetIgnore_words(void) const
Check if it is safe to call GetIgnore_words method.
const TEnd3 & GetEnd3(void) const
Get the End3 member data.
const TField & GetField(void) const
Get the Field member data.
@ e_N_or_more_brackets_or_parentheses
@ eStrand_constraint_plus
@ eStrand_constraint_minus
@ e_not_set
No variant selected.
Definition: Field_type_.hpp:98
@ e_not_set
No variant selected.
@ eSeqtype_constraint_prot
@ eSeqtype_constraint_nuc
@ ePartial_constraint_complete
@ ePartial_constraint_partial
@ ePartial_constraint_either
@ eString_location_inlist
@ eString_location_equals
@ eString_location_contains
@ eString_location_starts
@ eString_location_ends
@ eLocation_type_constraint_ordered
@ eLocation_type_constraint_joined
@ eLocation_type_constraint_single_interval
unsigned int
A callback function used to compare two keys in a database.
Definition: types.hpp:1210
int i
int len
static const BitmapCharRec ch1
Definition: ncbi_10x20.c:1827
static const BitmapCharRec ch2
Definition: ncbi_10x20.c:1819
int isalpha(Uchar c)
Definition: ncbictype.hpp:61
int isspace(Uchar c)
Definition: ncbictype.hpp:69
int isdigit(Uchar c)
Definition: ncbictype.hpp:64
int ispunct(Uchar c)
Definition: ncbictype.hpp:68
static int match(register const pcre_uchar *eptr, register const pcre_uchar *ecode, const pcre_uchar *mstart, int offset_top, match_data *md, eptrblock *eptrb, unsigned int rdepth)
Definition: pcre_exec.c:513
Definition: type.c:6
else result
Definition: token2.c:20
Modified on Tue Apr 23 07:40:12 2024 by modify_doxy.py rev. 669887