diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2018-07-25 11:57:44 -0400 |
|---|---|---|
| committer | Tim Foley <tfoleyNV@users.noreply.github.com> | 2018-07-25 08:57:44 -0700 |
| commit | dff216cc5ddb073e5bffdd4550eda208b7527676 (patch) | |
| tree | 938d28c2659765ef1d6e28acf58b77e8318974f8 /tools/slang-test/render-api-util.cpp | |
| parent | 990ed7383ef1d3311dfc1023785d2dc18cca5171 (diff) | |
Improved command line control for apis and synthesized tests (#616)
* Parsing of control of api parameters no longer needs comma separator.
Parsing of API list now can take an initial state.
Document the command line option.
* * Proper handling of 'default' (or initialFlags) - by using if the first token is an operator.
* Clarified parsing of api flags.
* Now 'vk' will mean just use vk. +vk will mean the defaults plus vk, and -vk is the defaults -vk.
* Improve README.md on api expressions.
Improve error text for failure to parse api expressions.
Diffstat (limited to 'tools/slang-test/render-api-util.cpp')
| -rw-r--r-- | tools/slang-test/render-api-util.cpp | 134 |
1 files changed, 105 insertions, 29 deletions
diff --git a/tools/slang-test/render-api-util.cpp b/tools/slang-test/render-api-util.cpp index 5f47f3b49..06a915df8 100644 --- a/tools/slang-test/render-api-util.cpp +++ b/tools/slang-test/render-api-util.cpp @@ -59,66 +59,142 @@ static int _calcAvailableApis() return RenderApiType::Unknown; } -/* static */int RenderApiUtil::findApiFlagsByName(const Slang::UnownedStringSlice& name) +/* static */ Slang::Result RenderApiUtil::findApiFlagsByName(const Slang::UnownedStringSlice& name, RenderApiFlags* flagsOut) { // Special case 'all' if (name == "all") { - return int(RenderApiFlag::AllOf); + *flagsOut = RenderApiFlags(RenderApiFlag::AllOf); + return SLANG_OK; + } + if (name == "none") + { + *flagsOut = RenderApiFlags(0); + return SLANG_OK; } RenderApiType type = findApiTypeByName(name); - return (type == RenderApiType::Unknown) ? 0 : (1 << int(type)); + if (type == RenderApiType::Unknown) + { + return SLANG_FAIL; + } + *flagsOut = RenderApiFlags(1) << int(type); + return SLANG_OK; } -/* static */Slang::Result RenderApiUtil::parseApiFlags(const Slang::UnownedStringSlice& text, int* apiBitsOut) +static bool isNameStartChar(char c) +{ + return (c >= 'a' && c <='z') || (c >= 'A' && c <= 'Z') || (c == '_'); +} + +static bool isNameNextChar(char c) +{ + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_') || (c >= '0' && c <= '9'); +} + +namespace { // anonymous +enum class Token +{ + eError, + eOp, + eId, + eEnd, +}; +} + +static Token nextToken(Slang::UnownedStringSlice& textInOut, Slang::UnownedStringSlice& lexemeOut) { using namespace Slang; + if (textInOut.size() <= 0) + { + return Token::eEnd; + } + const char* start = textInOut.begin(); + const char* end = textInOut.end(); + + const char firstChar = start[0]; + if (firstChar == '-' || firstChar == '+') + { + lexemeOut = UnownedStringSlice(start, start + 1); + textInOut = UnownedStringSlice(start + 1, end); + return Token::eOp; + } + + if (!isNameStartChar(firstChar)) + { + lexemeOut = UnownedStringSlice(start, start + 1); + return Token::eError; + } + const char* cur = start + 1; + while (cur < end && isNameNextChar(*cur)) + { + cur++; + } - int apiBits = 0; + lexemeOut = UnownedStringSlice(start, cur); + textInOut = UnownedStringSlice(cur, end); + return Token::eId; +} - List<UnownedStringSlice> slices; - StringUtil::split(text, ',', slices); +/* static */Slang::Result RenderApiUtil::parseApiFlags(const Slang::UnownedStringSlice& textIn, RenderApiFlags initialFlags, RenderApiFlags* apiFlagsOut) +{ + using namespace Slang; - for (int i = 0; i < int(slices.Count()); ++i) + UnownedStringSlice text(textIn); + UnownedStringSlice lexeme; + + RenderApiFlags apiFlags = 0; + + switch (nextToken(text, lexeme)) { - UnownedStringSlice slice = slices[i]; - bool add = true; - if (slice.size() <= 0) + case Token::eOp: { - return SLANG_FAIL; + // If we start with an op - we use the passed in values as the default + // Rewind back to the start + text = textIn; + apiFlags = initialFlags; + break; } - if (slice[0] == '+') + case Token::eId: { - // Drop the + - slice = UnownedStringSlice(slice.begin() + 1, slice.end()); + // If we start with an Id - we use that as the starting state + SLANG_RETURN_ON_FAIL(findApiFlagsByName(lexeme, &apiFlags)); + break; } - else if (slice[0] == '-') + default: return SLANG_FAIL; + } + + while (true) + { + // Must have an op followed by an id unless we are at the end + switch (nextToken(text, lexeme)) { - add = false; - // Drop the + - slice = UnownedStringSlice(slice.begin() + 1, slice.end()); + case Token::eEnd: + { + *apiFlagsOut = apiFlags; + return SLANG_OK; + } + case Token::eOp: break; + default: return SLANG_FAIL; } - // We need to find the bits... - int bits = findApiFlagsByName(slice); - // 0 means an error - if (bits == 0) + const char op = lexeme[0]; + if (nextToken(text, lexeme) != Token::eId) { return SLANG_FAIL; } - if (add) + RenderApiFlags flags; + SLANG_RETURN_ON_FAIL(findApiFlagsByName(lexeme, &flags)); + + if (op == '+') { - apiBits |= bits; + apiFlags |= flags; } else { - apiBits &= ~bits; + apiFlags &= ~flags; } } - - *apiBitsOut = apiBits; - return SLANG_OK; } /* !!!!!!!!!!!!!!!!!!!!!!!!!!!! Platform specific stuff !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ |
