RegularExpression.cpp revision 6bc0b5d69f6f5f46055be6cfea6f9a0eb11b1943
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_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(),
103                                  &m_matches.front(),
104                                  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    {
114        match_str.assign (s + m_matches[idx].rm_so,
115                          m_matches[idx].rm_eo - m_matches[idx].rm_so);
116        return true;
117    }
118    return false;
119}
120
121
122//----------------------------------------------------------------------
123// Returns true if the regular expression compiled and is ready
124// for execution.
125//----------------------------------------------------------------------
126bool
127RegularExpression::IsValid () const
128{
129    return m_comp_err == 0;
130}
131
132//----------------------------------------------------------------------
133// Returns the text that was used to compile the current regular
134// expression.
135//----------------------------------------------------------------------
136const char*
137RegularExpression::GetText () const
138{
139    return m_re.c_str();
140}
141
142//----------------------------------------------------------------------
143// Free any contained compiled regular expressions.
144//----------------------------------------------------------------------
145void
146RegularExpression::Free()
147{
148    if (m_comp_err == 0)
149    {
150        m_re.clear();
151        regfree(&m_preg);
152        // Set a compile error since we no longer have a valid regex
153        m_comp_err = 1;
154    }
155}
156
157size_t
158RegularExpression::GetErrorAsCString (char *err_str, size_t err_str_max_len) const
159{
160    if (m_comp_err == 0)
161    {
162        if (err_str && err_str_max_len)
163            *err_str = '\0';
164        return 0;
165    }
166
167    return ::regerror (m_comp_err, &m_preg, err_str, err_str_max_len);
168}
169
170
171