regExp.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 | Copyright (C) 2011-2015 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "regExp.H"
27 #include "string.H"
28 #include "List.H"
29 
30 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
31 
32 template<class StringType>
33 bool Foam::regExp::matchGrouping
34 (
35  const std::string& str,
36  List<StringType>& groups
37 ) const
38 {
39  if (preg_ && str.size())
40  {
41  size_t nmatch = ngroups() + 1;
42  regmatch_t pmatch[nmatch];
43 
44  // Also verify that the entire string was matched.
45  // pmatch[0] is the entire match
46  // pmatch[1..] are the (...) sub-groups
47  if
48  (
49  regexec(preg_, str.c_str(), nmatch, pmatch, 0) == 0
50  && (pmatch[0].rm_so == 0 && pmatch[0].rm_eo == label(str.size()))
51  )
52  {
53  groups.setSize(ngroups());
54  label groupI = 0;
55 
56  for (size_t matchI = 1; matchI < nmatch; matchI++)
57  {
58  if (pmatch[matchI].rm_so != -1 && pmatch[matchI].rm_eo != -1)
59  {
60  groups[groupI] = str.substr
61  (
62  pmatch[matchI].rm_so,
63  pmatch[matchI].rm_eo - pmatch[matchI].rm_so
64  );
65  }
66  else
67  {
68  groups[groupI].clear();
69  }
70  groupI++;
71  }
72 
73  return true;
74  }
75  }
76 
77  groups.clear();
78  return false;
79 }
80 
81 
82 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
83 
85 :
86  preg_(0)
87 {}
88 
89 
90 Foam::regExp::regExp(const char* pattern, const bool ignoreCase)
91 :
92  preg_(0)
93 {
94  set(pattern, ignoreCase);
95 }
96 
97 
98 Foam::regExp::regExp(const std::string& pattern, const bool ignoreCase)
99 :
100  preg_(0)
101 {
102  set(pattern.c_str(), ignoreCase);
103 }
104 
105 
106 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
107 
109 {
110  clear();
111 }
112 
113 
114 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
115 
116 void Foam::regExp::set(const char* pattern, const bool ignoreCase) const
117 {
118  clear();
119 
120  // Avoid NULL pointer and zero-length patterns
121  if (pattern && *pattern)
122  {
123  int cflags = REG_EXTENDED;
124  if (ignoreCase)
125  {
126  cflags |= REG_ICASE;
127  }
128 
129  const char* pat = pattern;
130 
131  // Check for embedded prefix for ignore-case
132  // this is the only embedded prefix we support
133  // - a simple check is sufficient
134  if (!strncmp(pattern, "(?i)", 4))
135  {
136  cflags |= REG_ICASE;
137  pat += 4;
138 
139  // avoid zero-length patterns
140  if (!*pat)
141  {
142  return;
143  }
144  }
145 
146  preg_ = new regex_t;
147  int err = regcomp(preg_, pat, cflags);
148 
149  if (err != 0)
150  {
151  char errbuf[200];
152  regerror(err, preg_, errbuf, sizeof(errbuf));
153 
155  (
156  "regExp::set(const char*, const bool ignoreCase)"
157  ) << "Failed to compile regular expression '" << pattern << "'"
158  << nl << errbuf
159  << exit(FatalError);
160  }
161  }
162 }
163 
164 
165 void Foam::regExp::set(const std::string& pattern, const bool ignoreCase) const
166 {
167  return set(pattern.c_str(), ignoreCase);
168 }
169 
170 
172 {
173  if (preg_)
174  {
175  regfree(preg_);
176  delete preg_;
177  preg_ = 0;
178 
179  return true;
180  }
181 
182  return false;
183 }
184 
185 
186 std::string::size_type Foam::regExp::find(const std::string& str) const
187 {
188  if (preg_ && str.size())
189  {
190  size_t nmatch = 1;
191  regmatch_t pmatch[1];
192 
193  if (regexec(preg_, str.c_str(), nmatch, pmatch, 0) == 0)
194  {
195  return pmatch[0].rm_so;
196  }
197  }
198 
199  return string::npos;
200 }
201 
202 
203 bool Foam::regExp::match(const std::string& str) const
204 {
205  if (preg_ && str.size())
206  {
207  size_t nmatch = 1;
208  regmatch_t pmatch[1];
209 
210  // Also verify that the entire string was matched
211  // pmatch[0] is the entire match
212  if
213  (
214  regexec(preg_, str.c_str(), nmatch, pmatch, 0) == 0
215  && (pmatch[0].rm_so == 0 && pmatch[0].rm_eo == label(str.size()))
216  )
217  {
218  return true;
219  }
220  }
221 
222  return false;
223 }
224 
225 
227 (
228  const std::string& str,
229  List<std::string>& groups
230 ) const
231 {
232  return matchGrouping(str, groups);
233 }
234 
235 
237 (
238  const std::string& str,
239  List<Foam::string>& groups
240 ) const
241 {
242  return matchGrouping(str, groups);
243 }
244 
245 
246 // * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
247 
248 void Foam::regExp::operator=(const char* pat)
249 {
250  set(pat);
251 }
252 
253 
254 void Foam::regExp::operator=(const std::string& pat)
255 {
256  set(pat);
257 }
258 
259 
260 // ************************************************************************* //
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
bool match(const std::string &) const
Return true if it matches the entire string.
Definition: regExp.C:203
int ngroups() const
Return the number of (groups)
Definition: regExp.H:143
graph_traits< Graph >::vertices_size_type size_type
Definition: SloanRenumber.C:73
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
static const char nl
Definition: Ostream.H:260
void set(const char *, const bool ignoreCase=false) const
Compile pattern into a regular expression,.
Definition: regExp.C:116
std::string::size_type find(const std::string &str) const
Find position within string.
Definition: regExp.C:186
#define FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
Definition: error.H:314
~regExp()
Destructor.
Definition: regExp.C:108
error FatalError
bool clear() const
Release precompiled expression.
Definition: regExp.C:171
regExp()
Construct null.
Definition: regExp.C:84