[libc-commits] [libc] [libc][regex] Add bracket expressions and character ranges (PR #234895)

Pavel Labath via libc-commits libc-commits at lists.llvm.org
Fri Oct 23 04:53:15 PDT 2026


================
@@ -261,18 +261,103 @@ TEST(LlvmLibcRegexMatcherTest, ParseEreEscapesAndErrors) {
     EXPECT_EQ(err.error(), REG_BADRPT);
   }
 
+  const string_view ebrack_patterns[] = {"[abc", "[]", "a[[.x", "a[[.x."};
+  for (string_view pat : ebrack_patterns) {
+    ErrorOr<ExprId> err = parse_ere(pat, REG_EXTENDED, pool);
+    ASSERT_FALSE(err.has_value());
+    EXPECT_EQ(err.error(), REG_EBRACK);
+  }
+
+  const string_view erange_patterns[] = {"a[3-1]c", "a[1-3-5]c", "a[1-",
+                                         "a[a-[:digit:]]c"};
+  for (string_view pat : erange_patterns) {
+    ErrorOr<ExprId> err = parse_ere(pat, REG_EXTENDED, pool);
+    ASSERT_FALSE(err.has_value());
+    EXPECT_EQ(err.error(), REG_ERANGE);
+  }
+
+  const string_view ecollate_patterns[] = {"a[[.notdef.]]b", "a[[.x,.]]",
+                                           "a[[=b,=]]"};
+  for (string_view pat : ecollate_patterns) {
+    ErrorOr<ExprId> err = parse_ere(pat, REG_EXTENDED, pool);
+    ASSERT_FALSE(err.has_value());
+    EXPECT_EQ(err.error(), REG_ECOLLATE);
+  }
+
   const string_view bad_patterns[] = {
-      "a+",    "a?",    "a{1}",  "{",     "(",     ")",     "[",     "|",
-      R"(\1)", R"(\2)", R"(\3)", R"(\4)", R"(\5)", R"(\6)", R"(\7)", R"(\8)",
-      R"(\9)", R"(\b)", R"(\B)", R"(\<)", R"(\>)", R"(\A)", R"(\Z)", R"(\`)",
-      R"(\')", R"(\w)", R"(\W)", R"(\s)", R"(\S)", R"(\d)", R"(\D)"};
+      "a+",    "a?",    "a{1}",  "{",     "(",     ")",     "[[:alpha:]]",
+      "|",     R"(\1)", R"(\2)", R"(\3)", R"(\4)", R"(\5)", R"(\6)",
+      R"(\7)", R"(\8)", R"(\9)", R"(\b)", R"(\B)", R"(\<)", R"(\>)",
+      R"(\A)", R"(\Z)", R"(\`)", R"(\')", R"(\w)", R"(\W)", R"(\s)",
+      R"(\S)", R"(\d)", R"(\D)"};
   for (string_view bad : bad_patterns) {
     ErrorOr<ExprId> err = parse_ere(bad, REG_EXTENDED, pool);
     ASSERT_FALSE(err.has_value());
     EXPECT_EQ(err.error(), REG_BADPAT);
   }
 }
 
+TEST(LlvmLibcRegexMatcherTest, BracketMatchingAndRanges) {
+  ExprPool pool;
+  ErrorOr<ExprId> range = parse_ere("x[c-f]y", REG_EXTENDED, pool);
+  ASSERT_TRUE(range.has_value());
+  EXPECT_EQ(match(pool, *range, "xcy"), MatchResult::Match);
+  EXPECT_EQ(match(pool, *range, "xdy"), MatchResult::Match);
+  EXPECT_EQ(match(pool, *range, "xey"), MatchResult::Match);
+  EXPECT_EQ(match(pool, *range, "xfy"), MatchResult::Match);
+  EXPECT_EQ(match(pool, *range, "xby"), MatchResult::NoMatch);
+  EXPECT_EQ(match(pool, *range, "xgy"), MatchResult::NoMatch);
+  EXPECT_EQ(match(pool, *range, "xy"), MatchResult::NoMatch);
+  EXPECT_EQ(match(pool, *range, "xccy"), MatchResult::NoMatch);
+  EXPECT_EQ(match(pool, *range, "x-y"), MatchResult::NoMatch);
+
+  ErrorOr<ExprId> negated = parse_ere("x[^c-f]y", REG_EXTENDED, pool);
+  ASSERT_TRUE(negated.has_value());
+  EXPECT_EQ(match(pool, *negated, "xby"), MatchResult::Match);
+  EXPECT_EQ(match(pool, *negated, "xgy"), MatchResult::Match);
+  EXPECT_EQ(match(pool, *negated, "xcy"), MatchResult::NoMatch);
+  EXPECT_EQ(match(pool, *negated, "xfy"), MatchResult::NoMatch);
+  EXPECT_EQ(match(pool, *negated, "xy"), MatchResult::NoMatch);
+
+  ErrorOr<ExprId> nl_neg =
+      parse_ere("x[^c-f]y", REG_EXTENDED | REG_NEWLINE, pool);
+  ASSERT_TRUE(nl_neg.has_value());
+  EXPECT_EQ(match(pool, *nl_neg, "x\ny", REG_NEWLINE, 0), MatchResult::NoMatch);
+
+  ErrorOr<ExprId> first_rb = parse_ere("a[]b]c", REG_EXTENDED, pool);
+  ASSERT_TRUE(first_rb.has_value());
+  EXPECT_EQ(match(pool, *first_rb, "a]c"), MatchResult::Match);
+  EXPECT_EQ(match(pool, *first_rb, "abc"), MatchResult::Match);
+  EXPECT_EQ(match(pool, *first_rb, "ac"), MatchResult::NoMatch);
+
+  ErrorOr<ExprId> lead_dash = parse_ere("a[-b]c", REG_EXTENDED, pool);
----------------
labath wrote:

A case where '-' is the beginning/end of the range would be nice.

https://github.com/llvm/llvm-project/pull/234895


More information about the libc-commits mailing list