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

Go to the SVN repository for this file.

1 /* $Id: ncbidiag_p.cpp 90627 2020-07-08 13:47:46Z grichenk $
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: Vyacheslav Kononenko
27  *
28  * File Description:
29  * NCBI service classes and functions for C++ diagnostic API
30  *
31  */
32 
33 #include <ncbi_pch.hpp>
34 #include "ncbidiag_p.hpp"
35 #include <corelib/ncbidiag.hpp>
36 
38 
39 
40 ///////////////////////////////////////////////////////
41 // CDiagStrMatcher::
42 
44 {
45 }
46 
47 
48 ///////////////////////////////////////////////////////
49 // CDiagStrEmptyMatcher::
50 
51 bool CDiagStrEmptyMatcher::Match(const char* str) const
52 {
53  return (!str || *str == '\0');
54 }
55 
56 
57 void CDiagStrEmptyMatcher::Print(ostream& out) const
58 {
59  out << '?';
60 }
61 
62 
63 
64 ///////////////////////////////////////////////////////
65 // CDiagStrStringMatcher::
66 
67 bool CDiagStrStringMatcher::Match(const char* str) const
68 {
69  if ( !str )
70  return false;
71  return m_Pattern == str;
72 }
73 
74 
75 void CDiagStrStringMatcher::Print(ostream& out) const
76 {
77  out << m_Pattern;
78 }
79 
80 
81 ///////////////////////////////////////////////////////
82 // CDiagStrPathMatcher::
83 
85  : m_Pattern(pattern)
86 {
87 # ifdef NCBI_OS_MSWIN
88  size_t pos;
89  // replace \ in windows path to /
90  while ( (pos = m_Pattern.find('\\')) != string::npos )
91  m_Pattern[pos] = '/';
92 # endif
93 }
94 
95 
96 bool CDiagStrPathMatcher::Match(const char* str) const
97 {
98  if ( !str )
99  return false;
100  string lstr(str);
101  size_t pos;
102 # ifdef NCBI_OS_MSWIN
103  // replace \ in windows path to /
104  while ( (pos = lstr.find('\\')) != string::npos )
105  lstr[pos] = '/';
106 # endif
107 
108  pos = lstr.find(m_Pattern);
109  if (pos == string::npos)
110  return false;
111 
112  // check if found pattern after src/ or include/
113  if ( !(pos > 2 && lstr.substr(pos-3, 3) == "src" ) &&
114  !(pos > 6 && lstr.substr(pos-7, 7) == "include" ) )
115  return false;
116 
117  // if pattern ends with / check that pattern matches all dirs
118  if (m_Pattern[m_Pattern.size()-1] != '/')
119  return true;
120 
121  // '/' should not be after place we found m_Pattern
122  return (lstr.find('/', pos + m_Pattern.size()) == string::npos);
123 }
124 
125 
126 void CDiagStrPathMatcher::Print(ostream& out) const
127 {
128  out << m_Pattern;
129 }
130 
131 /////////////////////////////////////////////////////////////////////////////
132 // CDiagStrErrCodeMatcher
133 
135 {
136  string code, subcode;
137  NStr::SplitInTwo(pattern,".",code, subcode);
139  x_Parse(m_SubCode,subcode);
140 }
141 
142 bool CDiagStrErrCodeMatcher::Match(const char* str) const
143 {
144  string first, second;
145  NStr::SplitInTwo(str,".", first, second);
146  if (!first.empty() && !second.empty()) {
148  TCode subcode = NStr::StringToInt( second);
149  return x_Match(m_Code,code) && x_Match(m_SubCode, subcode);
150  }
151  return false;
152 }
153 
154 void CDiagStrErrCodeMatcher::Print(ostream& out) const
155 {
156  x_Print(m_Code,out);
157  out << '.';
159 }
160 
161 void CDiagStrErrCodeMatcher::x_Parse(TPattern& pattern, const string& str)
162 {
163  list<string> loc;
164  NStr::Split( str, ",", loc,
166  list<string>::iterator it_loc;
167  for (it_loc = loc.begin(); it_loc != loc.end(); ++it_loc) {
168  string first, second;
169  const string& sloc = *it_loc;
170  size_t shift = 0;
171  if (sloc[0] == '-') {
172  shift = 1;
173  }
174  NStr::SplitInTwo( sloc.c_str() + shift,"-",first,second);
175  if (!first.empty()) {
176  TCode from, to;
177  to = from = NStr::StringToInt( first);
178  if (shift != 0) {
179  to = from = -from;
180  }
181  if (!second.empty()) {
182  to = NStr::StringToInt( second);
183  }
184  pattern.push_back( make_pair(from,to) );
185  }
186  }
187 }
188 
190 {
191  ITERATE( TPattern, c, pattern) {
192  if (code >= c->first && code <= c->second) {
193  return true;
194  }
195  }
196  return pattern.empty();
197 }
198 
199 void CDiagStrErrCodeMatcher::x_Print(const TPattern& pattern, ostream& out)
200 {
201  bool first = true;
202  ITERATE( TPattern, c, pattern) {
203  if (!first) {
204  out << ',';
205  }
206  if (c->first != c->second) {
207  out << c->first << '-' << c->second;
208  } else {
209  out << c->first;
210  }
211  first = false;
212  }
213 }
214 
215 
216 ///////////////////////////////////////////////////////
217 // CDiagMatcher::
218 
220  const char* nclass,
221  const char* function) const
222 {
223  if( !m_Module && !m_Class && !m_Function )
224  return eDiagFilter_None;
225 
228 
229  if ( m_Module && !m_Module ->Match(module ) )
230  return reverse;
231  if ( m_Class && !m_Class ->Match(nclass ) )
232  return reverse;
233  if ( m_Function && !m_Function->Match(function) )
234  return reverse;
235 
236  return m_Action;
237 }
238 
240 {
241  if (!m_ErrCode)
242  return eDiagFilter_None;
243  string str = NStr::IntToString(code);
244  str += '.';
245  str += NStr::IntToString(subcode);
246  if (m_ErrCode->Match(str.c_str())) {
247  return m_Action;
248  }
249  return m_Action == eDiagFilter_Reject ?
251 }
252 
254 {
255  if(!m_File)
256  return eDiagFilter_None;
257 
258  if(m_File->Match(file))
259  return m_Action;
260 
261  return m_Action == eDiagFilter_Reject ?
263 }
264 
265 inline
266 void s_PrintMatcher(ostream& out,
267  const AutoPtr<CDiagStrMatcher> &matcher,
268  const string& desc)
269 {
270  out << desc << "(";
271  if(matcher)
272  matcher->Print(out);
273  else
274  out << "NULL";
275  out << ") ";
276 }
277 
278 void CDiagMatcher::Print(ostream& out) const
279 {
281  out << '!';
282 
283  s_PrintMatcher(out, m_ErrCode, "ErrCode" );
284  s_PrintMatcher(out, m_File, "File" );
285  s_PrintMatcher(out, m_Module, "Module" );
286  s_PrintMatcher(out, m_Class, "Class" );
287  s_PrintMatcher(out, m_Function, "Function");
288 }
289 
290 
291 
292 ///////////////////////////////////////////////////////
293 // CDiagFilter::
294 
296 : m_NotMatchersNum(0)
297 {
298 }
299 
301 {
302  Clean();
303 }
304 
306 {
307  m_Matchers.clear();
308  m_NotMatchersNum = 0;
309 }
310 
311 void CDiagFilter::Fill(const char* filter_string)
312 {
313  try {
314  m_Filter.clear();
315  CDiagSyntaxParser parser;
316  CNcbiIstrstream in(filter_string);
317 
318  parser.Parse(in, *this);
319  m_Filter = filter_string;
320  }
321  catch (const CDiagSyntaxParser::TErrorInfo& err_info) {
322  CNcbiOstrstream message;
323  message << "Syntax error in string \"" << filter_string
324  << "\" at position:"
325  << err_info.second << " - " << err_info.first << ends;
326  NCBI_THROW(CCoreException, eDiagFilter,
327  CNcbiOstrstreamToString(message));
328  }
329 }
330 
331 void CDiagFilter::Append(const char* filter_string)
332 {
333  string new_filter = m_Filter + " " + filter_string;
334  Fill(new_filter.c_str());
335 }
336 
337 
339  const CException* ex) const
340 {
341  // if we do not have any filters -- accept
342  if (m_Matchers.empty()) {
343  return eDiagFilter_Accept;
344  }
345 
346  // Check errcode, file and location for the message
347  EDiagFilterAction action;
348  EDiagSev sev = msg.GetSeverity();
349  action = x_CheckErrCode(msg.GetErrorCode(), msg.GetErrorSubCode(), sev);
350  if (action == eDiagFilter_None) {
351  action = x_CheckFile(msg.GetFile(), sev);
352  }
353  if (action == eDiagFilter_None) {
354  action = x_CheckLocation(msg.GetModule(), msg.GetClass(), msg.GetFunction(), sev);
355  }
356 
357  // If specified, additionally check an exception and its backlog.
358  // Accept if one of the exceptions match.
359 
360  if (action == eDiagFilter_None && ex) {
361 
362  // Fast check on non errcode matchers.
363  // We already did errcode check above, exceptions have file/location only.
364  bool found = false;
366  if (!(*i)->IsErrCodeMatcher()) {
367  found = true;
368  break;
369  }
370  }
371  // If found at least one, process with check
372  if (found) {
373  const CException* pex;
374  for (pex = ex; pex; pex = pex->GetPredecessor()) {
375  action = x_CheckFile(pex->GetFile().c_str(), sev);
376  if (action == eDiagFilter_None) {
377  action = x_CheckLocation(pex->GetModule().c_str(),
378  pex->GetClass().c_str(),
379  pex->GetFunction().c_str(),
380  sev);
381  }
382  if (action == eDiagFilter_Accept) {
383  return action;
384  }
385  }
386  }
387  }
388 
389  // Reject if not accepted
390  if (action == eDiagFilter_None) {
391  action = eDiagFilter_Reject;
392  }
393  return action;
394 }
395 
396 
397 // same logic as in CheckFile()
399 {
400  size_t not_matchers_processed = 0;
401  size_t curr_ind = 0;
402 
404  ++curr_ind;
405  EDiagFilterAction action = (*i)->MatchErrCode(code, subcode);
406 
407  switch( action )
408  {
409  case eDiagFilter_Accept:
410  if ( not_matchers_processed < m_NotMatchersNum ) {
411  ++not_matchers_processed;
412  // Check severity ...
413  if (int(sev) < int((*i)->GetSeverity())) {
414  return eDiagFilter_Reject;
415  }
416  if ( curr_ind != m_Matchers.size() ) {
417  continue;
418  } else {
419  return eDiagFilter_Accept;
420  }
421  }
422  // Process *OR* conditions *PLUS* severity
423  if (int(sev) < int((*i)->GetSeverity())) {
424  continue;
425  }
426  return eDiagFilter_Accept;
427 
428  case eDiagFilter_Reject:
429  if ( not_matchers_processed < m_NotMatchersNum ) {
430  ++not_matchers_processed;
431  return eDiagFilter_Reject;
432  }
433  if ( curr_ind != m_Matchers.size() ) {
434  continue;
435  }
436  return eDiagFilter_Reject;
437 
438  case eDiagFilter_None:
439  if ( not_matchers_processed < m_NotMatchersNum ) {
440  ++not_matchers_processed;
441  }
442  break;
443  }
444  }
445 
446  return eDiagFilter_None;
447 }
448 
450 {
451  size_t not_matchers_processed = 0;
452  size_t curr_ind = 0;
453 
455  ++curr_ind;
456  EDiagFilterAction action = (*i)->MatchFile(file);
457 
458  switch( action )
459  {
460  case eDiagFilter_Accept:
461  // Process all *AND NOT* conditions.
462  if ( not_matchers_processed < m_NotMatchersNum ) {
463  // Not all *AND* conditions are still processed.
464  // Continue to check.
465  ++not_matchers_processed;
466  // Check severity ...
467  if (int(sev) < int((*i)->GetSeverity())) {
468  return eDiagFilter_Reject;
469  }
470  if ( curr_ind != m_Matchers.size() ) {
471  continue;
472  }
473  return eDiagFilter_Accept;
474  }
475  // Process *OR* conditions *PLUS* severity
476  if (int(sev) < int((*i)->GetSeverity())) {
477  continue;
478  }
479  return eDiagFilter_Accept;
480 
481  case eDiagFilter_Reject:
482  // Process all *AND NOT* and *OR* conditions.
483  if ( not_matchers_processed < m_NotMatchersNum ) {
484  // *AND* failed ...
485  ++not_matchers_processed;
486  return eDiagFilter_Reject;
487  }
488  if ( curr_ind != m_Matchers.size() ) {
489  // It is still not the end of a list of the *OR* matchers.
490  // Continue to check for a success.
491  continue;
492  }
493  return eDiagFilter_Reject;
494 
495  case eDiagFilter_None:
496  // Continue the loop.
497  if ( not_matchers_processed < m_NotMatchersNum ) {
498  ++not_matchers_processed;
499  }
500  break;
501  }
502  }
503 
504  return eDiagFilter_None;
505 }
506 
507 // Check if the filter accepts module, class and function
509  const char* nclass,
510  const char* function,
511  EDiagSev sev) const
512 {
513  size_t not_matchers_processed = 0;
514  size_t curr_ind = 0;
515 
517  ++curr_ind;
518  EDiagFilterAction action = (*i)->Match(module, nclass, function);
519 
520  switch( action )
521  {
522  case eDiagFilter_Accept:
523  // Process all *AND NOT* conditions.
524  if ( not_matchers_processed < m_NotMatchersNum ) {
525  // Not all *AND* conditions are still processed.
526  // Continue to check.
527  ++not_matchers_processed;
528  // Check severity ...
529  if ( int(sev) < int((*i)->GetSeverity()) ) {
530  return eDiagFilter_Reject;
531  }
532  if ( curr_ind != m_Matchers.size() ) {
533  continue;
534  }
535  return eDiagFilter_Accept;
536  }
537  // Process *OR* conditions *PLUS* severity
538  if ( int(sev) < int((*i)->GetSeverity()) ) {
539  continue;
540  }
541  return eDiagFilter_Accept;
542 
543  case eDiagFilter_Reject:
544  // Process all *AND NOT* and *OR* conditions.
545  if ( not_matchers_processed < m_NotMatchersNum ) {
546  // *AND* failed ...
547  ++not_matchers_processed;
548  return eDiagFilter_Reject;
549  }
550  if ( curr_ind != m_Matchers.size() ) {
551  // It is still not the end of a list of the *OR* matchers.
552  // Continue to check for a success.
553  continue;
554  }
555  return eDiagFilter_Reject;
556 
557  case eDiagFilter_None:
558  // Continue the loop.
559  if ( not_matchers_processed < m_NotMatchersNum ) {
560  ++not_matchers_processed;
561  }
562  break;
563  }
564  }
565 
566  return eDiagFilter_None;
567 }
568 
569 
570 void CDiagFilter::Print(ostream& out) const
571 {
572  int count = 0;
574  out << "\tFilter " << count++ << " - ";
575  (*i)->Print(out);
576  out << endl;
577  }
578 }
579 
580 
581 
582 /////////////////////////////////////////////////////////////////////////////
583 /// CDiagLexParser::
584 
586  : m_Pos(0)
587 {
588 }
589 
590 
591 // Takes next lexical symbol from the stream
593 {
594  CT_INT_TYPE symbol0;
595  enum EState {
596  eStart,
597  eExpectColon,
598  eExpectClosePar,
599  eExpectCloseBracket,
600  eInsideId,
601  eInsidePath,
602  eInsideErrCode,
603  eSpace
604  };
605  EState state = eStart;
606 
607  while( true ){
608  symbol0 = in.get();
609  if (CT_EQ_INT_TYPE(symbol0, CT_EOF)) {
610  break;
611  }
612  CT_CHAR_TYPE symbol = CT_TO_CHAR_TYPE(symbol0);
613  m_Pos++;
614 
615  switch( state ) {
616  case eStart:
617  switch( symbol ) {
618  case '?' :
619  m_Str = '?';
620  return eId;
621  case '!' :
622  return eExpl;
623  case ':' :
624  state = eExpectColon;
625  break;
626  case '(' :
627  state = eExpectClosePar;
628  break;
629  case '[':
630  m_Str = kEmptyStr;
631  state = eExpectCloseBracket;
632  break;
633  case '\\':
634  case '/' :
635  state = eInsidePath;
636  m_Str = symbol;
637  break;
638  default :
639  if ( isspace((unsigned char) symbol) )
640  {
641  state = eSpace;
642  break;
643  }
644  if ( !isalpha((unsigned char) symbol) && symbol != '_' )
645  throw CDiagSyntaxParser::TErrorInfo("wrong symbol", m_Pos);
646  m_Str = symbol;
647  state = eInsideId;
648  }
649  break;
650  case eSpace :
651  if ( !isspace((unsigned char) symbol) ) {
652  if ( symbol == '[' ||
653  symbol == '(' ||
654  symbol == '/' ||
655  (symbol == '!' && CT_TO_CHAR_TYPE(in.peek()) == '(') ||
656  (symbol == '!' && CT_TO_CHAR_TYPE(in.peek()) == '/')) {
657  in.putback( symbol );
658  --m_Pos;
659  state = eStart;
660  break;
661  }
662  in.putback( symbol );
663  --m_Pos;
664  return eDone;
665  }
666  break;
667  case eExpectColon :
668  if( isspace((unsigned char) symbol) )
669  break;
670  if( symbol == ':' )
671  return eDoubleColon;
673  ( "wrong symbol, expected :", m_Pos );
674  case eExpectClosePar :
675  if( isspace((unsigned char) symbol) )
676  break;
677  if( symbol == ')' )
678  return ePars;
679  if( symbol == '+' || symbol == '-' ||
680  symbol == '.' ||
681  isdigit((unsigned char) symbol)) {
682  state = eInsideErrCode;
683  m_Str = symbol;
684  break;
685  }
687  ( "wrong symbol, expected )", m_Pos );
688  case eExpectCloseBracket:
689  if (symbol == ']') {
690  return eBrackets;
691  }
692  if( isspace((unsigned char) symbol) )
693  break;
694  m_Str += symbol;
695  break;
696  case eInsideId :
697  if(isalpha((unsigned char) symbol) ||
698  isdigit((unsigned char) symbol) || symbol == '_') {
699  m_Str += symbol;
700  break;
701  }
702  in.putback( symbol );
703  m_Pos--;
704  return eId;
705  case eInsidePath :
706  if( isspace((unsigned char) symbol) )
707  return ePath;
708  m_Str += symbol;
709  break;
710  case eInsideErrCode:
711  if( symbol == '+' || symbol == '-' ||
712  symbol == '.' || symbol == ',' ||
713  isdigit((unsigned char) symbol)) {
714  m_Str += symbol;
715  break;
716  }
717  if( symbol == ')' )
718  return eErrCode;
719  break;
720  }
721  }
722 
723  switch ( state ) {
724  case eExpectColon :
726  ( "unexpected end of input, ':' expected", m_Pos );
727  case eExpectClosePar :
729  ( "unexpected end of input, ')' expected", m_Pos );
730  case eExpectCloseBracket:
732  ( "unexpected end of input, ']' expected", m_Pos );
733  case eInsideId :
734  return eId;
735  case eInsidePath :
736  return ePath;
737  case eStart :
738  break;
739  default:
740  break;
741  }
742 
743  return eEnd;
744 }
745 
746 
747 
748 /////////////////////////////////////////////////////////////////////////////
749 /// CDiagSyntaxParser::
750 
752  : m_Pos(0),
753  m_Negative(false),
754  m_DiagSev(eDiag_Info)
755 {
756 }
757 
758 
760 {
761  CDiagMatcher* matcher = 0;
762  switch ( m_Matchers.size() ) {
763  case 0 :
764  matcher = new CDiagMatcher
765  (
768  NULL,
769  NULL,
770  NULL,
772  );
773  break;
774  case 1:
775  matcher = new CDiagMatcher
776  (
779  // the matcher goes to module if function is not enforced
780  into == eFunction ? NULL : m_Matchers[0].release(),
781  NULL,
782  into == eFunction ? m_Matchers[0].release() : NULL,
783  // the matcher goes to function if function is enforced
785  );
786  break;
787  case 2:
788  matcher = new CDiagMatcher
789  (
792  // the first matcher goes to module
793  m_Matchers[0].release(),
794  // the second matcher goes to class if function is not enforced
795  into == eFunction ? NULL : m_Matchers[1].release(),
796  // the second matcher goes to function if function is enforced
797  into == eFunction ? m_Matchers[1].release() : NULL,
799  );
800  break;
801  case 3:
802  matcher = new CDiagMatcher
803  (
806  // the first matcher goes to module
807  m_Matchers[0].release(),
808  // the second matcher goes to class
809  m_Matchers[1].release(),
810  // the third matcher goes to function
811  m_Matchers[2].release(),
813  );
814  break;
815  default :
816  _ASSERT( false );
817  return;
818  }
819  m_Matchers.clear();
822  matcher->SetSeverity(m_DiagSev);
823  // reset severity for next matcher
825 
826  _ASSERT( matcher );
827 
828  if ( m_Negative ) {
829  to.InsertNegativeMatcher( matcher );
830  } else {
831  to.InsertMatcher( matcher );
832  }
833 }
834 
835 
837 {
838  _ASSERT( !str.empty() );
839 
840  if (str == "?")
841  return new CDiagStrEmptyMatcher;
842 
843  return new CDiagStrStringMatcher(str);
844 }
845 
846 
847 
849 {
850  if (NStr::CompareNocase(sev_str, "Info") == 0) {
851  return eDiag_Info;
852  }
853  if (NStr::CompareNocase(sev_str, "Warning") == 0) {
854  return eDiag_Warning;
855  }
856  if (NStr::CompareNocase(sev_str, "Error") == 0) {
857  return eDiag_Error;
858  }
859  if (NStr::CompareNocase(sev_str, "Critical") == 0) {
860  return eDiag_Critical;
861  }
862  if (NStr::CompareNocase(sev_str, "Fatal") == 0) {
863  return eDiag_Fatal;
864  }
865  if (NStr::CompareNocase(sev_str, "Trace") == 0) {
866  return eDiag_Trace;
867  }
868  throw TErrorInfo("Incorrect severity level", m_Pos);
869 
870 }
871 
873 {
874  enum EState {
875  eStart,
876  eGotExpl,
877  eGotModule,
878  eGotModuleOrFunction,
879  eGotClass,
880  eGotFunction,
881  eGotClassOrFunction,
882  eReadyForFunction
883  };
884 
885  CDiagLexParser lexer;
886  EState state = eStart;
887  m_Negative = false;
888 
890  try {
891  to.Clean();
892 
893  for (;;) {
894  if (symbol == CDiagLexParser::eDone)
895  symbol = lexer.Parse(in);
896 
897  switch (state) {
898 
899  case eStart :
900  switch (symbol) {
902  m_Negative = true;
903  state = eGotExpl;
904  break;
906  m_Matchers.push_back(NULL); // push empty module
907  state = eGotModule;
908  break;
909  case CDiagLexParser::eId:
910  m_Matchers.push_back( x_CreateMatcher(lexer.GetId()) );
911  state = eGotModuleOrFunction;
912  break;
914  m_FileMatcher = new CDiagStrPathMatcher(lexer.GetId());
916  m_Negative = false;
917  break;
921  m_Negative = false;
922  break;
924  {
925  EDiagSev sev = x_GetDiagSeverity(lexer.GetId());
926  // trace is not controlled by this filtering
927  if (sev == eDiag_Trace) {
928  throw TErrorInfo("unexpected 'Trace' severity", m_Pos);
929  }
930  m_DiagSev = sev;
931  }
932  break;
934  break;
935  default :
936  throw TErrorInfo("'!' '::' '[]' or 'id' expected", m_Pos);
937  }
938  break;
939 
940  case eGotExpl :
941  switch (symbol) {
942  case CDiagLexParser::eId:
943  m_Matchers.push_back( x_CreateMatcher(lexer.GetId()) );
944  state = eGotModuleOrFunction;
945  break;
947  m_Matchers.push_back(NULL); // push empty module
948  state = eGotModule;
949  break;
951  m_FileMatcher = new CDiagStrPathMatcher(lexer.GetId());
953  m_Negative = false;
954  state = eStart;
955  break;
959  m_Negative = false;
960  state = eStart;
961  break;
962  default :
963  throw TErrorInfo("'::' or 'id' expected", m_Pos);
964  }
965  break;
966 
967  case eGotModule :
968  switch ( symbol ) {
969  case CDiagLexParser::eId:
970  m_Matchers.push_back( x_CreateMatcher(lexer.GetId()) );
971  state = eGotClassOrFunction;
972  break;
973  default :
974  throw TErrorInfo("'id' expected", m_Pos);
975  }
976  break;
977 
978  case eGotModuleOrFunction :
979  switch( symbol ) {
981  state = eGotFunction;
982  break;
984  state = eGotModule;
985  break;
986  default :
987  x_PutIntoFilter( to, eModule );
988  m_Negative = false;
989  state = eStart;
990  continue;
991  }
992  break;
993 
994  case eGotFunction :
996  m_Negative = false;
997  state = eStart;
998  continue;
999 
1000  case eGotClassOrFunction :
1001  switch( symbol ) {
1002  case CDiagLexParser::ePars:
1003  state = eGotFunction;
1004  break;
1006  state = eGotClass;
1007  break;
1008  default :
1009  x_PutIntoFilter( to, eModule );
1010  m_Negative = false;
1011  state = eStart;
1012  continue;
1013  }
1014  break;
1015 
1016  case eGotClass :
1017  switch( symbol ) {
1018  case CDiagLexParser::eId:
1019  m_Matchers.push_back( x_CreateMatcher(lexer.GetId()) );
1020  state = eReadyForFunction;
1021  break;
1022  default :
1023  throw TErrorInfo("'id' expected", m_Pos);
1024  }
1025  break;
1026 
1027  case eReadyForFunction :
1028  switch( symbol ) {
1029  case CDiagLexParser::ePars:
1030  state = eGotFunction;
1031  break;
1032  default :
1033  x_PutIntoFilter(to, eModule);
1034  m_Negative = false;
1035  state = eStart;
1036  continue;
1037  }
1038  break;
1039  }
1040  if( symbol == CDiagLexParser::eEnd ) break;
1041  symbol = CDiagLexParser::eDone;
1042  m_Pos = lexer.GetPos();
1043 
1044  }
1045  }
1046  catch (...) {
1047  to.Clean();
1048  throw;
1049  }
1050 }
1051 
1052 
1053 
CCoreException –.
Definition: ncbiexpt.hpp:1476
CDiagFilter –.
Definition: ncbidiag_p.hpp:247
~CDiagFilter(void)
Definition: ncbidiag_p.cpp:300
void Fill(const char *filter_string)
Fill the filter from a string.
Definition: ncbidiag_p.cpp:311
EDiagFilterAction Check(const CNcbiDiag &msg, const CException *ex=NULL) const
Check if the filter accepts message.
Definition: ncbidiag_p.cpp:338
void InsertNegativeMatcher(CDiagMatcher *matcher)
Definition: ncbidiag_p.hpp:292
CDiagFilter(void)
Definition: ncbidiag_p.cpp:295
EDiagFilterAction x_CheckLocation(const char *module, const char *nclass, const char *function, EDiagSev sev) const
Definition: ncbidiag_p.cpp:508
EDiagFilterAction x_CheckFile(const char *file, EDiagSev sev) const
Check if the filter accepts path.
Definition: ncbidiag_p.cpp:449
deque< AutoPtr< CDiagMatcher > > TMatchers
Definition: ncbidiag_p.hpp:302
TMatchers m_Matchers
Definition: ncbidiag_p.hpp:304
EDiagFilterAction x_CheckErrCode(int code, int subcode, EDiagSev sev) const
Check if the filter accepts errcode.
Definition: ncbidiag_p.cpp:398
void Append(const char *filter_string)
Definition: ncbidiag_p.cpp:331
string m_Filter
Definition: ncbidiag_p.hpp:303
size_t m_NotMatchersNum
Definition: ncbidiag_p.hpp:305
void Clean(void)
Definition: ncbidiag_p.cpp:305
void Print(ostream &out) const
Print state.
Definition: ncbidiag_p.cpp:570
void InsertMatcher(CDiagMatcher *matcher)
Definition: ncbidiag_p.hpp:285
CDiagLexParser –.
Definition: ncbidiag_p.hpp:318
ESymbol Parse(istream &in)
Definition: ncbidiag_p.cpp:592
int GetPos() const
Definition: ncbidiag_p.hpp:343
const string & GetId() const
Definition: ncbidiag_p.hpp:340
CDiagLexParser()
CDiagLexParser::
Definition: ncbidiag_p.cpp:585
CDiagMatcher –.
Definition: ncbidiag_p.hpp:193
AutoPtr< CDiagStrMatcher > m_Module
Definition: ncbidiag_p.hpp:229
AutoPtr< CDiagStrMatcher > m_Function
Definition: ncbidiag_p.hpp:231
AutoPtr< CDiagStrMatcher > m_ErrCode
Definition: ncbidiag_p.hpp:227
EDiagFilterAction MatchFile(const char *file) const
Definition: ncbidiag_p.cpp:253
EDiagFilterAction Match(const char *module, const char *nclass, const char *function) const
Definition: ncbidiag_p.cpp:219
void Print(ostream &out) const
Definition: ncbidiag_p.cpp:278
void SetSeverity(EDiagSev sev)
Definition: ncbidiag_p.hpp:222
EDiagFilterAction MatchErrCode(int code, int subcode) const
Definition: ncbidiag_p.cpp:239
AutoPtr< CDiagStrMatcher > m_File
Definition: ncbidiag_p.hpp:228
AutoPtr< CDiagStrMatcher > m_Class
Definition: ncbidiag_p.hpp:230
EDiagFilterAction m_Action
Definition: ncbidiag_p.hpp:232
CDiagStrEmptyMatcher –.
Definition: ncbidiag_p.hpp:89
virtual bool Match(const char *str) const
Return true if str is empty.
Definition: ncbidiag_p.cpp:51
virtual void Print(ostream &out) const
Definition: ncbidiag_p.cpp:57
CDiagStrErrCodeMatcher –.
Definition: ncbidiag_p.hpp:157
static void x_Parse(TPattern &pattern, const string &str)
Definition: ncbidiag_p.cpp:161
CDiagStrErrCodeMatcher(const string &pattern)
Definition: ncbidiag_p.cpp:134
static bool x_Match(const TPattern &pattern, TCode code)
Definition: ncbidiag_p.cpp:189
virtual bool Match(const char *str) const
Return true if str matches pattern str ::= errcode ':' subcode.
Definition: ncbidiag_p.cpp:142
static void x_Print(const TPattern &pattern, ostream &out)
Definition: ncbidiag_p.cpp:199
virtual void Print(ostream &out) const
Definition: ncbidiag_p.cpp:154
vector< pair< TCode, TCode > > TPattern
Definition: ncbidiag_p.hpp:175
CDiagStrMatcher –.
Definition: ncbidiag_p.hpp:68
virtual void Print(ostream &out) const =0
virtual ~CDiagStrMatcher()
Definition: ncbidiag_p.cpp:43
virtual bool Match(const char *str) const =0
Return true if str matches for this object.
CDiagStrPathMatcher –.
Definition: ncbidiag_p.hpp:133
virtual void Print(ostream &out) const
Definition: ncbidiag_p.cpp:126
virtual bool Match(const char *str) const
Return true if str is equal to pattern.
Definition: ncbidiag_p.cpp:96
CDiagStrPathMatcher(const string &pattern)
Definition: ncbidiag_p.cpp:84
CDiagStrStringMatcher –.
Definition: ncbidiag_p.hpp:108
virtual bool Match(const char *str) const
Return true if str is equal to pattern.
Definition: ncbidiag_p.cpp:67
virtual void Print(ostream &out) const
Definition: ncbidiag_p.cpp:75
CDiagSyntaxParser –.
Definition: ncbidiag_p.hpp:360
TMatchers m_Matchers
Definition: ncbidiag_p.hpp:389
CDiagSyntaxParser()
CDiagSyntaxParser::
Definition: ncbidiag_p.cpp:751
EDiagSev x_GetDiagSeverity(const string &sev_str)
"Info", "Warning", etc converted to enum value Throws an excpetion if incorrect value passed
Definition: ncbidiag_p.cpp:848
pair< const char *, int > TErrorInfo
Definition: ncbidiag_p.hpp:363
AutoPtr< CDiagStrErrCodeMatcher > m_ErrCodeMatcher
Definition: ncbidiag_p.hpp:390
void Parse(istream &in, CDiagFilter &to)
Definition: ncbidiag_p.cpp:872
AutoPtr< CDiagStrMatcher > m_FileMatcher
Definition: ncbidiag_p.hpp:391
static CDiagStrMatcher * x_CreateMatcher(const string &str)
Definition: ncbidiag_p.cpp:836
void x_PutIntoFilter(CDiagFilter &to, EInto into)
Definition: ncbidiag_p.cpp:759
CNcbiDiag –.
Definition: ncbidiag.hpp:924
CNcbiOstrstreamToString class helps convert CNcbiOstrstream to a string Sample usage:
Definition: ncbistre.hpp:802
std::ofstream out("events_result.xml")
main entry point for tests
#define false
Definition: bool.h:36
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
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
element_type * release(void)
Release will release ownership of pointer to caller.
Definition: ncbimisc.hpp:472
#define NULL
Definition: ncbistd.hpp:225
int GetErrorSubCode(void) const
Get error subcode of the current message.
const char * GetModule(void) const
Get module name of the current message.
int GetErrorCode(void) const
Get error code of the current message.
const char * GetFunction(void) const
Get function name of the current message.
const char * GetClass(void) const
Get class name of the current message.
EDiagSev
Severity level for the posted diagnostics.
Definition: ncbidiag.hpp:650
const char * GetFile(void) const
Get file used for the current message.
EDiagSev GetSeverity(void) const
Get severity of the current message.
@ eDiag_Trace
Trace message.
Definition: ncbidiag.hpp:657
@ eDiag_Info
Informational message.
Definition: ncbidiag.hpp:651
@ eDiag_Error
Error message.
Definition: ncbidiag.hpp:653
@ eDiag_Warning
Warning message.
Definition: ncbidiag.hpp:652
@ eDiag_Fatal
Fatal error – guarantees exit(or abort)
Definition: ncbidiag.hpp:655
@ eDiag_Critical
Critical error message.
Definition: ncbidiag.hpp:654
const string & GetModule(void) const
Get module name used for reporting.
Definition: ncbiexpt.hpp:1017
const string & GetFile(void) const
Get file name used for reporting.
Definition: ncbiexpt.hpp:1011
#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 string & GetClass(void) const
Get class name used for reporting.
Definition: ncbiexpt.hpp:1023
const string & GetFunction(void) const
Get function name used for reporting.
Definition: ncbiexpt.hpp:1029
const CException * GetPredecessor(void) const
Get "previous" exception from the backlog.
Definition: ncbiexpt.hpp:1041
#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 CT_TO_CHAR_TYPE
Definition: ncbistre.hpp:735
#define CT_EOF
Definition: ncbistre.hpp:732
#define CT_INT_TYPE
Definition: ncbistre.hpp:728
#define CT_EQ_INT_TYPE
Definition: ncbistre.hpp:736
#define CT_CHAR_TYPE
Definition: ncbistre.hpp:729
#define kEmptyStr
Definition: ncbistr.hpp:123
static int CompareNocase(const CTempString s1, SIZE_TYPE pos, SIZE_TYPE n, const char *s2)
Case-insensitive compare of a substring with another string.
Definition: ncbistr.cpp:219
static int StringToInt(const CTempString str, TStringToNumFlags flags=0, int base=10)
Convert string to int.
Definition: ncbistr.cpp:630
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 string IntToString(int value, TNumToStringFlags flags=0, int base=10)
Convert int to string.
Definition: ncbistr.hpp:5084
static bool SplitInTwo(const CTempString str, const CTempString delim, string &str1, string &str2, TSplitFlags flags=0)
Split a string into two pieces using the specified delimiters.
Definition: ncbistr.cpp:3554
@ fSplit_Truncate
Definition: ncbistr.hpp:2501
@ fSplit_MergeDelimiters
Merge adjacent delimiters.
Definition: ncbistr.hpp:2498
FILE * file
int i
int isalpha(Uchar c)
Definition: ncbictype.hpp:61
int isspace(Uchar c)
Definition: ncbictype.hpp:69
int isdigit(Uchar c)
Definition: ncbictype.hpp:64
Defines NCBI C++ diagnostic APIs, classes, and macros.
void s_PrintMatcher(ostream &out, const AutoPtr< CDiagStrMatcher > &matcher, const string &desc)
Definition: ncbidiag_p.cpp:266
Defines NCBI C++ service classes and functions for diagnostic APIs, classes, and macros.
EDiagFilterAction
Definition: ncbidiag_p.hpp:53
@ eDiagFilter_None
Definition: ncbidiag_p.hpp:54
@ eDiagFilter_Reject
Definition: ncbidiag_p.hpp:56
@ eDiagFilter_Accept
Definition: ncbidiag_p.hpp:55
std::istream & in(std::istream &in_, double &x_)
Definition: inftrees.h:24
#define _ASSERT
@ eSpace
Definition: text_util.cpp:56
Modified on Wed Apr 17 13:09:19 2024 by modify_doxy.py rev. 669887