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

Go to the SVN repository for this file.

1 /* $Id: macro_fn_string_constr.cpp 46868 2021-11-17 16:29:03Z asztalos $
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  * Authors: Andrea Asztalos
27  *
28  */
29 
30 #include <ncbi_pch.hpp>
31 #include <corelib/ncbifile.hpp>
38 
39 /** @addtogroup GUI_MACRO_SCRIPTS_UTIL
40  *
41  * @{
42  */
43 
45 BEGIN_SCOPE(macro)
47 
48 //////////////////////////////////////////////////////////////////////////////
49 /// Classes related to STRING CONSTRAINTS
50 ///
51 /// Testing whether the string is all upper case, lower case or fully composed of punctuation
52 /// ISUPPER(fieldname), ISLOWER(fieldname), ISPUNCTUATION(fieldname)
53 ///
54 /// In case of a modifier, the functions accept two parameters:
55 /// ISUPPER(asn_path_to_modifier_container, modifier_subtype)
56 ///
57 ///
58 /// String comparison functions with various options:
59 /// STARTS(field_name, match_text, case_sensitive, ignore_space, ignore_punctuation,
60 /// whole_word, ignore_weasel, syn_fname, word, case_sensitive, whole_word)
61 /// Minimum number of arguments: 2
62 ///
63 /// In case of a modifier, number of minimum/possible parameters increases by one:
64 /// STARTS(asn_path_to_modifier_container, modifier_subtype, match_text, case_sensitive,
65 /// ignore_space, ignore_punctuation, whole_word, ignore_weasel, syn_fname, word, case_sensitive, whole_word)
66 ///
67 /// Any String constraint function can form a composite function
68 ///
69 const string CMacroFunction_StringConstraints::sm_syn("synonym");
70 const char* CMacroFunction_StringConstraints::sm_Upper = "ISUPPER";
71 const char* CMacroFunction_StringConstraints::sm_Lower = "ISLOWER";
72 const char* CMacroFunction_StringConstraints::sm_Punct = "ISPUNCTUATION";
73 
74 const char* CMacroFunction_StringConstraints::sm_UpperAll = "IS_ALL_UPPER";
75 const char* CMacroFunction_StringConstraints::sm_LowerAll = "IS_ALL_LOWER";
76 const char* CMacroFunction_StringConstraints::sm_PunctAll = "IS_ALL_PUNCTUATION";
77 
78 const char* CMacroFunction_StringConstraints::sm_Start = "STARTS";
79 const char* CMacroFunction_StringConstraints::sm_End = "ENDS";
80 const char* CMacroFunction_StringConstraints::sm_Equal = "EQUALS";
81 const char* CMacroFunction_StringConstraints::sm_Contain = "CONTAINS";
82 const char* CMacroFunction_StringConstraints::sm_InList = "INLIST";
83 
85  const string& type, EStrConstrCase testcase, ELogicType op_type)
86  : IEditMacroFunction(func_scope),
87  m_TestCase(testcase),
88  m_Type(type),
89  m_Modifier(false),
90  m_Operation(op_type),
91  m_Constraint(0)
92 {
93 }
94 
96 {
98 
99  // build the string constraint from the argument list
101  if (!m_Constraint) {
102  return;
103  }
104 
105  // obtain the field name (path to container and subtype in case of a modifier) or obtain the object
106  string field_name, container;
107  bool match = false;
108  if (m_Args[0]->IsString()) {
109  field_name = m_Args[0]->GetString();
110  if (m_Modifier) {
111  container = field_name; // asn path to orgmod/subsource modifier container
112  field_name = m_Args[1]->GetString(); // modifier subtype
113  }
114 
115  if (field_name.empty() || (m_Modifier && container.empty()))
116  return;
117 
118  if (m_Modifier) {
119  match = x_CheckConstraintContainer(container, field_name);
120  } else {
121  match = x_CheckConstraintPrimitive(field_name);
122  }
123  }
124  else if (m_Args[0]->AreStrings()) {
125  const vector<string>& strs = m_Args[0]->GetStrings();
126  for (auto& it : strs) {
127  if (m_Constraint->Match(it)) {
128  match = true;
129  break;
130  }
131  }
132  }
133  else if (m_Args[0]->AreObjects()) {
134  // if the first parameter is an object returned by another function
135  CMQueryNodeValue& obj = m_Args[0].GetNCObject();
136  obj.Dereference();
137  CMQueryNodeValue::TObs res_oi = obj.GetObjects();
139 
141  }
142  else if (m_Args[0]->IsRef()) {
143  m_Args[0]->Dereference();
144  if (m_Args[0]->IsString()) {
145  match = m_Constraint->Match(m_Args[0]->GetString());
146  }
147  else if (m_Args[0]->AreObjects()) {
148  CMQueryNodeValue::TObs res_oi = m_Args[0]->GetObjects();
151  }
152  else if (m_Args[0]->AreStrings()) {
153  const vector<string>& strs = m_Args[0]->GetStrings();
154  for (auto& it : strs) {
155  if (m_Constraint->Match(it)) {
156  match = true;
157  break;
158  }
159  }
160  }
161  }
162 
163  // return a bool type variable
166 }
167 
168 
170 {
171  /* For testing only case constraints (isupper, islower and ispunctuation),
172  number of parameters should be one (or two, for modifiers)
173  In Both cases the first parameter can be a CObjectInfo - occurring in composite functions
174  */
175  if (m_Args.empty()) {
176  return false;
177  }
178  size_t as = m_Args.size();
179  bool first_ok = m_Args[0]->IsString() ||
180  m_Args[0]->AreStrings() ||
181  m_Args[0]->AreObjects() ||
182  m_Args[0]->IsRef();
183 
184  if (NStr::IsBlank(m_Type)) { // for testing case constraints
185  if (as > 2 || !first_ok)
186  return false;
187  if (as == 2 && !m_Args[1]->IsString())
188  return false;
189  } else { // for testing more complex string constraints
190  if (as < 2 || !first_ok || !(m_Args[1]->IsString() || m_Args[1]->IsInt() || m_Args[1]->IsDouble()))
191  return false;
192  }
193  return true;
194 }
195 
197 {
198  return !(!m_Args.empty() && m_Args[0]->IsNotSet());
199 }
200 
202 {
203  return (NStr::EqualNocase(fn_name, sm_Contain) ||
204  NStr::EqualNocase(fn_name, sm_Equal) ||
205  NStr::EqualNocase(fn_name, sm_Start) ||
206  NStr::EqualNocase(fn_name, sm_End) ||
207  NStr::EqualNocase(fn_name, sm_InList));
208 }
209 
211 {
212  if (NStr::EndsWith(str, "synonyms.txt"))
213  return true;
214 
215  CFile file(str);
216  return (file.Exists());
217 }
218 
219 
221 {
222  m_Modifier = false; // by default
223  if (NStr::IsBlank(m_Type)) { // for testing case constraints
224  // set the modifier flag
225  if (m_Args.size() == 2) {
226  m_Modifier = true;
227  }
228  }
229  else {
230  if (m_Args.size() > 2 &&
231  m_Args[0]->IsString() && m_Args[1]->IsString() &&
232  (m_Args[2]->IsString() || m_Args[2]->IsInt() || m_Args[2]->IsDouble()) &&
233  !s_IsSynonymFile(m_Args[2]->GetString())) {
234  m_Modifier = true;
235  }
236  }
237 }
238 
239 
241 {
242  if (NStr::IsBlank(m_Type)){ // for testing case constraints
244  } else {
246  }
247 
248  // if nothing else is specified, default values will apply
249 }
250 
252 {
254  switch (m_TestCase) {
255  case eUpper:
256  m_Constraint->SetIs_all_caps(true);
257  break;
258  case eLower:
259  m_Constraint->SetIs_all_lower(true);
260  break;
261  case ePunct:
262  m_Constraint->SetIs_all_punct(true);
263  break;
264  case eNotSet:
265  break;
266  }
267 }
268 
270 {
271  size_t arg_size = m_Args.size();
273 
274  size_t check = (m_Modifier) ? 2 : 1; // the index of the parameter corresponding to the match_text
275  if (check < arg_size) {
277  } else {
279  return;
280  }
281 
282  // set the type of string comparison:
283  if (NStr::EqualNocase(m_Type, "starts")) {
284  m_Constraint->SetMatch_location(eString_location_starts);
285  } else if (NStr::EqualNocase(m_Type, "ends")) {
286  m_Constraint->SetMatch_location(eString_location_ends);
287  } else if (NStr::EqualNocase(m_Type, "contains")) {
288  m_Constraint->SetMatch_location(eString_location_contains);
289  } else if (NStr::EqualNocase(m_Type, "equals")) {
290  m_Constraint->SetMatch_location(eString_location_equals);
291  } else if (NStr::EqualNocase(m_Type, "inlist")) {
292  m_Constraint->SetMatch_location(eString_location_inlist);
293  }
294 
295  // setting the optional boolean flags
296  size_t opt_min = (m_Modifier) ? 3 : 2; // the optional boolean flags
297  size_t opt_max = (m_Modifier) ? 8 : 7;
298  size_t n = opt_min;
299  for ( ; n < min(arg_size, opt_max); ++n) {
300  if (m_Args[n]->IsBool()) {
301  switch (n) {
302  case 2:
303  m_Constraint->SetCase_sensitive(m_Args[n]->GetBool());
304  break;
305  case 3:
306  if (m_Modifier)
307  m_Constraint->SetCase_sensitive(m_Args[n]->GetBool());
308  else
309  m_Constraint->SetIgnore_space(m_Args[n]->GetBool());
310  break;
311  case 4:
312  if (m_Modifier)
313  m_Constraint->SetIgnore_space(m_Args[n]->GetBool());
314  else
315  m_Constraint->SetIgnore_punct(m_Args[n]->GetBool());
316  break;
317  case 5:
318  if (m_Modifier)
319  m_Constraint->SetIgnore_punct(m_Args[n]->GetBool());
320  else
321  m_Constraint->SetWhole_word(m_Args[n]->GetBool());
322  break;
323  case 6:
324  if (m_Modifier)
325  m_Constraint->SetWhole_word(m_Args[n]->GetBool());
326  else
327  m_Constraint->SetIgnore_weasel(m_Args[n]->GetBool());
328  break;
329  case 7:
330  if (m_Modifier)
331  m_Constraint->SetIgnore_weasel(m_Args[n]->GetBool());
332  break;
333  }
334  } else if (m_Args[n]->GetDataType() == CMQueryNodeValue::eString) {
335  break;
336  } else {
338  return;
339  }
340  }
341 
342  size_t index = 0; // the possible index for finding the synonym list filename
343  if (n < arg_size) {
344  index = min(opt_max, n);
345  }
346 
347  if (index && m_Args[index]->IsString()) {
348  string synonym_file = m_Args[index]->GetString(); // path to the synonym file
349 
350  n = index + 1;
351  if ( n > arg_size || (n < arg_size && !m_Args[n]->IsString())) {
353  return;
354  }
355 
356  list<CRef<CWord_substitution> > word_subst_list;
357  while ( n < arg_size ) {
358  if (m_Args[n]->IsString()) {
359  CRef<CWord_substitution> word_subst = x_ReadSynonymsFor(synonym_file, m_Args[n]->GetString());
360  if (!word_subst) {
363  "Synonyms for phrase '" + m_Args[n]->GetString() + "' were not found in '" + synonym_file + "' file", nullptr);
364  }
365  if ( n + 1 < arg_size && m_Args[n + 1]->IsBool()) {
366  word_subst->SetCase_sensitive(m_Args[n + 1]->GetBool());
367  n++;
368  }
369  if (n + 1 < arg_size && m_Args[n + 1]->IsBool()) {
370  word_subst->SetWhole_word(m_Args[n + 1]->GetBool());
371  n++;
372  }
373  word_subst_list.push_back(word_subst);
374  n++;
375  } else {
377  return;
378  }
379  }
380  if (!word_subst_list.empty()) {
381  m_Constraint->SetIgnore_words().Set() = word_subst_list;
382  }
383  }
384 }
385 
387 {
388  if (filename.empty() || phrase.empty()) {
389  LOG_POST(Error << "Either synonym filename '" << filename << "' or phrase '" << phrase << "' is empty");
390  return CRef<CWord_substitution>(nullptr);
391  }
392 
393  /* When the match word is prefixed by the "optional-" word it means that the match word is optional
394  and has no synonyms. The word-substitution object is:
395  Word-substitution::=
396  {
397  word "match_word",
398  case-sensitive FALSE,
399  whole - word FALSE
400  }
401  */
402 
403  /* When the match word starts with "emptystring", the match word is considered to be empty and its
404  synonyms are read from the "synonyms.txt" (or a specified synonym) text file.
405  */
406 
407  const char* kOptional = "optional-";
408  const char* kEmpty = "emptystring";
409 
411  if (NStr::StartsWith(phrase, kOptional)) {
412  string word = phrase.substr(CTempString(kOptional).size(), NPOS);
413  if (!word.empty()) {
414  word_subst->SetWord(word);
415  }
416  }
417  else if (NStr::StartsWith(phrase, kEmpty)) {
418  word_subst->SetWord(kEmptyStr);
419  word_subst->SetSynonyms() = CMacroLib::GetInstance().GetSynonymListForPhrase(phrase);
420  if (word_subst->GetSynonyms().empty()) {
421  word_subst.Reset();
422  }
423  }
424  else if (NStr::StartsWith(phrase, sm_syn)) { // phrases like "synonym03-CBS"
425  string word = phrase.substr(sm_syn.size() + 3, NPOS);
426  if (!word.empty()) {
427  word_subst->SetWord(word);
428  word_subst->SetSynonyms() = CMacroLib::GetInstance().GetSynonymListForPhrase(phrase);
429  if (word_subst->GetSynonyms().empty()) {
430  word_subst.Reset();
431  }
432  }
433  }
434  else {
435  word_subst->SetWord(phrase);
436  word_subst->SetSynonyms() = CMacroLib::GetInstance().GetSynonymListForPhrase(phrase);
437  if (word_subst->GetSynonyms().empty()) {
438  word_subst.Reset();
439  }
440  }
441  return word_subst;
442 }
443 
445 {
446  if (filename.empty() || phrase.empty()) {
447  LOG_POST(Error << "Either synonym filename '" << filename << "' or phrase '" << phrase << "' is empty");
448  return CRef<CWord_substitution>(nullptr);
449  }
450 
451  /* When the match word is prefixed by the "optional-" word it means that the match word is optional
452  and has no synonyms. The word-substitution object is:
453  Word-substitution::=
454  {
455  word "match_word",
456  case-sensitive FALSE,
457  whole - word FALSE
458  }
459  */
460 
461  /* When the match word starts with "emptystring", the match word is considered to be empty and its
462  synonyms are read from the "synonyms.txt" (or a specified synonym) text file.
463  */
464 
465  const char* kOptional = "optional-";
466  const char* kEmpty = "emptystring";
467 
469  if (NStr::StartsWith(phrase, kOptional)) {
470  string word = phrase.substr(CTempString(kOptional).size(), NPOS);
471  if (!word.empty()) {
472  word_subst->SetWord(word);
473  }
474  }
475  else if (NStr::StartsWith(phrase, kEmpty)) {
476  word_subst->SetWord(kEmptyStr);
477  word_subst->SetSynonyms() = CMacroLib::GetInstance().GetSynonymListForPhrase(filename, phrase);
478  if (word_subst->GetSynonyms().empty()) {
479  word_subst.Reset();
480  }
481  }
482  else if (NStr::StartsWith(phrase, sm_syn)) { // phrases like "synonym03-CBS"
483  string word = phrase.substr(sm_syn.size() + 3, NPOS);
484  if (!word.empty()) {
485  word_subst->SetWord(word);
486  word_subst->SetSynonyms() = CMacroLib::GetInstance().GetSynonymListForPhrase(filename, phrase);
487  if (word_subst->GetSynonyms().empty()) {
488  word_subst.Reset();
489  }
490  }
491  }
492  else {
493  word_subst->SetWord(phrase);
494  word_subst->SetSynonyms() = CMacroLib::GetInstance().GetSynonymListForPhrase(filename, phrase);
495  if (word_subst->GetSynonyms().empty()) {
496  word_subst.Reset();
497  }
498  }
499  return word_subst;
500 }
501 
503 {
504  if (oi.GetTypeFamily() == eTypeFamilyPrimitive) {
506  m_Constraint->Match(oi.GetPrimitiveValueString())) {
507  return true;
508  } else if (oi.GetPrimitiveValueType() == ePrimitiveValueEnum) {
509  string value;
510  try {
512  } catch(const CException&) {
514  }
515  if (m_Constraint->Match(value))
516  return true;
517  }
518  } else if (oi.GetTypeFamily() == eTypeFamilyContainer) { // in case of protein names
519  bool constr_sat = false;
520  CObjectInfoEI elem = oi.BeginElements();
521  while (elem.Valid() && !constr_sat) {
522  constr_sat = x_CheckStringConstraint(elem.GetElement());
523  ++elem;
524  }
525  return constr_sat;
526  }
527  else if (oi.GetTypeFamily() == eTypeFamilyClass) {
528  if (NStr::EqualNocase(oi.GetName(), "Name-std")) {
529  return x_CheckAuthorNames(oi);
530  }
531  }
532  else if (oi.GetTypeFamily() == eTypeFamilyChoice) {
534  return x_CheckStringConstraint(var.GetVariant());
535  }
536  else if (oi.GetTypeFamily() == eTypeFamilyPointer) {
538  }
539  return false;
540 }
541 
543 {
544  CMQueryNodeValue::TObs res_oi;
545  CObjectInfo objInfo = m_DataIter->GetEditedObject();
546  if (!GetFieldsByName(&res_oi, objInfo, field) || res_oi.size() != 1)
547  return false;
548 
549  return x_CheckStringConstraint(res_oi.front().field);
550 }
551 
553 {
554  if (objs.empty())
555  return false;
556 
557  // to make ISUPPER() and its relative also work for publication authors
558  // IS_ALL_UPPER() will be deprecated
559  bool all_authors = true;
560  for (auto& it : objs) {
561  if (it.field.GetName() != "Name-std") {
562  all_authors = false;
563  break;
564  }
565  }
566 
567  if (all_authors) {
568  m_Operation = eAND;
569  }
570 
571  if (m_Operation == eOR) {
572  // return true if there is at least one field that matches the string constraint
573  ITERATE(CMQueryNodeValue::TObs, it, objs) {
574  if (x_CheckStringConstraint(it->field))
575  return true;
576  }
577  } else if (m_Operation == eAND) {
578  ITERATE(CMQueryNodeValue::TObs, it, objs) {
579  if (!x_CheckStringConstraint(it->field))
580  return false;
581  }
582  return true;
583  }
584  return false;
585 }
586 
588 {
589  _ASSERT(NStr::EqualNocase(oi.GetName(), "Name-std"));
590 
591  bool match(true);
592  CObjectInfoMI mem = oi.BeginMembers();
593  while (mem.Valid() && match) {
594  if (mem.IsSet()) {
596  }
597  ++mem;
598  }
599  return match;
600 }
601 
602 // returns true if there is at least one subtype of type "subtype" that satisfies the constraint
603 bool CMacroFunction_StringConstraints::x_CheckConstraintContainer(const string& container, const string& subtype)
604 {
605  CMQueryNodeValue::TObs res_oi;
606  CObjectInfo objinfo = m_DataIter->GetEditedObject();
607  if (!GetFieldsByName(&res_oi, objinfo, container) || res_oi.empty()) {
608  return false;
609  }
610 
611  bool constr_sat = false;
612  CObjectInfo obj = res_oi.front().field;
613  if (obj.GetTypeFamily() == eTypeFamilyContainer) {
614  CObjectInfoEI elem = obj.BeginElements();
615  // iterating over present modifiers
616  while (elem.Valid() && !constr_sat) {
617  CObjectInfo oi = elem.GetElement();
618  if (oi.GetTypeFamily() == eTypeFamilyPointer) {
619  CObjectInfo obj(oi.GetPointedObject());
620  if (obj.GetTypeFamily() == eTypeFamilyClass) {
621  constr_sat = x_CheckConstraintWithinClass(obj, subtype);
622  } else {
623  NCBI_THROW(CMacroExecException, eVarNotResolved,
624  "Family type mismatch (class is expected), object type is: " + NStr::IntToString(obj.GetTypeFamily()));
625  }
626  } else {
627  NCBI_THROW(CMacroExecException, eVarNotResolved,
628  "Family type mismatch (pointer is expected), object type is: " + NStr::IntToString(oi.GetTypeFamily()));
629  }
630  ++elem;
631  }
632  }
633  return constr_sat;
634 }
635 
637 {
638  if (obj.GetTypeFamily() != eTypeFamilyClass)
639  return false;
640 
641  // check whether this object (CObjectInfo) has the right "subtype" (class COrgMod or class CSubSource)
642  // the first member is the name of the subtype
643  TMemberIndex index = 1;
645  if (!mem.Valid()) {
646  return false;
647  }
648  string mem_name = mem.GetMemberInfo()->GetId().GetName();
649  CMQueryNodeValue::TObs type_objs;
650  if (!GetFieldsByName(&type_objs, obj, mem_name) || type_objs.size() != 1) {
651  return false;
652  }
653 
654  string type;
655  bool subtype_found = false;
656  CObjectInfo oi = type_objs.front().field;
657  if (oi.GetTypeFamily() == eTypeFamilyPrimitive) {
658  switch (oi.GetPrimitiveValueType()) {
660  {
662  break;
663  }
664  case ePrimitiveValueEnum:
665  {
666  try {
668  } catch(const CException&) {
670  }
671  break;
672  }
673  default:
674  break;
675  }
676 
677  if (NStr::EqualNocase(type, subtype)) { // case_insensitive string matching
678  subtype_found = true;
679  }
680 
681  } else {
682  string msg = oi.GetName() + " class member's type is " + NStr::IntToString(oi.GetTypeFamily());
683  NCBI_THROW(CMacroExecException, eVarNotResolved, msg);
684  }
685 
686  if (!subtype_found)
687  return false;
688 
689  // once the subtype is found, check the value associated to it
690  // the second member gives the value of the subtype
691  ++index;
692  mem = obj.GetClassMemberIterator(index);
693  if (!mem.Valid()) {
694  return false;
695  }
696 
697  mem_name = mem.GetMemberInfo()->GetId().GetName();
698  type_objs.clear();
699  if (!GetFieldsByName(&type_objs, obj, mem_name) || type_objs.size() != 1) {
700  return false;
701  }
702 
703  oi = type_objs.front().field;
705  if (m_Constraint->Match(oi.GetPrimitiveValueString())) { // whether the subtype value matches the constraint
706  return true;
707  }
708  } else {
709  string msg = oi.GetName() + " class member's type is " + NStr::IntToString(oi.GetTypeFamily());
710  NCBI_THROW(CMacroExecException, eVarNotResolved, msg);
711  }
712 
713  return false;
714 }
715 
716 END_SCOPE(macro)
718 
719 /* @} */
User-defined methods of the data storage class.
CFile –.
Definition: ncbifile.hpp:1604
Subclass of the IQueryParseUserObject which is held as the user-defined object in each CQueryParseNod...
Definition: macro_exec.hpp:71
class CMacroExecException
Definition: macro_ex.hpp:196
CObjectInfoCV –.
Definition: objectiter.hpp:588
CObjectInfoEI –.
Definition: objectiter.hpp:125
CObjectInfoMI –.
Definition: objectiter.hpp:432
CObjectInfo –.
Definition: objectinfo.hpp:597
CRef –.
Definition: ncbiobj.hpp:618
CTempString implements a light-weight string on top of a storage buffer whose lifetime management is ...
Definition: tempstr.hpp:65
Base class for any user function that performs editing operations on ASN.1 data.
#define false
Definition: bool.h:36
#define check(s)
Definition: describecol2.c:21
static int type
Definition: getdata.c:31
static const char * str(char *buf, int n)
Definition: stats.c:84
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
#define DIAG_COMPILE_INFO
Make compile time diagnostic information object to use in CNcbiDiag and CException.
Definition: ncbidiag.hpp:170
#define LOG_POST(message)
This macro is deprecated and it's strongly recomended to move in all projects (except tests) to macro...
Definition: ncbidiag.hpp:226
void Error(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1197
#define NCBI_THROW(exception_class, err_code, message)
Generic macro to throw an exception, given the exception class, error code and message string.
Definition: ncbiexpt.hpp:704
const CMemberId & GetId(void) const
const string & GetName(void) const
void ThrowCMacroExecException(const CDiagCompileInfo &info, CMacroExecException::EErrCode code, const string &message, const CQueryParseTree::TNode *treeNode, const CException *previous=nullptr)
Throws CMacroExecException with the specified message and error location from the TNode.
Definition: macro_ex.hpp:279
bool x_CheckAuthorNames(const CObjectInfo &obj)
const list< string > GetSynonymListForPhrase(const string &phrase) const
Function returns the synonym list of a given phrase.
Definition: macro_lib.cpp:92
virtual bool x_ValidArguments() const
checks whether the arguments number and their type is good and sets the m_Modifier flag in case of a ...
bool x_CheckConstraintWithinClass(const CObjectInfo &obj, const string &subtype)
list< SResolvedField > TObs
Definition: macro_exec.hpp:92
void SetBool(bool data)
Definition: macro_exec.hpp:127
static const string sm_syn
Classes related to STRING CONSTRAINTS.
void Dereference()
If it is a reference it is resolved to the first non reference type in the hierarchy.
Definition: macro_exec.cpp:94
const TObs & GetObjects() const
Definition: macro_exec.hpp:144
bool m_Modifier
flag that indicates that the field to be checked is a modifier
virtual void TheFunction()
Function implementation.
void SetDataType(EType dt)
Definition: macro_exec.hpp:121
string GetStringValue(CRef< CMQueryNodeValue > &value)
converts ints and doubles into string, by changing the type of the value
Definition: macro_util.cpp:330
bool x_CheckConstraintPrimitive(const string &field)
virtual CRef< objects::CWord_substitution > x_ReadSynonymsFor(const string &filename, const string &phrase)
EStrConstrCase m_TestCase
indicates to test for the case of the phrase
bool GetFieldsByName(CMQueryNodeValue::TObs *results, const CObjectInfo &oi_i, const string &field_name)
Resolve existing dot qualified ASN.1 name (field_name) starting from the object information instance ...
virtual CRef< objects::CWord_substitution > x_ReadSynonymsFor(const string &filename, const string &phrase)
CRef< objects::CString_constraint > m_Constraint
the string constraint
bool x_CheckConstraintObjects(const CMQueryNodeValue::TObs &objs)
CRef< CMQueryNodeValue > m_Result
virtual bool x_IsNestedFunctionReturnValid() const
CMacroFunction_StringConstraints(EScopeEnum func_scope, const string &type, EStrConstrCase testcase=eNotSet, ELogicType op_type=eOR)
string m_Type
specifies the type of pattern matching
static CMacroLib & GetInstance()
Definition: macro_lib.hpp:67
ELogicType m_Operation
flag to indicate whether to use OR or AND operation for the input values
void SwapGbQualWithValues(CMQueryNodeValue::TObs &objs)
Definition: macro_util.cpp:282
bool x_CheckStringConstraint(const CObjectInfo &oi)
static bool s_IsStringMatching(const string &fn_name)
CIRef< IMacroBioDataIter > m_DataIter
bool x_CheckConstraintContainer(const string &container, const string &subtype)
virtual CRef< objects::CWord_substitution > x_ReadSynonymsFor(const string &filename, const string &phrase)=0
void x_BuildStringConstraint(void)
builds a new string constraint to later match with the value of the field
static bool s_IsSynonymFile(const string &str)
size_t TMemberIndex
Type used for indexing class members and choice variants.
Definition: serialdef.hpp:230
@ ePrimitiveValueString
string|char*|const char*
Definition: serialdef.hpp:153
@ ePrimitiveValueEnum
enum
Definition: serialdef.hpp:154
@ eTypeFamilyClass
Definition: serialdef.hpp:140
@ eTypeFamilyContainer
Definition: serialdef.hpp:142
@ eTypeFamilyChoice
Definition: serialdef.hpp:141
@ eTypeFamilyPointer
Definition: serialdef.hpp:143
@ eTypeFamilyPrimitive
Definition: serialdef.hpp:139
bool Valid(void) const
Is iterator valid.
CElementIterator BeginElements(void) const
Create container elements iterator.
CObjectInfo GetPointedObject(void) const
Get data and type information of object to which this type refers.
Definition: objectinfo.cpp:102
CObjectInfo GetElement(void) const
Get element data and type information.
const CMemberInfo * GetMemberInfo(void) const
CMemberIterator BeginMembers(void) const
Create class member iterator.
CObjectInfo GetMember(void) const
Get class member data.
CChoiceVariant GetCurrentChoiceVariant(void) const
Get data and type information of selected choice variant.
CObjectInfo GetVariant(void) const
Get variant data.
bool Valid(void) const
Is iterator valid.
CMemberIterator GetClassMemberIterator(TMemberIndex index) const
Create class member iterator that initially points to specified member.
ETypeFamily GetTypeFamily(void) const
Get data type family.
void GetPrimitiveValueString(string &value) const
Get string data.
Definition: objectinfo.cpp:199
Int4 GetPrimitiveValueInt4(void) const
Get data as Int4.
Definition: objectinfo.cpp:174
const string & GetName(void) const
Get type name.
Definition: objectinfo.hpp:106
EPrimitiveValueType GetPrimitiveValueType(void) const
Get type of primitive value.
Definition: objectinfo.cpp:109
bool IsSet(void) const
Is member assigned a value.
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
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define USING_SCOPE(ns)
Use the specified namespace.
Definition: ncbistl.hpp:78
#define END_SCOPE(ns)
End the previously defined scope.
Definition: ncbistl.hpp:75
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
#define BEGIN_SCOPE(ns)
Define a new scope.
Definition: ncbistl.hpp:72
#define kEmptyStr
Definition: ncbistr.hpp:123
static bool EndsWith(const CTempString str, const CTempString end, ECase use_case=eCase)
Check if a string ends with a specified suffix value.
Definition: ncbistr.hpp:5430
static bool IsBlank(const CTempString str, SIZE_TYPE pos=0)
Check if a string is blank (has no text).
Definition: ncbistr.cpp:106
#define NPOS
Definition: ncbistr.hpp:133
static string IntToString(int value, TNumToStringFlags flags=0, int base=10)
Convert int to string.
Definition: ncbistr.hpp:5084
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:5412
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
static enable_if< is_arithmetic< TNumeric >::value||is_convertible< TNumeric, Int8 >::value, string >::type NumericToString(TNumeric value, TNumToStringFlags flags=0, int base=10)
Convert numeric value to string.
Definition: ncbistr.hpp:673
@ eString_location_inlist
@ eString_location_equals
@ eString_location_contains
@ eString_location_starts
@ eString_location_ends
FILE * file
yy_size_t n
Macro engine for macro execution.
Macro exceptions.
Functions that resolve field names described in asn format.
const struct ncbi::grid::netcache::search::fields::SIZE size
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1227
Defines classes: CDirEntry, CFile, CDir, CSymLink, CMemoryFile, CFileUtil, CFileLock,...
T min(T x_, T y_)
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
#define _ASSERT
Modified on Tue Apr 16 20:13:53 2024 by modify_doxy.py rev. 669887