regExpPosix.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) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2018 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "regExpPosix.H"
30 #include "SubStrings.H"
31 #include "error.H"
32 
33 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34 
36 
37 
38 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
39 
40 namespace
41 {
42 
43 // Verify that the entire len was matched
44 static inline bool fullMatch(const regmatch_t& m, const regoff_t len)
45 {
46  return (m.rm_so == 0 && m.rm_eo == len);
47 }
48 
49 } // End anonymous namespace
50 
51 
52 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
53 
55 {
56  if (preg_)
57  {
58  regfree(preg_);
59  delete preg_;
60  preg_ = nullptr;
61 
62  return true;
63  }
64 
65  return false;
66 }
67 
68 
69 bool Foam::regExpPosix::set(const char* pattern, bool ignoreCase)
70 {
71  clear();
72 
73  // Avoid nullptr and zero-length patterns
74  if (pattern && *pattern)
75  {
76  int cflags = REG_EXTENDED;
77  if (ignoreCase)
78  {
79  cflags |= REG_ICASE;
80  }
81 
82  const char* pat = pattern;
83 
84  // Check for embedded prefix for ignore-case
85  // this is the only embedded prefix we support
86  // - a simple check is sufficient
87  if (!strncmp(pattern, "(?i)", 4))
88  {
89  cflags |= REG_ICASE;
90  pat += 4;
91 
92  // avoid zero-length patterns
93  if (!*pat)
94  {
95  return false;
96  }
97  }
98 
99  preg_ = new regex_t;
100  int err = regcomp(preg_, pat, cflags);
101 
102  if (err != 0)
103  {
104  char errbuf[200];
105  regerror(err, preg_, errbuf, sizeof(errbuf));
106 
108  << "Failed to compile regular expression '" << pattern << "'"
109  << nl << errbuf
110  << exit(FatalError);
111  }
112 
113  return true;
114  }
115 
116  return false; // Was cleared and nothing was set
117 }
118 
119 
120 bool Foam::regExpPosix::set(const std::string& pattern, bool ignoreCase)
121 {
122  return set(pattern.c_str(), ignoreCase);
123 }
124 
125 
126 std::string::size_type Foam::regExpPosix::find(const std::string& text) const
127 {
128  if (preg_ && !text.empty())
129  {
130  const size_t nmatch = 1;
131  regmatch_t pmatch[1];
132 
133  if (regexec(preg_, text.c_str(), nmatch, pmatch, 0) == 0)
134  {
135  return pmatch[0].rm_so;
136  }
137  }
138 
139  return std::string::npos;
140 }
141 
142 
143 bool Foam::regExpPosix::match(const std::string& text) const
144 {
145  const auto len = text.size();
146 
147  if (preg_ && len)
148  {
149  const size_t nmatch = 1;
150  regmatch_t pmatch[1];
151 
152  // Verify that the entire string was matched
153  // - [0] is the entire match result
154  return
155  (
156  regexec(preg_, text.c_str(), nmatch, pmatch, 0) == 0
157  && fullMatch(pmatch[0], len)
158  );
159  }
160 
161  return false;
162 }
163 
164 
166 (
167  const std::string& text,
168  SubStrings<std::string>& matches
169 ) const
170 {
171  matches.clear();
172 
173  const auto len = text.size();
174  if (preg_ && len)
175  {
176  const size_t nmatch = ngroups() + 1;
177  regmatch_t pmatch[nmatch];
178 
179  // Verify that the entire string was matched
180  // - [0] is the entire match result
181  // - [1..] are the match groups (1..)
182  if
183  (
184  regexec(preg_, text.c_str(), nmatch, pmatch, 0) != 0
185  || !fullMatch(pmatch[0], len)
186  )
187  {
188  return false;
189  }
190 
191  matches.reserve(nmatch);
192 
193  for (size_t matchi = 0; matchi < nmatch; ++matchi)
194  {
195  const auto& mat = pmatch[matchi];
196 
197  if (mat.rm_so != -1 && mat.rm_eo != -1)
198  {
199  matches.append
200  (
201  text.cbegin() + mat.rm_so,
202  text.cbegin() + mat.rm_eo
203  );
204  }
205  else
206  {
207  // This may be misleading...
208  matches.append(text.cbegin(), text.cbegin());
209  }
210  }
211 
212  return true;
213  }
214 
215  return false;
216 }
217 
218 
219 // ************************************************************************* //
Foam::BitOps::set
void set(List< bool > &bools, const labelRange &range)
Set the specified range 'on' in a boolList.
Definition: BitOps.C:37
Foam::regExpPosix::find
std::string::size_type find(const std::string &text) const
Find position within the text.
Definition: regExpPosix.C:126
Foam::SubStrings
Sub-ranges of a string with a structure similar to std::match_results, but without the underlying reg...
Definition: CStringList.H:63
regExpPosix.H
error.H
size_type
graph_traits< Graph >::vertices_size_type size_type
Definition: SloanRenumber.C:76
Foam::FatalError
error FatalError
Foam::regExpPosix::set
bool set(const char *pattern, bool ignoreCase=false)
Compile pattern into a regular expression, optionally ignore case.
Definition: regExpPosix.C:69
Foam::regExpPosix::grammar
static int grammar
Grammar (unused) - for compatibility with Foam::regExpCxx.
Definition: regExpPosix.H:93
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:381
SubStrings.H
clear
patchWriters clear()
Foam::nl
constexpr char nl
Definition: Ostream.H:385
Foam::regExpPosix::match
bool match(const std::string &text) const
True if the regex matches the entire text.
Definition: regExpPosix.C:143
Foam::SubStrings::append
void append(const typename String::const_iterator &b, const typename String::const_iterator &e)
Append sub-string defined by begin/end iterators.
Definition: SubStrings.H:92
Foam::regExpPosix::clear
bool clear()
Clear expression.
Definition: regExpPosix.C:54