| 81 | } |
| 82 | |
| 83 | bool Regex::match(StringRef String, SmallVectorImpl<StringRef> *Matches, |
| 84 | std::string *Error) const { |
| 85 | // Reset error, if given. |
| 86 | if (Error && !Error->empty()) |
| 87 | *Error = ""; |
| 88 | |
| 89 | // Check if the regex itself didn't successfully compile. |
| 90 | if (Error ? !isValid(*Error) : !isValid()) |
| 91 | return false; |
| 92 | |
| 93 | unsigned nmatch = Matches ? preg->re_nsub+1 : 0; |
| 94 | |
| 95 | // pmatch needs to have at least one element. |
| 96 | SmallVector<llvm_regmatch_t, 8> pm; |
| 97 | pm.resize(nmatch > 0 ? nmatch : 1); |
| 98 | pm[0].rm_so = 0; |
| 99 | pm[0].rm_eo = String.size(); |
| 100 | |
| 101 | int rc = llvm_regexec(preg, String.data(), nmatch, pm.data(), REG_STARTEND); |
| 102 | |
| 103 | // Failure to match is not an error, it's just a normal return value. |
| 104 | // Any other error code is considered abnormal, and is logged in the Error. |
| 105 | if (rc == REG_NOMATCH) |
| 106 | return false; |
| 107 | if (rc != 0) { |
| 108 | if (Error) |
| 109 | RegexErrorToString(error, preg, *Error); |
| 110 | return false; |
| 111 | } |
| 112 | |
| 113 | // There was a match. |
| 114 | |
| 115 | if (Matches) { // match position requested |
| 116 | Matches->clear(); |
| 117 | |
| 118 | for (unsigned i = 0; i != nmatch; ++i) { |
| 119 | if (pm[i].rm_so == -1) { |
| 120 | // this group didn't match |
| 121 | Matches->push_back(StringRef()); |
| 122 | continue; |
| 123 | } |
| 124 | assert(pm[i].rm_eo >= pm[i].rm_so); |
| 125 | Matches->push_back(StringRef(String.data()+pm[i].rm_so, |
| 126 | pm[i].rm_eo-pm[i].rm_so)); |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | return true; |
| 131 | } |
| 132 | |
| 133 | std::string Regex::sub(StringRef Repl, StringRef String, |
| 134 | std::string *Error) const { |