RegularExpression.cpp revision 73844aa19a7360b662e2be710fc3c969d6c86606
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 <string.h>
12
13using namespace lldb_private;
14
15//----------------------------------------------------------------------
16// Default constructor
17//----------------------------------------------------------------------
18RegularExpression::RegularExpression() :
19    m_re(),
20    m_comp_err (1),
21    m_preg(),
22    m_compile_flags(REG_EXTENDED),
23    m_matches()
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//----------------------------------------------------------------------
32RegularExpression::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//----------------------------------------------------------------------
46RegularExpression::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
56RegularExpression::RegularExpression(const RegularExpression &rhs)
57{
58    memset(&m_preg,0,sizeof(m_preg));
59    Compile(rhs.GetText(), rhs.GetCompileFlags());
60}
61
62const RegularExpression &
63RegularExpression::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//----------------------------------------------------------------------
77RegularExpression::~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//----------------------------------------------------------------------
94bool
95RegularExpression::Compile(const char* re)
96{
97    return Compile (re, m_compile_flags);
98}
99
100bool
101RegularExpression::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//----------------------------------------------------------------------
128bool
129RegularExpression::Execute(const char* s, size_t num_matches, int execute_flags) const
130{
131    int match_result = 1;
132    if (m_comp_err == 0)
133    {
134        if (num_matches > 0)
135            m_matches.resize(num_matches + 1);
136        else
137            m_matches.clear();
138
139        match_result = ::regexec (&m_preg,
140                                  s,
141                                  m_matches.size(),
142                                  &m_matches[0],
143                                  execute_flags);
144    }
145    return match_result == 0;
146}
147
148bool
149RegularExpression::GetMatchAtIndex (const char* s, uint32_t idx, std::string& match_str) const
150{
151    if (idx <= m_preg.re_nsub && idx < m_matches.size())
152    {
153        if (m_matches[idx].rm_eo == m_matches[idx].rm_so)
154        {
155            // Matched the empty string...
156            match_str.clear();
157            return true;
158        }
159        else if (m_matches[idx].rm_eo > m_matches[idx].rm_so)
160        {
161            match_str.assign (s + m_matches[idx].rm_so,
162                              m_matches[idx].rm_eo - m_matches[idx].rm_so);
163            return true;
164        }
165    }
166    return false;
167}
168
169
170//----------------------------------------------------------------------
171// Returns true if the regular expression compiled and is ready
172// for execution.
173//----------------------------------------------------------------------
174bool
175RegularExpression::IsValid () const
176{
177    return m_comp_err == 0;
178}
179
180//----------------------------------------------------------------------
181// Returns the text that was used to compile the current regular
182// expression.
183//----------------------------------------------------------------------
184const char*
185RegularExpression::GetText () const
186{
187    if (m_re.empty())
188        return NULL;
189    return m_re.c_str();
190}
191
192//----------------------------------------------------------------------
193// Free any contained compiled regular expressions.
194//----------------------------------------------------------------------
195void
196RegularExpression::Free()
197{
198    if (m_comp_err == 0)
199    {
200        m_re.clear();
201        regfree(&m_preg);
202        // Set a compile error since we no longer have a valid regex
203        m_comp_err = 1;
204    }
205}
206
207size_t
208RegularExpression::GetErrorAsCString (char *err_str, size_t err_str_max_len) const
209{
210    if (m_comp_err == 0)
211    {
212        if (err_str && err_str_max_len)
213            *err_str = '\0';
214        return 0;
215    }
216
217    return ::regerror (m_comp_err, &m_preg, err_str, err_str_max_len);
218}
219
220bool
221RegularExpression::operator < (const RegularExpression& rhs) const
222{
223    return (m_re < rhs.m_re);
224}
225
226