1254721Semaste//===-- RegularExpression.cpp -----------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "lldb/Core/RegularExpression.h"
11254721Semaste#include "llvm/ADT/StringRef.h"
12254721Semaste#include <string.h>
13254721Semaste
14254721Semasteusing namespace lldb_private;
15254721Semaste
16254721Semaste//----------------------------------------------------------------------
17254721Semaste// Default constructor
18254721Semaste//----------------------------------------------------------------------
19254721SemasteRegularExpression::RegularExpression() :
20254721Semaste    m_re(),
21254721Semaste    m_comp_err (1),
22254721Semaste    m_preg(),
23254721Semaste    m_compile_flags(REG_EXTENDED)
24254721Semaste{
25254721Semaste    memset(&m_preg,0,sizeof(m_preg));
26254721Semaste}
27254721Semaste
28254721Semaste//----------------------------------------------------------------------
29254721Semaste// Constructor that compiles "re" using "flags" and stores the
30254721Semaste// resulting compiled regular expression into this object.
31254721Semaste//----------------------------------------------------------------------
32254721SemasteRegularExpression::RegularExpression(const char* re, int flags) :
33254721Semaste    m_re(),
34254721Semaste    m_comp_err (1),
35254721Semaste    m_preg(),
36254721Semaste    m_compile_flags(flags)
37254721Semaste{
38254721Semaste    memset(&m_preg,0,sizeof(m_preg));
39254721Semaste    Compile(re);
40254721Semaste}
41254721Semaste
42254721Semaste//----------------------------------------------------------------------
43254721Semaste// Constructor that compiles "re" using "flags" and stores the
44254721Semaste// resulting compiled regular expression into this object.
45254721Semaste//----------------------------------------------------------------------
46254721SemasteRegularExpression::RegularExpression(const char* re) :
47254721Semaste    m_re(),
48254721Semaste    m_comp_err (1),
49254721Semaste    m_preg(),
50254721Semaste    m_compile_flags(REG_EXTENDED)
51254721Semaste{
52254721Semaste    memset(&m_preg,0,sizeof(m_preg));
53254721Semaste    Compile(re);
54254721Semaste}
55254721Semaste
56254721SemasteRegularExpression::RegularExpression(const RegularExpression &rhs)
57254721Semaste{
58254721Semaste    memset(&m_preg,0,sizeof(m_preg));
59254721Semaste    Compile(rhs.GetText(), rhs.GetCompileFlags());
60254721Semaste}
61254721Semaste
62254721Semasteconst RegularExpression &
63254721SemasteRegularExpression::operator= (const RegularExpression &rhs)
64254721Semaste{
65254721Semaste    if (&rhs != this)
66254721Semaste    {
67254721Semaste        Compile (rhs.GetText(), rhs.GetCompileFlags());
68254721Semaste    }
69254721Semaste    return *this;
70254721Semaste}
71254721Semaste//----------------------------------------------------------------------
72254721Semaste// Destructor
73254721Semaste//
74254721Semaste// Any previosuly compiled regular expression contained in this
75254721Semaste// object will be freed.
76254721Semaste//----------------------------------------------------------------------
77254721SemasteRegularExpression::~RegularExpression()
78254721Semaste{
79254721Semaste    Free();
80254721Semaste}
81254721Semaste
82254721Semaste//----------------------------------------------------------------------
83254721Semaste// Compile a regular expression using the supplied regular
84254721Semaste// expression text and flags. The compied regular expression lives
85254721Semaste// in this object so that it can be readily used for regular
86254721Semaste// expression matches. Execute() can be called after the regular
87254721Semaste// expression is compiled. Any previosuly compiled regular
88254721Semaste// expression contained in this object will be freed.
89254721Semaste//
90254721Semaste// RETURNS
91254721Semaste//  True of the refular expression compiles successfully, false
92254721Semaste//  otherwise.
93254721Semaste//----------------------------------------------------------------------
94254721Semastebool
95254721SemasteRegularExpression::Compile(const char* re)
96254721Semaste{
97254721Semaste    return Compile (re, m_compile_flags);
98254721Semaste}
99254721Semaste
100254721Semastebool
101254721SemasteRegularExpression::Compile(const char* re, int flags)
102254721Semaste{
103254721Semaste    Free();
104254721Semaste    m_compile_flags = flags;
105254721Semaste
106254721Semaste    if (re && re[0])
107254721Semaste    {
108254721Semaste        m_re = re;
109254721Semaste        m_comp_err = ::regcomp (&m_preg, re, flags);
110254721Semaste    }
111254721Semaste    else
112254721Semaste    {
113254721Semaste        // No valid regular expression
114254721Semaste        m_comp_err = 1;
115254721Semaste    }
116254721Semaste
117254721Semaste    return m_comp_err == 0;
118254721Semaste}
119254721Semaste
120254721Semaste//----------------------------------------------------------------------
121254721Semaste// Execute a regular expression match using the compiled regular
122254721Semaste// expression that is already in this object against the match
123254721Semaste// string "s". If any parens are used for regular expression
124254721Semaste// matches "match_count" should indicate the number of regmatch_t
125254721Semaste// values that are present in "match_ptr". The regular expression
126254721Semaste// will be executed using the "execute_flags".
127254721Semaste//---------------------------------------------------------------------
128254721Semastebool
129254721SemasteRegularExpression::Execute(const char* s, Match *match, int execute_flags) const
130254721Semaste{
131254721Semaste    int err = 1;
132254721Semaste    if (s != NULL && m_comp_err == 0)
133254721Semaste    {
134254721Semaste        if (match)
135254721Semaste        {
136254721Semaste            err = ::regexec (&m_preg,
137254721Semaste                             s,
138254721Semaste                             match->GetSize(),
139254721Semaste                             match->GetData(),
140254721Semaste                             execute_flags);
141254721Semaste        }
142254721Semaste        else
143254721Semaste        {
144254721Semaste            err = ::regexec (&m_preg,
145254721Semaste                             s,
146254721Semaste                             0,
147254721Semaste                             NULL,
148254721Semaste                             execute_flags);
149254721Semaste        }
150254721Semaste    }
151254721Semaste
152254721Semaste    if (err != 0)
153254721Semaste    {
154254721Semaste        // The regular expression didn't compile, so clear the matches
155254721Semaste        if (match)
156254721Semaste            match->Clear();
157254721Semaste        return false;
158254721Semaste    }
159254721Semaste    return true;
160254721Semaste}
161254721Semaste
162254721Semastebool
163254721SemasteRegularExpression::Match::GetMatchAtIndex (const char* s, uint32_t idx, std::string& match_str) const
164254721Semaste{
165254721Semaste    if (idx < m_matches.size())
166254721Semaste    {
167254721Semaste        if (m_matches[idx].rm_eo == m_matches[idx].rm_so)
168254721Semaste        {
169254721Semaste            // Matched the empty string...
170254721Semaste            match_str.clear();
171254721Semaste            return true;
172254721Semaste        }
173254721Semaste        else if (m_matches[idx].rm_eo > m_matches[idx].rm_so)
174254721Semaste        {
175254721Semaste            match_str.assign (s + m_matches[idx].rm_so,
176254721Semaste                              m_matches[idx].rm_eo - m_matches[idx].rm_so);
177254721Semaste            return true;
178254721Semaste        }
179254721Semaste    }
180254721Semaste    return false;
181254721Semaste}
182254721Semaste
183254721Semastebool
184254721SemasteRegularExpression::Match::GetMatchAtIndex (const char* s, uint32_t idx, llvm::StringRef& match_str) const
185254721Semaste{
186254721Semaste    if (idx < m_matches.size())
187254721Semaste    {
188254721Semaste        if (m_matches[idx].rm_eo == m_matches[idx].rm_so)
189254721Semaste        {
190254721Semaste            // Matched the empty string...
191254721Semaste            match_str = llvm::StringRef();
192254721Semaste            return true;
193254721Semaste        }
194254721Semaste        else if (m_matches[idx].rm_eo > m_matches[idx].rm_so)
195254721Semaste        {
196254721Semaste            match_str = llvm::StringRef (s + m_matches[idx].rm_so, m_matches[idx].rm_eo - m_matches[idx].rm_so);
197254721Semaste            return true;
198254721Semaste        }
199254721Semaste    }
200254721Semaste    return false;
201254721Semaste}
202254721Semaste
203254721Semastebool
204254721SemasteRegularExpression::Match::GetMatchSpanningIndices (const char* s, uint32_t idx1, uint32_t idx2, llvm::StringRef& match_str) const
205254721Semaste{
206254721Semaste    if (idx1 < m_matches.size() && idx2 < m_matches.size())
207254721Semaste    {
208254721Semaste        if (m_matches[idx1].rm_so == m_matches[idx2].rm_eo)
209254721Semaste        {
210254721Semaste            // Matched the empty string...
211254721Semaste            match_str = llvm::StringRef();
212254721Semaste            return true;
213254721Semaste        }
214254721Semaste        else if (m_matches[idx1].rm_so < m_matches[idx2].rm_eo)
215254721Semaste        {
216254721Semaste            match_str = llvm::StringRef (s + m_matches[idx1].rm_so, m_matches[idx2].rm_eo - m_matches[idx1].rm_so);
217254721Semaste            return true;
218254721Semaste        }
219254721Semaste    }
220254721Semaste    return false;
221254721Semaste}
222254721Semaste
223254721Semaste
224254721Semaste//----------------------------------------------------------------------
225254721Semaste// Returns true if the regular expression compiled and is ready
226254721Semaste// for execution.
227254721Semaste//----------------------------------------------------------------------
228254721Semastebool
229254721SemasteRegularExpression::IsValid () const
230254721Semaste{
231254721Semaste    return m_comp_err == 0;
232254721Semaste}
233254721Semaste
234254721Semaste//----------------------------------------------------------------------
235254721Semaste// Returns the text that was used to compile the current regular
236254721Semaste// expression.
237254721Semaste//----------------------------------------------------------------------
238254721Semasteconst char*
239254721SemasteRegularExpression::GetText () const
240254721Semaste{
241254721Semaste    if (m_re.empty())
242254721Semaste        return NULL;
243254721Semaste    return m_re.c_str();
244254721Semaste}
245254721Semaste
246254721Semaste//----------------------------------------------------------------------
247254721Semaste// Free any contained compiled regular expressions.
248254721Semaste//----------------------------------------------------------------------
249254721Semastevoid
250254721SemasteRegularExpression::Free()
251254721Semaste{
252254721Semaste    if (m_comp_err == 0)
253254721Semaste    {
254254721Semaste        m_re.clear();
255254721Semaste        regfree(&m_preg);
256254721Semaste        // Set a compile error since we no longer have a valid regex
257254721Semaste        m_comp_err = 1;
258254721Semaste    }
259254721Semaste}
260254721Semaste
261254721Semastesize_t
262254721SemasteRegularExpression::GetErrorAsCString (char *err_str, size_t err_str_max_len) const
263254721Semaste{
264254721Semaste    if (m_comp_err == 0)
265254721Semaste    {
266254721Semaste        if (err_str && err_str_max_len)
267254721Semaste            *err_str = '\0';
268254721Semaste        return 0;
269254721Semaste    }
270254721Semaste
271254721Semaste    return ::regerror (m_comp_err, &m_preg, err_str, err_str_max_len);
272254721Semaste}
273254721Semaste
274254721Semastebool
275254721SemasteRegularExpression::operator < (const RegularExpression& rhs) const
276254721Semaste{
277254721Semaste    return (m_re < rhs.m_re);
278254721Semaste}
279254721Semaste
280