[llvm-commits] [llvm] r169109 - in /llvm/trunk: test/FileCheck/regex-brackets.txt test/FileCheck/simple-var-capture.txt utils/FileCheck/FileCheck.cpp

Eli Bendersky eliben at google.com
Sun Dec 2 08:02:41 PST 2012


Author: eliben
Date: Sun Dec  2 10:02:41 2012
New Revision: 169109

URL: http://llvm.org/viewvc/llvm-project?rev=169109&view=rev
Log:
Fix a bug in FileCheck that wouldn't let define variables as follows:

; CHECK: [[VAR:[a-z]]]

The problem was that to find the end of the regex var definition, it was
simplistically looking for the next ]] and finding the incorrect one. A
better approach is to count nesting of brackets (taking escaping into
account). This way the brackets that are part of the regex can be discovered
and skipped properly, and the ]] ending is detected in the right place.



Added:
    llvm/trunk/test/FileCheck/regex-brackets.txt
Modified:
    llvm/trunk/test/FileCheck/simple-var-capture.txt
    llvm/trunk/utils/FileCheck/FileCheck.cpp

Added: llvm/trunk/test/FileCheck/regex-brackets.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FileCheck/regex-brackets.txt?rev=169109&view=auto
==============================================================================
--- llvm/trunk/test/FileCheck/regex-brackets.txt (added)
+++ llvm/trunk/test/FileCheck/regex-brackets.txt Sun Dec  2 10:02:41 2012
@@ -0,0 +1,7 @@
+// RUN: FileCheck -input-file %s %s
+
+op r1
+op r2, [x r1]
+; CHECK:        op [[REG:r[0-9]]]
+; CHECK:        op [[REG2:r[0-9]]], [x [[REG]]]
+

Modified: llvm/trunk/test/FileCheck/simple-var-capture.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FileCheck/simple-var-capture.txt?rev=169109&r1=169108&r2=169109&view=diff
==============================================================================
--- llvm/trunk/test/FileCheck/simple-var-capture.txt (original)
+++ llvm/trunk/test/FileCheck/simple-var-capture.txt Sun Dec  2 10:02:41 2012
@@ -2,7 +2,7 @@
 
 op1 r1
 op2 r1, r2
-; CHECK:        op1 [[REG:r[0-9]+]]
+; CHECK:        op1 [[REG:r[0-9]]]
 ; CHECK-NEXT:   op2 [[REG]]
 
 op3 r16, r18, r21
@@ -10,3 +10,4 @@
 ; CHECK:        op3 {{r[0-9]+}}, [[REGa:r[0-9]+]], [[REGb:r[0-9]+]]
 ; CHECK-NEXT:   op4 {{r[0-9]+}}, [[REGa]], [[REGb]]
 
+

Modified: llvm/trunk/utils/FileCheck/FileCheck.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/FileCheck/FileCheck.cpp?rev=169109&r1=169108&r2=169109&view=diff
==============================================================================
--- llvm/trunk/utils/FileCheck/FileCheck.cpp (original)
+++ llvm/trunk/utils/FileCheck/FileCheck.cpp Sun Dec  2 10:02:41 2012
@@ -119,6 +119,13 @@
   /// \brief Evaluates expression and stores the result to \p Value.
   /// \return true on success. false when the expression has invalid syntax.
   bool EvaluateExpression(StringRef Expr, std::string &Value) const;
+
+  /// \brief Finds the closing sequence of a regex variable usage or
+  /// definition. Str has to point in the beginning of the definition
+  /// (right after the opening sequence).
+  /// \return offset of the closing sequence within Str, or npos if it was not
+  /// found.
+  size_t FindRegexVarEnd(StringRef Str);
 };
 
 
@@ -187,8 +194,10 @@
     // itself must be of the form "[a-zA-Z_][0-9a-zA-Z_]*", otherwise we reject
     // it.  This is to catch some common errors.
     if (PatternStr.startswith("[[")) {
-      // Verify that it is terminated properly.
-      size_t End = PatternStr.find("]]");
+      // Find the closing bracket pair ending the match.  End is going to be an
+      // offset relative to the beginning of the match string.
+      size_t End = FindRegexVarEnd(PatternStr.substr(2));
+
       if (End == StringRef::npos) {
         SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
                         SourceMgr::DK_Error,
@@ -196,8 +205,8 @@
         return true;
       }
 
-      StringRef MatchStr = PatternStr.substr(2, End-2);
-      PatternStr = PatternStr.substr(End+2);
+      StringRef MatchStr = PatternStr.substr(2, End);
+      PatternStr = PatternStr.substr(End+4);
 
       // Get the regex name (e.g. "foo").
       size_t NameEnd = MatchStr.find(':');
@@ -519,6 +528,40 @@
   }
 }
 
+size_t Pattern::FindRegexVarEnd(StringRef Str) {
+  // Offset keeps track of the current offset within the input Str
+  size_t Offset = 0;
+  // [...] Nesting depth
+  size_t BracketDepth = 0;
+
+  while (!Str.empty()) {
+    if (Str.startswith("]]") && BracketDepth == 0)
+      return Offset;
+    if (Str[0] == '\\') {
+      // Backslash escapes the next char within regexes, so skip them both.
+      Str = Str.substr(2);
+      Offset += 2;
+    } else {
+      switch (Str[0]) {
+        default:
+          break;
+        case '[':
+          BracketDepth++;
+          break;
+        case ']':
+          assert(BracketDepth > 0 && "Invalid regex");
+          BracketDepth--;
+          break;
+      }
+      Str = Str.substr(1);
+      Offset++;
+    }
+  }
+
+  return StringRef::npos;
+}
+
+
 //===----------------------------------------------------------------------===//
 // Check Strings.
 //===----------------------------------------------------------------------===//





More information about the llvm-commits mailing list