1 //===-- Regex.cpp - Regular Expression matcher implementation -------------===// 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 // This file implements a POSIX regular expression matcher. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/Support/Regex.h" 15 #include "llvm/Support/ErrorHandling.h" 16 #include "llvm/Support/raw_ostream.h" 17 #include "regex_impl.h" 18 #include <string> 19 using namespace llvm; 20 21 Regex::Regex(const StringRef ®ex, unsigned Flags) { 22 unsigned flags = 0; 23 preg = new struct llvm_regex; 24 preg->re_endp = regex.end(); 25 if (Flags & IgnoreCase) 26 flags |= REG_ICASE; 27 if (Flags & NoSub) { 28 flags |= REG_NOSUB; 29 sub = false; 30 } else { 31 sub = true; 32 } 33 if (Flags & Newline) 34 flags |= REG_NEWLINE; 35 error = llvm_regcomp(preg, regex.data(), flags|REG_EXTENDED|REG_PEND); 36 } 37 38 bool Regex::isValid(std::string &Error) { 39 if (!error) 40 return true; 41 42 size_t len = llvm_regerror(error, preg, NULL, 0); 43 44 Error.resize(len); 45 llvm_regerror(error, preg, &Error[0], len); 46 return false; 47 } 48 49 Regex::~Regex() { 50 llvm_regfree(preg); 51 delete preg; 52 } 53 54 bool Regex::match(const StringRef &String, SmallVectorImpl<StringRef> *Matches){ 55 unsigned nmatch = Matches ? preg->re_nsub+1 : 0; 56 57 if (Matches) { 58 assert(sub && "Substring matching requested but pattern compiled without"); 59 Matches->clear(); 60 } 61 62 // pmatch needs to have at least one element. 63 SmallVector<llvm_regmatch_t, 2> pm; 64 pm.resize(nmatch > 0 ? nmatch : 1); 65 pm[0].rm_so = 0; 66 pm[0].rm_eo = String.size(); 67 68 int rc = llvm_regexec(preg, String.data(), nmatch, pm.data(), REG_STARTEND); 69 70 if (rc == REG_NOMATCH) 71 return false; 72 if (rc != 0) { 73 // regexec can fail due to invalid pattern or running out of memory. 74 error = rc; 75 return false; 76 } 77 78 // There was a match. 79 80 if (Matches) { // match position requested 81 for (unsigned i = 0; i != nmatch; ++i) { 82 if (pm[i].rm_so == -1) { 83 // this group didn't match 84 Matches->push_back(StringRef()); 85 continue; 86 } 87 assert(pm[i].rm_eo > pm[i].rm_so); 88 Matches->push_back(StringRef(String.data()+pm[i].rm_so, 89 pm[i].rm_eo-pm[i].rm_so)); 90 } 91 } 92 93 return true; 94 } 95