FreeFOAM The Cross-Platform CFD Toolkit
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) 1991-2010 OpenCFD Ltd.
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 <sys/types.h>
27 
28 #include "regExp.H"
29 #include <OpenFOAM/label.H>
30 #include <OpenFOAM/string.H>
31 #include <OpenFOAM/List.H>
32 #include <OpenFOAM/IOstreams.H>
33 
34 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
35 
37 :
38  preg_(0)
39 {}
40 
41 
42 Foam::regExp::regExp(const char* pattern, const bool ignoreCase)
43 :
44  preg_(0)
45 {
46  set(pattern, ignoreCase);
47 }
48 
49 
50 Foam::regExp::regExp(const std::string& pattern, const bool ignoreCase)
51 :
52  preg_(0)
53 {
54  set(pattern.c_str(), ignoreCase);
55 }
56 
57 
58 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
59 
61 {
62  clear();
63 }
64 
65 
66 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
67 
68 void Foam::regExp::set(const char* pattern, const bool ignoreCase) const
69 {
70  clear();
71 
72  // avoid NULL pointer and zero-length patterns
73  if (pattern && *pattern)
74  {
75  preg_ = new regex_t;
76 
77  int cflags = REG_EXTENDED;
78  if (ignoreCase)
79  {
80  cflags |= REG_ICASE;
81  }
82 
83  if (regcomp(preg_, pattern, cflags) != 0)
84  {
86  (
87  "regExp::set(const char*)"
88  ) << "Failed to compile regular expression '" << pattern << "'"
89  << exit(FatalError);
90  }
91  }
92 }
93 
94 
95 void Foam::regExp::set(const std::string& pattern, const bool ignoreCase) const
96 {
97  return set(pattern.c_str(), ignoreCase);
98 }
99 
100 
102 {
103  if (preg_)
104  {
105  regfree(preg_);
106  delete preg_;
107  preg_ = 0;
108 
109  return true;
110  }
111 
112  return false;
113 }
114 
115 
116 std::string::size_type Foam::regExp::find(const std::string& str) const
117 {
118  if (preg_ && str.size())
119  {
120  size_t nmatch = 1;
121  regmatch_t pmatch[1];
122 
123  if (regexec(preg_, str.c_str(), nmatch, pmatch, 0) == 0)
124  {
125  return pmatch[0].rm_so;
126  }
127  }
128 
129  return string::npos;
130 }
131 
132 
133 bool Foam::regExp::match(const std::string& str) const
134 {
135  if (preg_ && str.size())
136  {
137  size_t nmatch = 1;
138  regmatch_t pmatch[1];
139 
140  // also verify that the entire string was matched
141  // pmatch[0] is the entire match
142  if
143  (
144  regexec(preg_, str.c_str(), nmatch, pmatch, 0) == 0
145  && (pmatch[0].rm_so == 0 && pmatch[0].rm_eo == label(str.size()))
146  )
147  {
148  return true;
149  }
150  }
151 
152  return false;
153 }
154 
155 
156 bool Foam::regExp::match(const string& str, List<string>& groups) const
157 {
158  if (preg_ && str.size())
159  {
160  size_t nmatch = ngroups() + 1;
161  regmatch_t pmatch[nmatch];
162 
163  // also verify that the entire string was matched
164  // pmatch[0] is the entire match
165  // pmatch[1..] are the (...) sub-groups
166  if
167  (
168  regexec(preg_, str.c_str(), nmatch, pmatch, 0) == 0
169  && (pmatch[0].rm_so == 0 && pmatch[0].rm_eo == label(str.size()))
170  )
171  {
172  groups.setSize(ngroups());
173  label groupI = 0;
174 
175  for (size_t matchI = 1; matchI < nmatch; matchI++)
176  {
177  if (pmatch[matchI].rm_so != -1 && pmatch[matchI].rm_eo != -1)
178  {
179  groups[groupI] = str.substr
180  (
181  pmatch[matchI].rm_so,
182  pmatch[matchI].rm_eo - pmatch[matchI].rm_so
183  );
184  }
185  else
186  {
187  groups[groupI].clear();
188  }
189  groupI++;
190  }
191 
192  return true;
193  }
194  }
195 
196  groups.clear();
197  return false;
198 }
199 
200 
201 // * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
202 
203 void Foam::regExp::operator=(const char* pat)
204 {
205  set(pat);
206 }
207 
208 
209 void Foam::regExp::operator=(const std::string& pat)
210 {
211  set(pat);
212 }
213 
214 
215 // ************************ vim: set sw=4 sts=4 et: ************************ //