]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/tools/lldb/source/Core/RegularExpression.cpp
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / llvm / tools / lldb / source / Core / RegularExpression.cpp
1 //===-- RegularExpression.cpp -----------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "lldb/Core/RegularExpression.h"
11 #include "llvm/ADT/StringRef.h"
12 #include <string.h>
13
14 using namespace lldb_private;
15
16 //----------------------------------------------------------------------
17 // Default constructor
18 //----------------------------------------------------------------------
19 RegularExpression::RegularExpression() :
20     m_re(),
21     m_comp_err (1),
22     m_preg(),
23     m_compile_flags(REG_EXTENDED)
24 {
25     memset(&m_preg,0,sizeof(m_preg));
26 }
27
28 //----------------------------------------------------------------------
29 // Constructor that compiles "re" using "flags" and stores the
30 // resulting compiled regular expression into this object.
31 //----------------------------------------------------------------------
32 RegularExpression::RegularExpression(const char* re, int flags) :
33     m_re(),
34     m_comp_err (1),
35     m_preg(),
36     m_compile_flags(flags)
37 {
38     memset(&m_preg,0,sizeof(m_preg));
39     Compile(re);
40 }
41
42 //----------------------------------------------------------------------
43 // Constructor that compiles "re" using "flags" and stores the
44 // resulting compiled regular expression into this object.
45 //----------------------------------------------------------------------
46 RegularExpression::RegularExpression(const char* re) :
47     m_re(),
48     m_comp_err (1),
49     m_preg(),
50     m_compile_flags(REG_EXTENDED)
51 {
52     memset(&m_preg,0,sizeof(m_preg));
53     Compile(re);
54 }
55
56 RegularExpression::RegularExpression(const RegularExpression &rhs)
57 {
58     memset(&m_preg,0,sizeof(m_preg));
59     Compile(rhs.GetText(), rhs.GetCompileFlags());
60 }
61
62 const RegularExpression &
63 RegularExpression::operator= (const RegularExpression &rhs)
64 {
65     if (&rhs != this)
66     {
67         Compile (rhs.GetText(), rhs.GetCompileFlags());
68     }
69     return *this;
70 }
71 //----------------------------------------------------------------------
72 // Destructor
73 //
74 // Any previosuly compiled regular expression contained in this
75 // object will be freed.
76 //----------------------------------------------------------------------
77 RegularExpression::~RegularExpression()
78 {
79     Free();
80 }
81
82 //----------------------------------------------------------------------
83 // Compile a regular expression using the supplied regular
84 // expression text and flags. The compied regular expression lives
85 // in this object so that it can be readily used for regular
86 // expression matches. Execute() can be called after the regular
87 // expression is compiled. Any previosuly compiled regular
88 // expression contained in this object will be freed.
89 //
90 // RETURNS
91 //  True of the refular expression compiles successfully, false
92 //  otherwise.
93 //----------------------------------------------------------------------
94 bool
95 RegularExpression::Compile(const char* re)
96 {
97     return Compile (re, m_compile_flags);
98 }
99
100 bool
101 RegularExpression::Compile(const char* re, int flags)
102 {
103     Free();
104     m_compile_flags = flags;
105     
106     if (re && re[0])
107     {
108         m_re = re;
109         m_comp_err = ::regcomp (&m_preg, re, flags);
110     }
111     else
112     {
113         // No valid regular expression
114         m_comp_err = 1;
115     }
116
117     return m_comp_err == 0;
118 }
119
120 //----------------------------------------------------------------------
121 // Execute a regular expression match using the compiled regular
122 // expression that is already in this object against the match
123 // string "s". If any parens are used for regular expression
124 // matches "match_count" should indicate the number of regmatch_t
125 // values that are present in "match_ptr". The regular expression
126 // will be executed using the "execute_flags".
127 //---------------------------------------------------------------------
128 bool
129 RegularExpression::Execute(const char* s, Match *match, int execute_flags) const
130 {
131     int err = 1;
132     if (s != NULL && m_comp_err == 0)
133     {
134         if (match)
135         {
136             err = ::regexec (&m_preg,
137                              s,
138                              match->GetSize(),
139                              match->GetData(),
140                              execute_flags);
141         }
142         else
143         {
144             err = ::regexec (&m_preg,
145                              s,
146                              0,
147                              NULL,
148                              execute_flags);
149         }
150     }
151     
152     if (err != 0)
153     {
154         // The regular expression didn't compile, so clear the matches
155         if (match)
156             match->Clear();
157         return false;
158     }
159     return true;
160 }
161
162 bool
163 RegularExpression::Match::GetMatchAtIndex (const char* s, uint32_t idx, std::string& match_str) const
164 {
165     if (idx < m_matches.size())
166     {
167         if (m_matches[idx].rm_eo == m_matches[idx].rm_so)
168         {
169             // Matched the empty string...
170             match_str.clear();
171             return true;
172         }
173         else if (m_matches[idx].rm_eo > m_matches[idx].rm_so)
174         {
175             match_str.assign (s + m_matches[idx].rm_so,
176                               m_matches[idx].rm_eo - m_matches[idx].rm_so);
177             return true;
178         }
179     }
180     return false;
181 }
182
183 bool
184 RegularExpression::Match::GetMatchAtIndex (const char* s, uint32_t idx, llvm::StringRef& match_str) const
185 {
186     if (idx < m_matches.size())
187     {
188         if (m_matches[idx].rm_eo == m_matches[idx].rm_so)
189         {
190             // Matched the empty string...
191             match_str = llvm::StringRef();
192             return true;
193         }
194         else if (m_matches[idx].rm_eo > m_matches[idx].rm_so)
195         {
196             match_str = llvm::StringRef (s + m_matches[idx].rm_so, m_matches[idx].rm_eo - m_matches[idx].rm_so);
197             return true;
198         }
199     }
200     return false;
201 }
202
203 bool
204 RegularExpression::Match::GetMatchSpanningIndices (const char* s, uint32_t idx1, uint32_t idx2, llvm::StringRef& match_str) const
205 {
206     if (idx1 < m_matches.size() && idx2 < m_matches.size())
207     {
208         if (m_matches[idx1].rm_so == m_matches[idx2].rm_eo)
209         {
210             // Matched the empty string...
211             match_str = llvm::StringRef();
212             return true;
213         }
214         else if (m_matches[idx1].rm_so < m_matches[idx2].rm_eo)
215         {
216             match_str = llvm::StringRef (s + m_matches[idx1].rm_so, m_matches[idx2].rm_eo - m_matches[idx1].rm_so);
217             return true;
218         }
219     }
220     return false;
221 }
222
223
224 //----------------------------------------------------------------------
225 // Returns true if the regular expression compiled and is ready
226 // for execution.
227 //----------------------------------------------------------------------
228 bool
229 RegularExpression::IsValid () const
230 {
231     return m_comp_err == 0;
232 }
233
234 //----------------------------------------------------------------------
235 // Returns the text that was used to compile the current regular
236 // expression.
237 //----------------------------------------------------------------------
238 const char*
239 RegularExpression::GetText () const
240 {
241     if (m_re.empty())
242         return NULL;
243     return m_re.c_str();
244 }
245
246 //----------------------------------------------------------------------
247 // Free any contained compiled regular expressions.
248 //----------------------------------------------------------------------
249 void
250 RegularExpression::Free()
251 {
252     if (m_comp_err == 0)
253     {
254         m_re.clear();
255         regfree(&m_preg);
256         // Set a compile error since we no longer have a valid regex
257         m_comp_err = 1;
258     }
259 }
260
261 size_t
262 RegularExpression::GetErrorAsCString (char *err_str, size_t err_str_max_len) const
263 {
264     if (m_comp_err == 0)
265     {
266         if (err_str && err_str_max_len) 
267             *err_str = '\0';
268         return 0;
269     }
270     
271     return ::regerror (m_comp_err, &m_preg, err_str, err_str_max_len);
272 }
273
274 bool
275 RegularExpression::operator < (const RegularExpression& rhs) const
276 {
277     return (m_re < rhs.m_re);
278 }
279