llvm.org GIT mirror llvm / 81f46d9
remove support for "NoSub" from regex. It seems like a minor optimization and makes the API more annoying. Add a Regex::getNumMatches() method. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@82877 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 10 years ago
4 changed file(s) with 25 addition(s) and 33 deletion(s). Raw diff Collapse all Expand all
2121 class Regex {
2222 public:
2323 enum {
24 /// Compile with support for subgroup matches, this is just to make
25 /// constructs like Regex("...", 0) more readable as Regex("...", Sub).
26 Sub=0,
24 NoFlags=0,
2725 /// Compile for matching that ignores upper/lower case distinctions.
2826 IgnoreCase=1,
29 /// Compile for matching that need only report success or failure,
30 /// not what was matched.
31 NoSub=2,
3227 /// Compile for newline-sensitive matching. With this flag '[^' bracket
3328 /// expressions and '.' never match newline. A ^ anchor matches the
3429 /// null string after any newline in the string in addition to its normal
3530 /// function, and the $ anchor matches the null string before any
3631 /// newline in the string in addition to its normal function.
37 Newline=4
32 Newline=2
3833 };
3934
4035 /// Compiles the given POSIX Extended Regular Expression \arg Regex.
4136 /// This implementation supports regexes and matching strings with embedded
4237 /// NUL characters.
43 Regex(const StringRef &Regex, unsigned Flags=NoSub);
38 Regex(const StringRef &Regex, unsigned Flags = NoFlags);
4439 ~Regex();
4540
4641 /// isValid - returns the error encountered during regex compilation, or
4742 /// matching, if any.
4843 bool isValid(std::string &Error);
4944
45 /// getNumMatches - In a valid regex, return the number of parenthesized
46 /// matches it contains. The number filled in by match will include this
47 /// many entries plus one for the whole regex (as element 0).
48 unsigned getNumMatches() const;
49
5050 /// matches - Match the regex against a given \arg String.
5151 ///
5252 /// \param Matches - If given, on a succesful match this will be filled in
5353 /// with references to the matched group expressions (inside \arg String),
5454 /// the first group is always the entire pattern.
55 /// By default the regex is compiled with NoSub, which disables support for
56 /// Matches.
57 /// For this feature to be enabled you must construct the regex using
58 /// Regex("...", Regex::Sub) constructor.
5955 ///
6056 /// This returns true on a successful match.
6157 bool match(const StringRef &String, SmallVectorImpl *Matches=0);
6258 private:
6359 struct llvm_regex *preg;
6460 int error;
65 bool sub;
6661 };
6762 }
2424 preg->re_endp = regex.end();
2525 if (Flags & IgnoreCase)
2626 flags |= REG_ICASE;
27 if (Flags & NoSub) {
28 flags |= REG_NOSUB;
29 sub = false;
30 } else {
31 sub = true;
32 }
3327 if (Flags & Newline)
3428 flags |= REG_NEWLINE;
3529 error = llvm_regcomp(preg, regex.data(), flags|REG_EXTENDED|REG_PEND);
3630 }
3731
32 Regex::~Regex() {
33 llvm_regfree(preg);
34 delete preg;
35 }
36
3837 bool Regex::isValid(std::string &Error) {
3938 if (!error)
4039 return true;
41
40
4241 size_t len = llvm_regerror(error, preg, NULL, 0);
4342
4443 Error.resize(len);
4645 return false;
4746 }
4847
49 Regex::~Regex() {
50 llvm_regfree(preg);
51 delete preg;
48 /// getNumMatches - In a valid regex, return the number of parenthesized
49 /// matches it contains.
50 unsigned Regex::getNumMatches() const {
51 return preg->re_nsub;
5252 }
5353
5454 bool Regex::match(const StringRef &String, SmallVectorImpl *Matches){
5555 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 }
6156
6257 // pmatch needs to have at least one element.
6358 SmallVector pm;
7873 // There was a match.
7974
8075 if (Matches) { // match position requested
76 Matches->clear();
77
8178 for (unsigned i = 0; i != nmatch; ++i) {
8279 if (pm[i].rm_so == -1) {
8380 // this group didn't match
2424 EXPECT_FALSE(r1.match("9a"));
2525
2626 SmallVector Matches;
27 Regex r2("[0-9]+", Regex::Sub);
27 Regex r2("[0-9]+");
2828 EXPECT_TRUE(r2.match("aa216b", &Matches));
2929 EXPECT_EQ(1u, Matches.size());
3030 EXPECT_EQ("216", Matches[0].str());
3131
32 Regex r3("[0-9]+([a-f])?:([0-9]+)", Regex::Sub);
32 Regex r3("[0-9]+([a-f])?:([0-9]+)");
3333 EXPECT_TRUE(r3.match("9a:513b", &Matches));
3434 EXPECT_EQ(3u, Matches.size());
3535 EXPECT_EQ("9a:513", Matches[0].str());
4242 EXPECT_EQ("", Matches[1].str());
4343 EXPECT_EQ("513", Matches[2].str());
4444
45 Regex r4("a[^b]+b", Regex::Sub);
45 Regex r4("a[^b]+b");
4646 std::string String="axxb";
4747 String[2] = '\0';
4848 EXPECT_FALSE(r4.match("abb"));
5454 std::string NulPattern="X[0-9]+X([a-f])?:([0-9]+)";
5555 String="YX99a:513b";
5656 NulPattern[7] = '\0';
57 Regex r5(NulPattern, Regex::Sub);
57 Regex r5(NulPattern);
5858 EXPECT_FALSE(r5.match(String));
5959 EXPECT_FALSE(r5.match("X9"));
6060 String[3]='\0';
167167
168168 // Regex match.
169169 SmallVector MatchInfo;
170 if (!Regex(RegExStr, Regex::Sub|Regex::Newline).match(Buffer, &MatchInfo))
170 if (!Regex(RegExStr, Regex::Newline).match(Buffer, &MatchInfo))
171171 return StringRef::npos;
172172
173173 // Successful regex match.