summaryrefslogtreecommitdiff
path: root/tools/slang-test/slang-test-main.cpp
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2021-02-03 16:31:58 -0500
committerGitHub <noreply@github.com>2021-02-03 16:31:58 -0500
commit4c66c17b2e5572c95da260ea4761f5804eb52853 (patch)
tree198a2f7aeffb17d3a87fbe6223e1d8df32287562 /tools/slang-test/slang-test-main.cpp
parenta1d543d9b1bf3b2bcd813a498d2d3e24de67106d (diff)
Diagnostic comparison using parsing (#1683)
* #include an absolute path didn't work - because paths were taken to always be relative. * WIP diagnostics for line number output. * Small param naming change * Use x macro for pass through compile human name lookup/getting. * WIP on parsing downstream compiler output. * Split out parsing into ParseDiagnosticUtil. Added test result of single line. * Dump out the std output on fail to parse diagnostics. * Change test type for syntax-error-intrinsic.slang be TEST not TEST_DIAGNOSTIC * Use Index for StringUtil. * WIP: First pass support for parsing Slang diagnostics. * WIP Testing comparing with ParseDiagnosticUtil with previous ad-hoc mechanism. * Use the new parsing mechanism for diagnostic comparisons. * Improvements to diagnostics parsing. Better error handling, and fallback handling. Added ability to parse downstream compilers without a prefix. Added ability to parse Slang with a prefix.
Diffstat (limited to 'tools/slang-test/slang-test-main.cpp')
-rw-r--r--tools/slang-test/slang-test-main.cpp115
1 files changed, 12 insertions, 103 deletions
diff --git a/tools/slang-test/slang-test-main.cpp b/tools/slang-test/slang-test-main.cpp
index fcb609c34..e7e882ad4 100644
--- a/tools/slang-test/slang-test-main.cpp
+++ b/tools/slang-test/slang-test-main.cpp
@@ -1028,120 +1028,29 @@ static SlangResult _executeBinary(const UnownedStringSlice& hexDump, ExecuteResu
return ProcessUtil::execute(cmdLine, outExeRes);
}
-static UnownedStringSlice _removeDiagnosticPrefix(const UnownedStringSlice& prefix, const UnownedStringSlice& in)
-{
- SLANG_ASSERT(in.startsWith(prefix));
-
- UnownedStringSlice remaining(in.begin() + prefix.getLength(), in.end());
- const Index index = remaining.indexOf(':');
-
- if (index >= 0)
- {
- // Ok strip everything before the colon
- return UnownedStringSlice(remaining.begin() + index, remaining.end());
- }
- else
- {
- // Couldn't strip, just return the whole string as is
- return in;
- }
-}
-
-static bool _isUnsignedInteger(const UnownedStringSlice& a)
-{
- const char* end = a.end();
- for (const char* cur = a.begin(); cur < end; ++cur)
- {
- if (!(*cur >= '0' && *cur <= '9'))
- {
- return false;
- }
- }
- return true;
-}
-
-static bool _isDXCLineSplitEqual(const UnownedStringSlice& a, const UnownedStringSlice& b)
-{
- return a == b || (_isUnsignedInteger(a.trim()) && _isUnsignedInteger(b.trim()));
-}
-
-// Returns true if a and b are output from dxc (prefixed with dxc:.
-// Ignores line number/column number differences from the dxc specific line format.
-static bool _isDXCLineEqual(const UnownedStringSlice& a, const UnownedStringSlice& b)
-{
- // We are going to ignore the line number/column number.
- // To do this if we find any sub strings inbetween : that are just all digits we'll assume it's a line number/column number
- // and ignore
-
- // dxc: tests/cross-compile/dxc-error.hlsl:9:2: error: use of undeclared identifier 'gOutputBuffer'
- const UnownedStringSlice dxcPrefix = UnownedStringSlice::fromLiteral("dxc:");
- return a.startsWith(dxcPrefix) && b.startsWith(dxcPrefix) && StringUtil::areAllEqualWithSplit(a, b, ':', _isDXCLineSplitEqual);
-}
-
-static bool _isLineEqual(const UnownedStringSlice& a, const UnownedStringSlice& b)
-{
- if (a == b)
- {
- return true;
- }
-
- static const UnownedStringSlice stdLibNames[] =
- {
- UnownedStringSlice::fromLiteral("core.meta.slang"),
- UnownedStringSlice::fromLiteral("hlsl.meta.slang"),
- UnownedStringSlice::fromLiteral("slang-stdlib.cpp"),
- };
-
- // Look for if a line starts with a stdlib name
- for (const auto& stdLibName : stdLibNames)
- {
- if (a.startsWith(stdLibName) && b.startsWith(stdLibName))
- {
- // If the text after the diagnostic prefix is equal then the line is equal
- if (_removeDiagnosticPrefix(stdLibName, a) == _removeDiagnosticPrefix(stdLibName, b))
- {
- return true;
- }
- }
- }
-
- return _isDXCLineEqual(a, b);
-}
-
static bool _areDiagnosticsEqual(const UnownedStringSlice& a, const UnownedStringSlice& b)
{
- // If they are identical we are done
- if (a == b)
- {
- return true;
- }
-
- // Okay we are going to go line by line
- // If the lines are equal thats ok.
- // If they are not.. we will check if the only difference is line numbers from the stdlib
-
- List<UnownedStringSlice> linesA;
- List<UnownedStringSlice> linesB;
-
- StringUtil::calcLines(a, linesA);
- StringUtil::calcLines(b, linesB);
+ ParseDiagnosticUtil::OutputInfo outA, outB;
- if (linesA.getCount() != linesB.getCount())
+ // If we can't parse, we can't match, so fail.
+ if (SLANG_FAILED(ParseDiagnosticUtil::parseOutputInfo(a, outA)) ||
+ SLANG_FAILED(ParseDiagnosticUtil::parseOutputInfo(b, outB)))
{
return false;
}
- for (Index i = 0; i < linesA.getCount(); ++i)
+ // The result codes must match, and std out
+ if (outA.resultCode != outB.resultCode ||
+ !StringUtil::areLinesEqual(outA.stdOut.getUnownedSlice(), outB.stdOut.getUnownedSlice()))
{
- if (!_isLineEqual(linesA[i], linesB[i]))
- {
- return false;
- }
+ return false;
}
- return true;
+ // Parse the compiler diagnostics and make sure they are the same.
+ // Ignores line number differences
+ return ParseDiagnosticUtil::areEqual(outA.stdError.getUnownedSlice(), outB.stdError.getUnownedSlice(), ParseDiagnosticUtil::EqualityFlag::IgnoreLineNos);
}
-
+
static bool _areResultsEqual(TestOptions::Type type, const String& a, const String& b)
{
switch (type)