blob: d98bf484abfefd12ce15f6a55033a716abbf7367 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- 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"
Eli Friedmana4083262010-06-09 08:50:27 +000011#include <string.h>
Chris Lattner24943d22010-06-08 16:52:24 +000012
13using namespace lldb_private;
14
15//----------------------------------------------------------------------
16// Default constructor
17//----------------------------------------------------------------------
18RegularExpression::RegularExpression() :
19 m_re(),
20 m_comp_err (1),
21 m_preg(),
Jim Ingham03c8ee52011-09-21 01:17:13 +000022 m_compile_flags(REG_EXTENDED),
Chris Lattner24943d22010-06-08 16:52:24 +000023 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),
Daniel Dunbar97c89572011-10-31 22:50:49 +000035 m_preg(),
36 m_compile_flags(flags)
Chris Lattner24943d22010-06-08 16:52:24 +000037{
38 memset(&m_preg,0,sizeof(m_preg));
Jim Ingham03c8ee52011-09-21 01:17:13 +000039 Compile(re);
Chris Lattner24943d22010-06-08 16:52:24 +000040}
41
42//----------------------------------------------------------------------
Jim Ingham03c8ee52011-09-21 01:17:13 +000043// 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),
Daniel Dunbar97c89572011-10-31 22:50:49 +000049 m_preg(),
50 m_compile_flags(REG_EXTENDED)
Jim Ingham03c8ee52011-09-21 01:17:13 +000051{
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//----------------------------------------------------------------------
Chris Lattner24943d22010-06-08 16:52:24 +000072// 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
Jim Ingham03c8ee52011-09-21 01:17:13 +000095RegularExpression::Compile(const char* re)
96{
97 return Compile (re, m_compile_flags);
98}
99
100bool
Chris Lattner24943d22010-06-08 16:52:24 +0000101RegularExpression::Compile(const char* re, int flags)
102{
103 Free();
Jim Ingham03c8ee52011-09-21 01:17:13 +0000104 m_compile_flags = flags;
105
Chris Lattner24943d22010-06-08 16:52:24 +0000106 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(),
Greg Clayton928d1302010-12-19 03:41:24 +0000142 &m_matches[0],
Chris Lattner24943d22010-06-08 16:52:24 +0000143 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 {
Greg Clayton928d1302010-12-19 03:41:24 +0000153 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 }
Chris Lattner24943d22010-06-08 16:52:24 +0000165 }
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{
Greg Clayton73844aa2012-08-22 17:17:09 +0000187 if (m_re.empty())
188 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000189 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}
Greg Clayton6bc0b5d2010-10-10 23:55:27 +0000206
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
Enrico Granata886bc3e2011-07-02 00:25:22 +0000220bool
221RegularExpression::operator < (const RegularExpression& rhs) const
222{
223 return (m_re < rhs.m_re);
224}
Greg Clayton6bc0b5d2010-10-10 23:55:27 +0000225