blob: 7848931e3927aef586f8150896faba49eb166e2f [file] [log] [blame]
Chris Lattner30fdc8d2010-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 Friedman88966972010-06-09 08:50:27 +000011#include <string.h>
Chris Lattner30fdc8d2010-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(),
22 m_matches()
23{
24 memset(&m_preg,0,sizeof(m_preg));
25}
26
27//----------------------------------------------------------------------
28// Constructor that compiles "re" using "flags" and stores the
29// resulting compiled regular expression into this object.
30//----------------------------------------------------------------------
31RegularExpression::RegularExpression(const char* re, int flags) :
32 m_re(),
33 m_comp_err (1),
34 m_preg()
35{
36 memset(&m_preg,0,sizeof(m_preg));
37 Compile(re, flags);
38}
39
40//----------------------------------------------------------------------
41// Destructor
42//
43// Any previosuly compiled regular expression contained in this
44// object will be freed.
45//----------------------------------------------------------------------
46RegularExpression::~RegularExpression()
47{
48 Free();
49}
50
51//----------------------------------------------------------------------
52// Compile a regular expression using the supplied regular
53// expression text and flags. The compied regular expression lives
54// in this object so that it can be readily used for regular
55// expression matches. Execute() can be called after the regular
56// expression is compiled. Any previosuly compiled regular
57// expression contained in this object will be freed.
58//
59// RETURNS
60// True of the refular expression compiles successfully, false
61// otherwise.
62//----------------------------------------------------------------------
63bool
64RegularExpression::Compile(const char* re, int flags)
65{
66 Free();
67 if (re && re[0])
68 {
69 m_re = re;
70 m_comp_err = ::regcomp (&m_preg, re, flags);
71 }
72 else
73 {
74 // No valid regular expression
75 m_comp_err = 1;
76 }
77
78 return m_comp_err == 0;
79}
80
81//----------------------------------------------------------------------
82// Execute a regular expression match using the compiled regular
83// expression that is already in this object against the match
84// string "s". If any parens are used for regular expression
85// matches "match_count" should indicate the number of regmatch_t
86// values that are present in "match_ptr". The regular expression
87// will be executed using the "execute_flags".
88//----------------------------------------------------------------------
89bool
90RegularExpression::Execute(const char* s, size_t num_matches, int execute_flags) const
91{
92 int match_result = 1;
93 if (m_comp_err == 0)
94 {
95 if (num_matches > 0)
96 m_matches.resize(num_matches + 1);
97 else
98 m_matches.clear();
99
100 match_result = ::regexec (&m_preg,
101 s,
102 m_matches.size(),
Greg Clayton6ad07dd2010-12-19 03:41:24 +0000103 &m_matches[0],
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000104 execute_flags);
105 }
106 return match_result == 0;
107}
108
109bool
110RegularExpression::GetMatchAtIndex (const char* s, uint32_t idx, std::string& match_str) const
111{
112 if (idx <= m_preg.re_nsub && idx < m_matches.size())
113 {
Greg Clayton6ad07dd2010-12-19 03:41:24 +0000114 if (m_matches[idx].rm_eo == m_matches[idx].rm_so)
115 {
116 // Matched the empty string...
117 match_str.clear();
118 return true;
119 }
120 else if (m_matches[idx].rm_eo > m_matches[idx].rm_so)
121 {
122 match_str.assign (s + m_matches[idx].rm_so,
123 m_matches[idx].rm_eo - m_matches[idx].rm_so);
124 return true;
125 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000126 }
127 return false;
128}
129
130
131//----------------------------------------------------------------------
132// Returns true if the regular expression compiled and is ready
133// for execution.
134//----------------------------------------------------------------------
135bool
136RegularExpression::IsValid () const
137{
138 return m_comp_err == 0;
139}
140
141//----------------------------------------------------------------------
142// Returns the text that was used to compile the current regular
143// expression.
144//----------------------------------------------------------------------
145const char*
146RegularExpression::GetText () const
147{
148 return m_re.c_str();
149}
150
151//----------------------------------------------------------------------
152// Free any contained compiled regular expressions.
153//----------------------------------------------------------------------
154void
155RegularExpression::Free()
156{
157 if (m_comp_err == 0)
158 {
159 m_re.clear();
160 regfree(&m_preg);
161 // Set a compile error since we no longer have a valid regex
162 m_comp_err = 1;
163 }
164}
Greg Clayton46747022010-10-10 23:55:27 +0000165
166size_t
167RegularExpression::GetErrorAsCString (char *err_str, size_t err_str_max_len) const
168{
169 if (m_comp_err == 0)
170 {
171 if (err_str && err_str_max_len)
172 *err_str = '\0';
173 return 0;
174 }
175
176 return ::regerror (m_comp_err, &m_preg, err_str, err_str_max_len);
177}
178
179