Index: test/FileCheck/check-regexp-prefix.txt =================================================================== --- /dev/null +++ test/FileCheck/check-regexp-prefix.txt @@ -0,0 +1,16 @@ +// RUN: FileCheck -check-prefix=A -regex-prefixes -input-file %s %s +// RUN: FileCheck -check-prefix=b -regex-prefixes -input-file %s %s + +for B check +first +next-line + +// {{[A-Z]+}}: first +// {{[a-z0-9]+}}: for {{B}} + + +// {{[A-C0-9]+}}-NEXT: {{next-line}} + +same for both +// {{[A-Za-z0-9]+}}: same +// {{[A-Za-z0-9]+}}-SAME: both Index: test/FileCheck/check-wildcard-prefix.txt =================================================================== --- /dev/null +++ test/FileCheck/check-wildcard-prefix.txt @@ -0,0 +1,13 @@ +// RUN: FileCheck -check-prefix=A -regex-prefixes -input-file %s %s +// RUN: not FileCheck -check-prefix=B -regex-prefixes -input-file %s %s + +for B check +first +next-line +// A: first +// B: for B +// {{*}}-NEXT: {{next-line}} + +same for both +// {{*}}: same +// {{*}}-SAME: both \ No newline at end of file Index: utils/FileCheck/FileCheck.cpp =================================================================== --- utils/FileCheck/FileCheck.cpp +++ utils/FileCheck/FileCheck.cpp @@ -73,6 +73,10 @@ "Allows leading and trailing whitespace if --strict-whitespace\n" "is not also passed.")); +static cl::opt +RegexPrefixesOn ("regex-prefixes", + cl::desc("Use checks with prefixes which can be described as regular expressions.")); + typedef cl::list::const_iterator prefix_iterator; //===----------------------------------------------------------------------===// @@ -792,6 +796,39 @@ for (StringRef Prefix : CheckPrefixes) { size_t PrefixLoc = Buffer.find(Prefix); + if (RegexPrefixesOn) { + SmallVector Matches; + // Try ti find prefixes defined as regexes. + Regex PrefixesWithRegexes(StringRef("\\{\\{(.+)\\}\\}(-.+)?:.+$")); + StringRef BufferCopy = Buffer; + size_t DiffInLoc = 0; + + while (PrefixesWithRegexes.match(BufferCopy, &Matches) && (DiffInLoc < PrefixLoc || PrefixLoc == StringRef::npos)) { + // Get regex part + StringRef RegexPart = Matches[1]; + if (RegexPart.find("}}") != StringRef::npos) { + RegexPart = RegexPart.substr(0, RegexPart.find("}}")); + } + + size_t RegexPrefixLoc = Matches[1].data()-BufferCopy.data(); + DiffInLoc += RegexPrefixLoc; + // Check if current prefix matches with found. + if (Regex(RegexPart).match(Prefix)) { + if (DiffInLoc < PrefixLoc) { + PrefixLoc = DiffInLoc; + Prefix = StringRef(RegexPart.str() + "}}"); + } + } + + if (BufferCopy.find("\n", RegexPrefixLoc) != StringRef::npos) { + DiffInLoc += BufferCopy.find("\n", RegexPrefixLoc) - RegexPrefixLoc; + BufferCopy = BufferCopy.drop_front(BufferCopy.find("\n", RegexPrefixLoc)); + } else { + BufferCopy = BufferCopy.drop_front(RegexPrefixLoc); + } + } + } + if (PrefixLoc == StringRef::npos) continue; @@ -1301,6 +1338,10 @@ static void AddCheckPrefixIfNeeded() { if (CheckPrefixes.empty()) CheckPrefixes.push_back("CHECK"); + // Prefix wild-card which will be always matched. + if (RegexPrefixesOn) + if (std::find(CheckPrefixes.begin(), CheckPrefixes.end(), "{{*}}") == CheckPrefixes.end()) + CheckPrefixes.push_back("{{*}}"); } static void DumpCommandLine(int argc, char **argv) {