1 //===-- RegularExpression.cpp -----------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 #include "lldb/Core/RegularExpression.h"
12 #include "llvm/ADT/StringRef.h"
13 #include "lldb/Core/Error.h"
16 //----------------------------------------------------------------------
17 // Enable enhanced mode if it is available. This allows for things like
18 // \d for digit, \s for space, and many more, but it isn't available
20 //----------------------------------------------------------------------
21 #if defined(REG_ENHANCED)
22 #define DEFAULT_COMPILE_FLAGS (REG_ENHANCED|REG_EXTENDED)
24 #define DEFAULT_COMPILE_FLAGS (REG_EXTENDED)
27 using namespace lldb_private;
29 //----------------------------------------------------------------------
30 // Default constructor
31 //----------------------------------------------------------------------
32 RegularExpression::RegularExpression() :
37 memset(&m_preg,0,sizeof(m_preg));
40 //----------------------------------------------------------------------
41 // Constructor that compiles "re" using "flags" and stores the
42 // resulting compiled regular expression into this object.
43 //----------------------------------------------------------------------
44 RegularExpression::RegularExpression(const char* re) :
49 memset(&m_preg,0,sizeof(m_preg));
53 RegularExpression::RegularExpression(const RegularExpression &rhs)
55 memset(&m_preg,0,sizeof(m_preg));
56 Compile(rhs.GetText());
59 const RegularExpression &
60 RegularExpression::operator= (const RegularExpression &rhs)
63 Compile (rhs.GetText());
66 //----------------------------------------------------------------------
69 // Any previously compiled regular expression contained in this
70 // object will be freed.
71 //----------------------------------------------------------------------
72 RegularExpression::~RegularExpression()
77 //----------------------------------------------------------------------
78 // Compile a regular expression using the supplied regular
79 // expression text and flags. The compiled regular expression lives
80 // in this object so that it can be readily used for regular
81 // expression matches. Execute() can be called after the regular
82 // expression is compiled. Any previously compiled regular
83 // expression contained in this object will be freed.
86 // True if the regular expression compiles successfully, false
88 //----------------------------------------------------------------------
90 RegularExpression::Compile(const char* re)
97 m_comp_err = ::regcomp (&m_preg, re, DEFAULT_COMPILE_FLAGS);
101 // No valid regular expression
105 return m_comp_err == 0;
108 //----------------------------------------------------------------------
109 // Execute a regular expression match using the compiled regular
110 // expression that is already in this object against the match
111 // string "s". If any parens are used for regular expression
112 // matches "match_count" should indicate the number of regmatch_t
113 // values that are present in "match_ptr". The regular expression
114 // will be executed using the "execute_flags".
115 //---------------------------------------------------------------------
117 RegularExpression::Execute (const char* s, Match *match) const
120 if (s != NULL && m_comp_err == 0)
124 err = ::regexec (&m_preg,
132 err = ::regexec (&m_preg,
142 // The regular expression didn't compile, so clear the matches
151 RegularExpression::Match::GetMatchAtIndex (const char* s, uint32_t idx, std::string& match_str) const
153 llvm::StringRef match_str_ref;
154 if (GetMatchAtIndex(s, idx, match_str_ref))
156 match_str = std::move(match_str_ref.str());
163 RegularExpression::Match::GetMatchAtIndex (const char* s, uint32_t idx, llvm::StringRef& match_str) const
165 if (idx < m_matches.size())
167 if (m_matches[idx].rm_eo == -1 && m_matches[idx].rm_so == -1)
170 if (m_matches[idx].rm_eo == m_matches[idx].rm_so)
172 // Matched the empty string...
173 match_str = llvm::StringRef();
176 else if (m_matches[idx].rm_eo > m_matches[idx].rm_so)
178 match_str = llvm::StringRef (s + m_matches[idx].rm_so, m_matches[idx].rm_eo - m_matches[idx].rm_so);
186 RegularExpression::Match::GetMatchSpanningIndices (const char* s, uint32_t idx1, uint32_t idx2, llvm::StringRef& match_str) const
188 if (idx1 < m_matches.size() && idx2 < m_matches.size())
190 if (m_matches[idx1].rm_so == m_matches[idx2].rm_eo)
192 // Matched the empty string...
193 match_str = llvm::StringRef();
196 else if (m_matches[idx1].rm_so < m_matches[idx2].rm_eo)
198 match_str = llvm::StringRef (s + m_matches[idx1].rm_so, m_matches[idx2].rm_eo - m_matches[idx1].rm_so);
206 //----------------------------------------------------------------------
207 // Returns true if the regular expression compiled and is ready
209 //----------------------------------------------------------------------
211 RegularExpression::IsValid () const
213 return m_comp_err == 0;
216 //----------------------------------------------------------------------
217 // Returns the text that was used to compile the current regular
219 //----------------------------------------------------------------------
221 RegularExpression::GetText () const
228 //----------------------------------------------------------------------
229 // Free any contained compiled regular expressions.
230 //----------------------------------------------------------------------
232 RegularExpression::Free()
238 // Set a compile error since we no longer have a valid regex
244 RegularExpression::GetErrorAsCString (char *err_str, size_t err_str_max_len) const
248 if (err_str && err_str_max_len)
253 return ::regerror (m_comp_err, &m_preg, err_str, err_str_max_len);
257 RegularExpression::operator < (const RegularExpression& rhs) const
259 return (m_re < rhs.m_re);