1 #ifndef CORELIB___NCBIDIAG_P__HPP 2 #define CORELIB___NCBIDIAG_P__HPP 3 4 /* $Id: ncbidiag_p.hpp 611586 2020-07-08 13:47:46Z grichenk $ 5 * =========================================================================== 6 * 7 * PUBLIC DOMAIN NOTICE 8 * National Center for Biotechnology Information 9 * 10 * This software/database is a "United States Government Work" under the 11 * terms of the United States Copyright Act. It was written as part of 12 * the author's official duties as a United States Government employee and 13 * thus cannot be copyrighted. This software/database is freely available 14 * to the public for use. The National Library of Medicine and the U.S. 15 * Government have not placed any restriction on its use or reproduction. 16 * 17 * Although all reasonable efforts have been taken to ensure the accuracy 18 * and reliability of the software and data, the NLM and the U.S. 19 * Government do not and cannot warrant the performance or results that 20 * may be obtained by using this software or data. The NLM and the U.S. 21 * Government disclaim all warranties, express or implied, including 22 * warranties of performance, merchantability or fitness for any particular 23 * purpose. 24 * 25 * Please cite the author in any work or product based on this material. 26 * 27 * =========================================================================== 28 * 29 * Author: Vyacheslav Kononenko 30 * 31 * 32 */ 33 34 /// @file ncbidiag_p.hpp 35 /// 36 /// Defines NCBI C++ service classes and functions for diagnostic APIs, 37 /// classes, and macros. 38 /// 39 /// More elaborate documentation could be found in: 40 /// http://ncbi.github.io/cxx-toolkit/pages/ch_log 41 42 #include <corelib/ncbiutil.hpp> 43 #include <deque> 44 45 BEGIN_NCBI_SCOPE 46 47 48 ///////////////////////////////////////////////////////////////////////////// 49 /// Forward declaration 50 51 class CNcbiDiag; 52 53 enum EDiagFilterAction { 54 eDiagFilter_None, 55 eDiagFilter_Accept, 56 eDiagFilter_Reject 57 }; 58 59 60 ///////////////////////////////////////////////////////////////////////////// 61 /// 62 /// CDiagStrMatcher -- 63 /// 64 /// Abstract class that matches a char* string. 65 /// 66 67 class CDiagStrMatcher 68 { 69 public: 70 virtual ~CDiagStrMatcher(); 71 72 /// Return true if str matches for this object 73 virtual bool Match(const char* str) const = 0; 74 75 // Print state 76 virtual void Print(ostream& out) const = 0; 77 }; 78 79 80 81 ///////////////////////////////////////////////////////////////////////////// 82 /// 83 /// CDiagStrEmptyMatcher -- 84 /// 85 /// Specialization of CDiagStrMatcher that matches an empty string. 86 /// 87 88 class CDiagStrEmptyMatcher : public CDiagStrMatcher 89 { 90 public: 91 /// Return true if str is empty 92 virtual bool Match(const char* str) const; 93 94 // Print state 95 virtual void Print(ostream& out) const; 96 }; 97 98 99 100 ///////////////////////////////////////////////////////////////////////////// 101 /// 102 /// CDiagStrStringMatcher -- 103 /// 104 /// Specialization of CDiagStrMatcher that matches a given string. 105 /// 106 107 class CDiagStrStringMatcher : public CDiagStrMatcher 108 { 109 public: 110 // Constructor - set the pattern to match CDiagStrStringMatcher(const string & pattern)111 CDiagStrStringMatcher(const string& pattern) 112 : m_Pattern(pattern) 113 {} 114 115 /// Return true if str is equal to pattern 116 virtual bool Match(const char* str) const; 117 118 // Print state 119 virtual void Print(ostream& out) const; 120 121 private: 122 string m_Pattern; 123 }; 124 125 ///////////////////////////////////////////////////////////////////////////// 126 /// 127 /// CDiagStrPathMatcher -- 128 /// 129 /// Specialization of CDiagStrMatcher that matches a path to the source file 130 /// 131 132 class CDiagStrPathMatcher : public CDiagStrMatcher 133 { 134 public: 135 // Constructor - set the pattern to match. The pattern is converted 136 // to UNIX format ('/' rather than '\' or ':'). 137 CDiagStrPathMatcher(const string& pattern); 138 139 /// Return true if str is equal to pattern 140 virtual bool Match(const char* str) const; 141 142 // Print state 143 virtual void Print(ostream& out) const; 144 145 private: 146 string m_Pattern; 147 }; 148 149 ///////////////////////////////////////////////////////////////////////////// 150 /// 151 /// CDiagStrErrCodeMatcher -- 152 /// 153 /// Specialization of CDiagStrMatcher that matches error codes 154 /// 155 156 class CDiagStrErrCodeMatcher : public CDiagStrMatcher 157 { 158 public: 159 // Constructor - set the pattern to match. 160 // Pattern ::= coderange '.' coderange 161 // coderange ::= (int | intpair) (',' (int | intpair))* 162 // intpair ::= int '-' int 163 // int ::= integer 164 CDiagStrErrCodeMatcher(const string& pattern); 165 166 /// Return true if str matches pattern 167 /// str ::= errcode ':' subcode 168 virtual bool Match(const char* str) const; 169 170 // Print state 171 virtual void Print(ostream& out) const; 172 173 private: 174 typedef int TCode; 175 typedef vector< pair<TCode, TCode> > TPattern; 176 177 static void x_Parse(TPattern& pattern, const string& str); 178 static bool x_Match(const TPattern& pattern, TCode code); 179 static void x_Print(const TPattern& pattern, ostream& out); 180 TPattern m_Code; 181 TPattern m_SubCode; 182 }; 183 184 185 ///////////////////////////////////////////////////////////////////////////// 186 /// 187 /// CDiagMatcher -- 188 /// 189 /// Matcher of CNcbiDiag for module, class and function name if any 190 /// 191 192 class CDiagMatcher 193 { 194 public: 195 // Takes ownership of module, nclass and function. 196 // If NULL pointer passed as CDiagStrMatcher*, then it accepts anything CDiagMatcher(CDiagStrMatcher * errcode,CDiagStrMatcher * file,CDiagStrMatcher * module,CDiagStrMatcher * nclass,CDiagStrMatcher * func,EDiagFilterAction action)197 CDiagMatcher(CDiagStrMatcher* errcode, 198 CDiagStrMatcher* file, 199 CDiagStrMatcher* module, 200 CDiagStrMatcher* nclass, 201 CDiagStrMatcher* func, 202 EDiagFilterAction action) 203 : m_ErrCode(errcode), m_File(file), 204 m_Module(module), m_Class(nclass), m_Function(func), 205 m_Action(action), m_DiagSev(eDiag_Info) 206 {} 207 208 EDiagFilterAction MatchErrCode(int code, int subcode) const; 209 210 // Check if the filter accepts a filename 211 EDiagFilterAction MatchFile(const char* file) const; 212 213 // Match whole set 214 EDiagFilterAction Match(const char* module, 215 const char* nclass, 216 const char* function) const; 217 218 // Print state 219 void Print(ostream& out) const; 220 GetSeverity() const221 EDiagSev GetSeverity() const { return m_DiagSev; } SetSeverity(EDiagSev sev)222 void SetSeverity(EDiagSev sev) { m_DiagSev = sev; } 223 IsErrCodeMatcher(void) const224 bool IsErrCodeMatcher(void) const {return m_ErrCode.get() != 0;} 225 226 private: 227 AutoPtr<CDiagStrMatcher> m_ErrCode; 228 AutoPtr<CDiagStrMatcher> m_File; 229 AutoPtr<CDiagStrMatcher> m_Module; 230 AutoPtr<CDiagStrMatcher> m_Class; 231 AutoPtr<CDiagStrMatcher> m_Function; 232 EDiagFilterAction m_Action; 233 EDiagSev m_DiagSev; 234 }; 235 236 237 238 ///////////////////////////////////////////////////////////////////////////// 239 /// 240 /// CDiagFilter -- 241 /// 242 /// Checks if SDiagMessage should be passed. 243 /// Contains 0..N CDiagMatcher objects 244 /// 245 246 class NCBI_XNCBI_EXPORT CDiagFilter 247 { 248 public: 249 // 'tors 250 CDiagFilter(void); 251 ~CDiagFilter(void); 252 253 /// Check if the filter accepts message. 254 /// In addition check an exception and all its backlog if specified. 255 EDiagFilterAction Check(const CNcbiDiag& msg, const CException* ex = NULL) const; 256 257 /// Fill the filter from a string 258 void Fill(const char* filter_string); 259 260 /// Print state 261 void Print(ostream& out) const; 262 GetFilterStr(void) const263 const string& GetFilterStr(void) const { return m_Filter; } 264 265 void Append(const char* filter_string); 266 267 private: 268 /// Check if the filter accepts errcode 269 EDiagFilterAction x_CheckErrCode(int code, int subcode, EDiagSev sev) const; 270 271 /// Check if the filter accepts path 272 EDiagFilterAction x_CheckFile(const char* file, EDiagSev sev) const; 273 274 // Check if the filter accepts the location 275 EDiagFilterAction x_CheckLocation(const char* module, 276 const char* nclass, 277 const char* function, 278 EDiagSev sev) const; 279 280 // CSyntaxParser can insert CDiagStrMatcher and clean 281 friend class CDiagSyntaxParser; 282 283 // Insert a new matcher into the end of list 284 // Take ownership of the matcher InsertMatcher(CDiagMatcher * matcher)285 void InsertMatcher(CDiagMatcher *matcher) 286 { 287 m_Matchers.push_back(matcher); 288 } 289 290 // Negative matchers should be processed first 291 // because they are *AND NOT* matchers, not just *NOT*. InsertNegativeMatcher(CDiagMatcher * matcher)292 void InsertNegativeMatcher(CDiagMatcher *matcher) 293 { 294 m_Matchers.push_front(matcher); 295 ++m_NotMatchersNum; 296 } 297 298 // Remove and destroy all matchers, if any 299 void Clean(void); 300 301 private: 302 typedef deque< AutoPtr<CDiagMatcher> > TMatchers; 303 string m_Filter; 304 TMatchers m_Matchers; 305 size_t m_NotMatchersNum; 306 }; 307 308 309 310 ///////////////////////////////////////////////////////////////////////////// 311 /// 312 /// CDiagLexParser -- 313 /// 314 /// Lexical parser 315 /// 316 317 class CDiagLexParser 318 { 319 public: 320 // Symbols 321 enum ESymbol { 322 eDone, // to mark that symbol was processed 323 eExpl, // ! processed 324 ePath, // path started with / 325 eId, // id and ? 326 eDoubleColon, // :: 327 ePars, // () 328 eBrackets, // [] 329 eErrCode, // (code.subcode) 330 eEnd // end of stream 331 }; 332 333 // Constructor 334 CDiagLexParser(); 335 336 // Takes next lexical symbol from the stream 337 ESymbol Parse(istream& in); 338 339 // Returns id or ? string when eId is returned from parse() GetId() const340 const string& GetId() const { return m_Str; } 341 342 // Returns current position GetPos() const343 int GetPos() const { return m_Pos; } 344 345 private: 346 string m_Str; 347 int m_Pos; 348 }; 349 350 351 352 ///////////////////////////////////////////////////////////////////////////// 353 /// 354 /// CDiagSyntaxParser -- 355 /// 356 /// Parses string and fills CDiagFilter with CDiagStrMatchers 357 /// 358 359 class CDiagSyntaxParser 360 { 361 public: 362 // Error info type 363 typedef pair<const char*, int> TErrorInfo; 364 365 // Constructor 366 CDiagSyntaxParser(); 367 368 // Parses stream and fills CDiagFilter to with CDiagStrMatchers 369 void Parse(istream& in, CDiagFilter& to); 370 371 private: 372 enum EInto { 373 eModule, 374 eFunction 375 }; 376 377 // Puts CDiagMessageMatcher into CDiagFilter 378 void x_PutIntoFilter(CDiagFilter& to, EInto into); 379 380 // Creates a CDiagStrMatcher by string 381 static CDiagStrMatcher* x_CreateMatcher(const string& str); 382 383 /// "Info", "Warning", etc converted to enum value 384 /// Throws an excpetion if incorrect value passed 385 EDiagSev x_GetDiagSeverity(const string& sev_str); 386 387 private: 388 typedef vector< AutoPtr<CDiagStrMatcher> > TMatchers; 389 TMatchers m_Matchers; 390 AutoPtr<CDiagStrErrCodeMatcher> m_ErrCodeMatcher; 391 AutoPtr<CDiagStrMatcher> m_FileMatcher; 392 int m_Pos; 393 bool m_Negative; 394 EDiagSev m_DiagSev; 395 }; 396 397 398 END_NCBI_SCOPE 399 400 #endif /* CORELIB___NCBIDIAG_P__HPP */ 401