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 "llvm/ADT/StringRef.h" 12 #include <string.h> 13 14 using namespace lldb_private; 15 16 //---------------------------------------------------------------------- 17 // Default constructor 18 //---------------------------------------------------------------------- 19 RegularExpression::RegularExpression() : 20 m_re(), 21 m_comp_err (1), 22 m_preg(), 23 m_compile_flags(REG_EXTENDED) 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 //---------------------------------------------------------------------- 32 RegularExpression::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 //---------------------------------------------------------------------- 46 RegularExpression::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 56 RegularExpression::RegularExpression(const RegularExpression &rhs) 57 { 58 memset(&m_preg,0,sizeof(m_preg)); 59 Compile(rhs.GetText(), rhs.GetCompileFlags()); 60 } 61 62 const RegularExpression & 63 RegularExpression::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 //---------------------------------------------------------------------- 77 RegularExpression::~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 //---------------------------------------------------------------------- 94 bool 95 RegularExpression::Compile(const char* re) 96 { 97 return Compile (re, m_compile_flags); 98 } 99 100 bool 101 RegularExpression::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 //--------------------------------------------------------------------- 128 bool 129 RegularExpression::Execute(const char* s, Match *match, int execute_flags) const 130 { 131 int err = 1; 132 if (s != NULL && m_comp_err == 0) 133 { 134 if (match) 135 { 136 err = ::regexec (&m_preg, 137 s, 138 match->GetSize(), 139 match->GetData(), 140 execute_flags); 141 } 142 else 143 { 144 err = ::regexec (&m_preg, 145 s, 146 0, 147 NULL, 148 execute_flags); 149 } 150 } 151 152 if (err != 0) 153 { 154 // The regular expression didn't compile, so clear the matches 155 if (match) 156 match->Clear(); 157 return false; 158 } 159 return true; 160 } 161 162 bool 163 RegularExpression::Match::GetMatchAtIndex (const char* s, uint32_t idx, std::string& match_str) const 164 { 165 if (idx < m_matches.size()) 166 { 167 if (m_matches[idx].rm_eo == m_matches[idx].rm_so) 168 { 169 // Matched the empty string... 170 match_str.clear(); 171 return true; 172 } 173 else if (m_matches[idx].rm_eo > m_matches[idx].rm_so) 174 { 175 match_str.assign (s + m_matches[idx].rm_so, 176 m_matches[idx].rm_eo - m_matches[idx].rm_so); 177 return true; 178 } 179 } 180 return false; 181 } 182 183 bool 184 RegularExpression::Match::GetMatchAtIndex (const char* s, uint32_t idx, llvm::StringRef& match_str) const 185 { 186 if (idx < m_matches.size()) 187 { 188 if (m_matches[idx].rm_eo == m_matches[idx].rm_so) 189 { 190 // Matched the empty string... 191 match_str = llvm::StringRef(); 192 return true; 193 } 194 else if (m_matches[idx].rm_eo > m_matches[idx].rm_so) 195 { 196 match_str = llvm::StringRef (s + m_matches[idx].rm_so, m_matches[idx].rm_eo - m_matches[idx].rm_so); 197 return true; 198 } 199 } 200 return false; 201 } 202 203 bool 204 RegularExpression::Match::GetMatchSpanningIndices (const char* s, uint32_t idx1, uint32_t idx2, llvm::StringRef& match_str) const 205 { 206 if (idx1 < m_matches.size() && idx2 < m_matches.size()) 207 { 208 if (m_matches[idx1].rm_so == m_matches[idx2].rm_eo) 209 { 210 // Matched the empty string... 211 match_str = llvm::StringRef(); 212 return true; 213 } 214 else if (m_matches[idx1].rm_so < m_matches[idx2].rm_eo) 215 { 216 match_str = llvm::StringRef (s + m_matches[idx1].rm_so, m_matches[idx2].rm_eo - m_matches[idx1].rm_so); 217 return true; 218 } 219 } 220 return false; 221 } 222 223 224 //---------------------------------------------------------------------- 225 // Returns true if the regular expression compiled and is ready 226 // for execution. 227 //---------------------------------------------------------------------- 228 bool 229 RegularExpression::IsValid () const 230 { 231 return m_comp_err == 0; 232 } 233 234 //---------------------------------------------------------------------- 235 // Returns the text that was used to compile the current regular 236 // expression. 237 //---------------------------------------------------------------------- 238 const char* 239 RegularExpression::GetText () const 240 { 241 if (m_re.empty()) 242 return NULL; 243 return m_re.c_str(); 244 } 245 246 //---------------------------------------------------------------------- 247 // Free any contained compiled regular expressions. 248 //---------------------------------------------------------------------- 249 void 250 RegularExpression::Free() 251 { 252 if (m_comp_err == 0) 253 { 254 m_re.clear(); 255 regfree(&m_preg); 256 // Set a compile error since we no longer have a valid regex 257 m_comp_err = 1; 258 } 259 } 260 261 size_t 262 RegularExpression::GetErrorAsCString (char *err_str, size_t err_str_max_len) const 263 { 264 if (m_comp_err == 0) 265 { 266 if (err_str && err_str_max_len) 267 *err_str = '\0'; 268 return 0; 269 } 270 271 return ::regerror (m_comp_err, &m_preg, err_str, err_str_max_len); 272 } 273 274 bool 275 RegularExpression::operator < (const RegularExpression& rhs) const 276 { 277 return (m_re < rhs.m_re); 278 } 279 280