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