summaryrefslogtreecommitdiffstats
path: root/tools/slang-test/options.cpp
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2018-12-14 15:24:21 -0500
committerGitHub <noreply@github.com>2018-12-14 15:24:21 -0500
commitd43c566fa29bbc0da1534aea236d54ee5ca104b8 (patch)
tree5a1878687364d28361a2c6aa722c5c8d9c75810e /tools/slang-test/options.cpp
parentec745c032a8dc16c3e689458c20541a4e7aa64d6 (diff)
Fix memory leaks around slang-test (#757)
* Remove circular reference to renderer on Vk & D3D12 DescriptorSetImpl * Refactor Stbi image loading such that memory is correctly freed when goes out of scope. Added Crt memory dump at termination. Reduced erroneous reporting by scoping TestContext. * Used capitalized acronym for STBImage to keep Tim happy. * Split out TestReporter - to just handle reporting test results Split out Options Made TestContext hold options, and the reporter Removed remaining memory leaks. * Small optimization for rawWrite, such that it directly writes over print.. * Improve comments on TestCategorySet * Fix typos in TestCategorySet
Diffstat (limited to 'tools/slang-test/options.cpp')
-rw-r--r--tools/slang-test/options.cpp245
1 files changed, 245 insertions, 0 deletions
diff --git a/tools/slang-test/options.cpp b/tools/slang-test/options.cpp
new file mode 100644
index 000000000..cb6adbc6f
--- /dev/null
+++ b/tools/slang-test/options.cpp
@@ -0,0 +1,245 @@
+// test-context.cpp
+#include "options.h"
+
+#include "os.h"
+#include "../../source/core/slang-string-util.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+using namespace Slang;
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! CategorySet !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
+TestCategory* TestCategorySet::add(String const& name, TestCategory* parent)
+{
+ RefPtr<TestCategory> category(new TestCategory);
+ category->name = name;
+ category->parent = parent;
+
+ m_categoryMap.Add(name, category);
+ return category;
+}
+
+TestCategory* TestCategorySet::find(String const& name)
+{
+ RefPtr<TestCategory> category;
+ if (!m_categoryMap.TryGetValue(name, category))
+ {
+ return nullptr;
+ }
+ return category;
+}
+
+TestCategory* TestCategorySet::findOrError(String const& name)
+{
+ TestCategory* category = find(name);
+ if (!category)
+ {
+ AppContext::getStdError().print("error: unknown test category name '%s'\n", name.Buffer());
+ }
+ return category;
+}
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! Options !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
+/* static */Result Options::parse(int argc, char** argv, TestCategorySet* categorySet, Slang::WriterHelper stdError, Options* optionsOut)
+{
+ // Reset the options
+ *optionsOut = Options();
+
+ List<const char*> positionalArgs;
+
+ int argCount = argc;
+ char const* const* argCursor = argv;
+ char const* const* argEnd = argCursor + argCount;
+
+ // first argument is the application name
+ if (argCursor != argEnd)
+ {
+ optionsOut->appName = *argCursor++;
+ }
+
+ // now iterate over arguments to collect options
+ while (argCursor != argEnd)
+ {
+ char const* arg = *argCursor++;
+ if (arg[0] != '-')
+ {
+ positionalArgs.Add(arg);
+ continue;
+ }
+
+ if (strcmp(arg, "--") == 0)
+ {
+ while (argCursor != argEnd)
+ {
+ positionalArgs.Add(*argCursor++);
+ }
+ break;
+ }
+
+ if (strcmp(arg, "-bindir") == 0)
+ {
+ if (argCursor == argEnd)
+ {
+ stdError.print("error: expected operand for '%s'\n", arg);
+ return SLANG_FAIL;
+ }
+ optionsOut->binDir = *argCursor++;
+ }
+ else if (strcmp(arg, "-useexes") == 0)
+ {
+ optionsOut->useExes = true;
+ }
+ else if (strcmp(arg, "-v") == 0)
+ {
+ optionsOut->shouldBeVerbose = true;
+ }
+ else if (strcmp(arg, "-generate-hlsl-baselines") == 0)
+ {
+ optionsOut->generateHLSLBaselines = true;
+ }
+ else if (strcmp(arg, "-release") == 0)
+ {
+ // Assumed to be handle by .bat file that called us
+ }
+ else if (strcmp(arg, "-debug") == 0)
+ {
+ // Assumed to be handle by .bat file that called us
+ }
+ else if (strcmp(arg, "-configuration") == 0)
+ {
+ if (argCursor == argEnd)
+ {
+ stdError.print("error: expected operand for '%s'\n", arg);
+ return SLANG_FAIL;
+ }
+ argCursor++;
+ // Assumed to be handle by .bat file that called us
+ }
+ else if (strcmp(arg, "-platform") == 0)
+ {
+ if (argCursor == argEnd)
+ {
+ stdError.print("error: expected operand for '%s'\n", arg);
+ return SLANG_FAIL;
+ }
+ argCursor++;
+ // Assumed to be handle by .bat file that called us
+ }
+ else if (strcmp(arg, "-appveyor") == 0)
+ {
+ optionsOut->outputMode = TestOutputMode::AppVeyor;
+ optionsOut->dumpOutputOnFailure = true;
+ }
+ else if (strcmp(arg, "-travis") == 0)
+ {
+ optionsOut->outputMode = TestOutputMode::Travis;
+ optionsOut->dumpOutputOnFailure = true;
+ }
+ else if (strcmp(arg, "-xunit") == 0)
+ {
+ optionsOut->outputMode = TestOutputMode::XUnit;
+ }
+ else if (strcmp(arg, "-xunit2") == 0)
+ {
+ optionsOut->outputMode = TestOutputMode::XUnit2;
+ }
+ else if (strcmp(arg, "-teamcity") == 0)
+ {
+ optionsOut->outputMode = TestOutputMode::TeamCity;
+ }
+ else if (strcmp(arg, "-category") == 0)
+ {
+ if (argCursor == argEnd)
+ {
+ stdError.print("error: expected operand for '%s'\n", arg);
+ return SLANG_FAIL;
+ }
+ auto category = categorySet->findOrError(*argCursor++);
+ if (category)
+ {
+ optionsOut->includeCategories.Add(category, category);
+ }
+ }
+ else if (strcmp(arg, "-exclude") == 0)
+ {
+ if (argCursor == argEnd)
+ {
+ stdError.print("error: expected operand for '%s'\n", arg);
+ return SLANG_FAIL;
+ }
+ auto category = categorySet->findOrError(*argCursor++);
+ if (category)
+ {
+ optionsOut->excludeCategories.Add(category, category);
+ }
+ }
+ else if (strcmp(arg, "-api") == 0)
+ {
+ if (argCursor == argEnd)
+ {
+ stdError.print("error: expecting an api expression (eg 'vk+dx12' or '+dx11') '%s'\n", arg);
+ return SLANG_FAIL;
+ }
+ const char* apiList = *argCursor++;
+
+ SlangResult res = RenderApiUtil::parseApiFlags(UnownedStringSlice(apiList), optionsOut->enabledApis, &optionsOut->enabledApis);
+ if (SLANG_FAILED(res))
+ {
+ stdError.print("error: unable to parse api expression '%s'\n", apiList);
+ return res;
+ }
+ }
+ else if (strcmp(arg, "-synthesizedTestApi") == 0)
+ {
+ if (argCursor == argEnd)
+ {
+ stdError.print("error: expected an api expression (eg 'vk+dx12' or '+dx11') '%s'\n", arg);
+ return SLANG_FAIL;
+ }
+ const char* apiList = *argCursor++;
+
+ SlangResult res = RenderApiUtil::parseApiFlags(UnownedStringSlice(apiList), optionsOut->synthesizedTestApis, &optionsOut->synthesizedTestApis);
+ if (SLANG_FAILED(res))
+ {
+ stdError.print("error: unable to parse api expression '%s'\n", apiList);
+ return res;
+ }
+ }
+ else
+ {
+ stdError.print("unknown option '%s'\n", arg);
+ return SLANG_FAIL;
+ }
+ }
+
+ {
+ // Find out what apis are available
+ const int availableApis = RenderApiUtil::getAvailableApis();
+ // Only allow apis we know are available
+ optionsOut->enabledApis &= availableApis;
+
+ // Can only synth for apis that are available
+ optionsOut->synthesizedTestApis &= optionsOut->enabledApis;
+ }
+
+
+ // first positional argument is source shader path
+ if (positionalArgs.Count())
+ {
+ optionsOut->testPrefix = positionalArgs[0];
+ positionalArgs.RemoveAt(0);
+ }
+
+ // any remaining arguments represent an error
+ if (positionalArgs.Count() != 0)
+ {
+ stdError.print("unexpected arguments\n");
+ return SLANG_FAIL;
+ }
+
+ return SLANG_OK;
+}