regExpCxx.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2017-2021 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "regExpCxx.H"
29 #include "debug.H"
30 #include "error.H"
31 
32 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
33 
35 
36 
37 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
38 
39 namespace
40 {
41 
42 static std::string error_string(const std::regex_error& err)
43 {
44  switch (err.code())
45  {
46  case std::regex_constants::error_collate :
47  return "invalid collating element name";
48  break;
49 
50  case std::regex_constants::error_ctype :
51  return "invalid character class name";
52  break;
53 
54  case std::regex_constants::error_escape :
55  return "invalid escaped character or a trailing escape";
56  break;
57 
58  case std::regex_constants::error_backref :
59  return "invalid back reference";
60  break;
61 
62  case std::regex_constants::error_brack :
63  return "mismatched [ and ]";
64  break;
65 
66  case std::regex_constants::error_paren :
67  return "mismatched ( and )";
68  break;
69 
70  case std::regex_constants::error_brace :
71  return "mismatched { and }";
72  break;
73 
74  case std::regex_constants::error_badbrace :
75  return "invalid range in a {..}";
76  break;
77 
78  case std::regex_constants::error_range :
79  return "invalid [..] character range";
80  break;
81 
82  case std::regex_constants::error_space :
83  return "memory error";
84  break;
85 
86  case std::regex_constants::error_badrepeat :
87  return "bad '*?+{' repeat";
88  break;
89 
90  case std::regex_constants::error_complexity :
91  return "expression too complex";
92  break;
93 
94  case std::regex_constants::error_stack :
95  return "memory stack error";
96  break;
97 
98  default:
99  break;
100 
101  }
102 
103  return "";
104 }
105 
106 } // End anonymous namespace
107 
108 
109 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
110 
111 bool Foam::regExpCxx::set_pattern
112 (
113  const char* pattern,
114  size_t len,
115  bool ignoreCase
116 )
117 {
118  clear(); // Also sets ctrl_ = 0
119 
120  const char* pat = pattern;
121  bool doNegate = false;
122 
123  // Handle known embedded prefixes
124  if (len > 2 && pat[0] == '(' && pat[1] == '?')
125  {
126  pat += 2;
127  len -= 2;
128 
129  for (bool done = false; !done && len; ++pat, --len)
130  {
131  switch (*pat)
132  {
133  case '!':
134  {
135  // Negated (inverted) match
136  doNegate = true;
137  break;
138  }
139  case 'i':
140  {
141  // Ignore-case
142  ignoreCase = true;
143  break;
144  }
145  case ')':
146  {
147  // End of prefix parsing
148  done = true;
149  break;
150  }
151  }
152  }
153  }
154 
155  // Avoid zero-length patterns
156  if (len)
157  {
158  std::regex::flag_type flags = syntax();
159  if (ignoreCase)
160  {
161  flags |= std::regex::icase;
162  }
163 
164  try
165  {
166  re_.assign(pat, len, flags);
167  ctrl_ = (doNegate ? ctrlType::NEGATED : ctrlType::NORMAL);
168  return true;
169  }
170  catch (const std::regex_error& err)
171  {
173  << "Failed to compile regular expression '"
174  << pattern << "'" << nl
175  << err.what() << ": " << error_string(err).c_str() << nl
176  << exit(FatalError);
177  }
178  }
179 
180  return false;
181 }
182 
183 
184 // ************************************************************************* //
regExpCxx.H
debug.H
error.H
Foam::debug::optimisationSwitch
int optimisationSwitch(const char *name, const int deflt=0)
Lookup optimisation switch or add default value.
Definition: debug.C:237
Foam::FatalError
error FatalError
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::regExpCxx::clear
bool clear()
Clear expression.
Definition: regExpCxxI.H:184
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::regExpCxx::grammar
static int grammar
The default grammar (extended | ECMAScript).
Definition: regExpCxx.H:120