1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program Tester Core
3 * ----------------------------------------
5 * Copyright 2014 The Android Open Source Project
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
21 * \brief Command line parsing.
22 *//*--------------------------------------------------------------------*/
24 #include "tcuCommandLine.hpp"
25 #include "tcuPlatform.hpp"
26 #include "tcuTestCase.hpp"
27 #include "deFilePath.hpp"
28 #include "deStringUtil.hpp"
31 #include "deCommandLine.h"
32 #include "qpTestLog.h"
33 #include "qpDebugOut.h"
44 // OOM tests are enabled by default only on platforms that don't do memory overcommit (Win32)
45 #if (DE_OS == DE_OS_WIN32)
46 # define TEST_OOM_DEFAULT "enable"
48 # define TEST_OOM_DEFAULT "disable"
57 DE_DECLARE_COMMAND_LINE_OPT(CasePath, std::string);
58 DE_DECLARE_COMMAND_LINE_OPT(CaseList, std::string);
59 DE_DECLARE_COMMAND_LINE_OPT(CaseListFile, std::string);
60 DE_DECLARE_COMMAND_LINE_OPT(StdinCaseList, bool);
61 DE_DECLARE_COMMAND_LINE_OPT(LogFilename, std::string);
62 DE_DECLARE_COMMAND_LINE_OPT(RunMode, tcu::RunMode);
63 DE_DECLARE_COMMAND_LINE_OPT(ExportFilenamePattern, std::string);
64 DE_DECLARE_COMMAND_LINE_OPT(WatchDog, bool);
65 DE_DECLARE_COMMAND_LINE_OPT(CrashHandler, bool);
66 DE_DECLARE_COMMAND_LINE_OPT(BaseSeed, int);
67 DE_DECLARE_COMMAND_LINE_OPT(TestIterationCount, int);
68 DE_DECLARE_COMMAND_LINE_OPT(Visibility, WindowVisibility);
69 DE_DECLARE_COMMAND_LINE_OPT(SurfaceWidth, int);
70 DE_DECLARE_COMMAND_LINE_OPT(SurfaceHeight, int);
71 DE_DECLARE_COMMAND_LINE_OPT(SurfaceType, tcu::SurfaceType);
72 DE_DECLARE_COMMAND_LINE_OPT(ScreenRotation, tcu::ScreenRotation);
73 DE_DECLARE_COMMAND_LINE_OPT(GLContextType, std::string);
74 DE_DECLARE_COMMAND_LINE_OPT(GLConfigID, int);
75 DE_DECLARE_COMMAND_LINE_OPT(GLConfigName, std::string);
76 DE_DECLARE_COMMAND_LINE_OPT(GLContextFlags, std::string);
77 DE_DECLARE_COMMAND_LINE_OPT(CLPlatformID, int);
78 DE_DECLARE_COMMAND_LINE_OPT(CLDeviceIDs, std::vector<int>);
79 DE_DECLARE_COMMAND_LINE_OPT(CLBuildOptions, std::string);
80 DE_DECLARE_COMMAND_LINE_OPT(EGLDisplayType, std::string);
81 DE_DECLARE_COMMAND_LINE_OPT(EGLWindowType, std::string);
82 DE_DECLARE_COMMAND_LINE_OPT(EGLPixmapType, std::string);
83 DE_DECLARE_COMMAND_LINE_OPT(LogImages, bool);
84 DE_DECLARE_COMMAND_LINE_OPT(LogShaderSources, bool);
85 DE_DECLARE_COMMAND_LINE_OPT(TestOOM, bool);
86 DE_DECLARE_COMMAND_LINE_OPT(VKDeviceID, int);
88 static void parseIntList (const char* src, std::vector<int>* dst)
90 std::istringstream str (src);
93 while (std::getline(str, val, ','))
96 de::cmdline::parseType(val.c_str(), &intVal);
97 dst->push_back(intVal);
101 void registerOptions (de::cmdline::Parser& parser)
103 using de::cmdline::Option;
104 using de::cmdline::NamedValue;
106 static const NamedValue<bool> s_enableNames[] =
111 static const NamedValue<tcu::RunMode> s_runModes[] =
113 { "execute", RUNMODE_EXECUTE },
114 { "xml-caselist", RUNMODE_DUMP_XML_CASELIST },
115 { "txt-caselist", RUNMODE_DUMP_TEXT_CASELIST },
116 { "stdout-caselist",RUNMODE_DUMP_STDOUT_CASELIST}
118 static const NamedValue<WindowVisibility> s_visibilites[] =
120 { "windowed", WINDOWVISIBILITY_WINDOWED },
121 { "fullscreen", WINDOWVISIBILITY_FULLSCREEN },
122 { "hidden", WINDOWVISIBILITY_HIDDEN }
124 static const NamedValue<tcu::SurfaceType> s_surfaceTypes[] =
126 { "window", SURFACETYPE_WINDOW },
127 { "pixmap", SURFACETYPE_OFFSCREEN_NATIVE },
128 { "pbuffer", SURFACETYPE_OFFSCREEN_GENERIC },
129 { "fbo", SURFACETYPE_FBO }
131 static const NamedValue<tcu::ScreenRotation> s_screenRotations[] =
133 { "unspecified", SCREENROTATION_UNSPECIFIED },
134 { "0", SCREENROTATION_0 },
135 { "90", SCREENROTATION_90 },
136 { "180", SCREENROTATION_180 },
137 { "270", SCREENROTATION_270 }
141 << Option<CasePath> ("n", "deqp-case", "Test case(s) to run, supports wildcards (e.g. dEQP-GLES2.info.*)")
142 << Option<CaseList> (DE_NULL, "deqp-caselist", "Case list to run in trie format (e.g. {dEQP-GLES2{info{version,renderer}}})")
143 << Option<CaseListFile> (DE_NULL, "deqp-caselist-file", "Read case list (in trie format) from given file")
144 << Option<StdinCaseList> (DE_NULL, "deqp-stdin-caselist", "Read case list (in trie format) from stdin")
145 << Option<LogFilename> (DE_NULL, "deqp-log-filename", "Write test results to given file", "TestResults.qpa")
146 << Option<RunMode> (DE_NULL, "deqp-runmode", "Execute tests, or write list of test cases into a file",
147 s_runModes, "execute")
148 << Option<ExportFilenamePattern>(DE_NULL, "deqp-caselist-export-file", "Set the target file name pattern for caselist export", "${packageName}-cases.${typeExtension}")
149 << Option<WatchDog> (DE_NULL, "deqp-watchdog", "Enable test watchdog", s_enableNames, "disable")
150 << Option<CrashHandler> (DE_NULL, "deqp-crashhandler", "Enable crash handling", s_enableNames, "disable")
151 << Option<BaseSeed> (DE_NULL, "deqp-base-seed", "Base seed for test cases that use randomization", "0")
152 << Option<TestIterationCount> (DE_NULL, "deqp-test-iteration-count", "Iteration count for cases that support variable number of iterations", "0")
153 << Option<Visibility> (DE_NULL, "deqp-visibility", "Default test window visibility", s_visibilites, "windowed")
154 << Option<SurfaceWidth> (DE_NULL, "deqp-surface-width", "Use given surface width if possible", "-1")
155 << Option<SurfaceHeight> (DE_NULL, "deqp-surface-height", "Use given surface height if possible", "-1")
156 << Option<SurfaceType> (DE_NULL, "deqp-surface-type", "Use given surface type", s_surfaceTypes, "window")
157 << Option<ScreenRotation> (DE_NULL, "deqp-screen-rotation", "Screen rotation for platforms that support it", s_screenRotations, "0")
158 << Option<GLContextType> (DE_NULL, "deqp-gl-context-type", "OpenGL context type for platforms that support multiple")
159 << Option<GLConfigID> (DE_NULL, "deqp-gl-config-id", "OpenGL (ES) render config ID (EGL config id on EGL platforms)", "-1")
160 << Option<GLConfigName> (DE_NULL, "deqp-gl-config-name", "Symbolic OpenGL (ES) render config name")
161 << Option<GLContextFlags> (DE_NULL, "deqp-gl-context-flags", "OpenGL context flags (comma-separated, supports debug and robust)")
162 << Option<CLPlatformID> (DE_NULL, "deqp-cl-platform-id", "Execute tests on given OpenCL platform (IDs start from 1)", "1")
163 << Option<CLDeviceIDs> (DE_NULL, "deqp-cl-device-ids", "Execute tests on given CL devices (comma-separated, IDs start from 1)", parseIntList, "")
164 << Option<CLBuildOptions> (DE_NULL, "deqp-cl-build-options", "Extra build options for OpenCL compiler")
165 << Option<EGLDisplayType> (DE_NULL, "deqp-egl-display-type", "EGL native display type")
166 << Option<EGLWindowType> (DE_NULL, "deqp-egl-window-type", "EGL native window type")
167 << Option<EGLPixmapType> (DE_NULL, "deqp-egl-pixmap-type", "EGL native pixmap type")
168 << Option<VKDeviceID> (DE_NULL, "deqp-vk-device-id", "Vulkan device ID (IDs start from 1)", "1")
169 << Option<LogImages> (DE_NULL, "deqp-log-images", "Enable or disable logging of result images", s_enableNames, "enable")
170 << Option<LogShaderSources> (DE_NULL, "deqp-log-shader-sources", "Enable or disable logging of shader sources", s_enableNames, "enable")
171 << Option<TestOOM> (DE_NULL, "deqp-test-oom", "Run tests that exhaust memory on purpose", s_enableNames, TEST_OOM_DEFAULT);
174 void registerLegacyOptions (de::cmdline::Parser& parser)
176 using de::cmdline::Option;
179 << Option<GLConfigID> (DE_NULL, "deqp-egl-config-id", "Legacy name for --deqp-gl-config-id", "-1")
180 << Option<GLConfigName> (DE_NULL, "deqp-egl-config-name", "Legacy name for --deqp-gl-config-name");
185 // \todo [2014-02-13 pyry] This could be useful elsewhere as well.
186 class DebugOutStreambuf : public std::streambuf
189 DebugOutStreambuf (void);
190 ~DebugOutStreambuf (void);
193 std::streamsize xsputn (const char* s, std::streamsize count);
194 int overflow (int ch = -1);
197 void flushLine (void);
199 std::ostringstream m_curLine;
202 DebugOutStreambuf::DebugOutStreambuf (void)
206 DebugOutStreambuf::~DebugOutStreambuf (void)
208 if (m_curLine.tellp() != std::streampos(0))
212 std::streamsize DebugOutStreambuf::xsputn (const char* s, std::streamsize count)
214 for (std::streamsize pos = 0; pos < count; pos++)
216 m_curLine.put(s[pos]);
225 int DebugOutStreambuf::overflow (int ch)
231 DE_ASSERT((ch & 0xff) == ch);
232 const char chVal = (char)(deUint8)(ch & 0xff);
233 return xsputn(&chVal, 1) == 1 ? ch : -1;
237 void DebugOutStreambuf::flushLine (void)
239 qpPrint(m_curLine.str().c_str());
246 CaseTreeNode (const std::string& name) : m_name(name) {}
247 ~CaseTreeNode (void);
249 const std::string& getName (void) const { return m_name; }
250 bool hasChildren (void) const { return !m_children.empty(); }
252 bool hasChild (const std::string& name) const;
253 const CaseTreeNode* getChild (const std::string& name) const;
254 CaseTreeNode* getChild (const std::string& name);
256 void addChild (CaseTreeNode* child) { m_children.push_back(child); }
259 CaseTreeNode (const CaseTreeNode&);
260 CaseTreeNode& operator= (const CaseTreeNode&);
262 enum { NOT_FOUND = -1 };
264 // \todo [2014-10-30 pyry] Speed up with hash / sorting
265 int findChildNdx (const std::string& name) const;
268 std::vector<CaseTreeNode*> m_children;
271 CaseTreeNode::~CaseTreeNode (void)
273 for (vector<CaseTreeNode*>::const_iterator i = m_children.begin(); i != m_children.end(); ++i)
277 int CaseTreeNode::findChildNdx (const std::string& name) const
279 for (int ndx = 0; ndx < (int)m_children.size(); ++ndx)
281 if (m_children[ndx]->getName() == name)
287 inline bool CaseTreeNode::hasChild (const std::string& name) const
289 return findChildNdx(name) != NOT_FOUND;
292 inline const CaseTreeNode* CaseTreeNode::getChild (const std::string& name) const
294 const int ndx = findChildNdx(name);
295 return ndx == NOT_FOUND ? DE_NULL : m_children[ndx];
298 inline CaseTreeNode* CaseTreeNode::getChild (const std::string& name)
300 const int ndx = findChildNdx(name);
301 return ndx == NOT_FOUND ? DE_NULL : m_children[ndx];
304 static int getCurrentComponentLen (const char* path)
307 for (; path[ndx] != 0 && path[ndx] != '.'; ++ndx);
311 static const CaseTreeNode* findNode (const CaseTreeNode* root, const char* path)
313 const CaseTreeNode* curNode = root;
314 const char* curPath = path;
315 int curLen = getCurrentComponentLen(curPath);
319 curNode = curNode->getChild(std::string(curPath, curPath+curLen));
330 DE_ASSERT(curPath[0] == '.');
332 curLen = getCurrentComponentLen(curPath);
339 static void parseCaseTrie (CaseTreeNode* root, std::istream& in)
341 vector<CaseTreeNode*> nodeStack;
343 bool expectNode = true;
346 throw std::invalid_argument("Malformed case trie");
348 nodeStack.push_back(root);
350 while (!nodeStack.empty())
352 const int curChr = in.get();
354 if (curChr == std::char_traits<char>::eof() || curChr == 0)
355 throw std::invalid_argument("Unterminated case tree");
357 if (curChr == '{' || curChr == ',' || curChr == '}')
359 if (!curName.empty() && expectNode)
361 CaseTreeNode* const newChild = new CaseTreeNode(curName);
365 nodeStack.back()->addChild(newChild);
374 nodeStack.push_back(newChild);
378 else if (curName.empty() == expectNode)
379 throw std::invalid_argument(expectNode ? "Empty node name" : "Missing node separator");
384 nodeStack.pop_back();
386 // consume trailing new line
387 if (nodeStack.empty())
389 if (in.peek() == '\r')
391 if (in.peek() == '\n')
398 else if (isValidTestCaseNameChar((char)curChr))
399 curName += (char)curChr;
401 throw std::invalid_argument("Illegal character in node name");
405 static void parseCaseList (CaseTreeNode* root, std::istream& in)
407 // \note Algorithm assumes that cases are sorted by groups, but will
408 // function fine, albeit more slowly, if that is not the case.
409 vector<CaseTreeNode*> nodeStack;
413 nodeStack.resize(8, DE_NULL);
419 const int curChr = in.get();
421 if (curChr == std::char_traits<char>::eof() || curChr == 0 || curChr == '\n' || curChr == '\r')
424 throw std::invalid_argument("Empty test case name");
426 if (nodeStack[stackPos]->hasChild(curName))
427 throw std::invalid_argument("Duplicate test case");
429 CaseTreeNode* const newChild = new CaseTreeNode(curName);
433 nodeStack[stackPos]->addChild(newChild);
444 if (curChr == '\r' && in.peek() == '\n')
448 const int nextChr = in.peek();
450 if (nextChr == std::char_traits<char>::eof() || nextChr == 0)
454 else if (curChr == '.')
457 throw std::invalid_argument("Empty test group name");
459 if ((int)nodeStack.size() <= stackPos+1)
460 nodeStack.resize(nodeStack.size()*2, DE_NULL);
462 if (!nodeStack[stackPos+1] || nodeStack[stackPos+1]->getName() != curName)
464 CaseTreeNode* curGroup = nodeStack[stackPos]->getChild(curName);
468 curGroup = new CaseTreeNode(curName);
472 nodeStack[stackPos]->addChild(curGroup);
481 nodeStack[stackPos+1] = curGroup;
483 if ((int)nodeStack.size() > stackPos+2)
484 nodeStack[stackPos+2] = DE_NULL; // Invalidate rest of entries
487 DE_ASSERT(nodeStack[stackPos+1]->getName() == curName);
492 else if (isValidTestCaseNameChar((char)curChr))
493 curName += (char)curChr;
495 throw std::invalid_argument("Illegal character in test case name");
499 static CaseTreeNode* parseCaseList (std::istream& in)
501 CaseTreeNode* const root = new CaseTreeNode("");
504 if (in.peek() == '{')
505 parseCaseTrie(root, in);
507 parseCaseList(root, in);
510 const int curChr = in.get();
511 if (curChr != std::char_traits<char>::eof() && curChr != 0)
512 throw std::invalid_argument("Trailing characters at end of case list");
527 CasePaths (const string& pathList);
528 bool matches (const string& caseName, bool allowPrefix=false) const;
531 const vector<string> m_casePatterns;
534 CasePaths::CasePaths (const string& pathList)
535 : m_casePatterns(de::splitString(pathList, ','))
539 // Match a single path component against a pattern component that may contain *-wildcards.
540 static bool matchWildcards(string::const_iterator patternStart,
541 string::const_iterator patternEnd,
542 string::const_iterator pathStart,
543 string::const_iterator pathEnd,
546 string::const_iterator pattern = patternStart;
547 string::const_iterator path = pathStart;
549 while (pattern != patternEnd && path != pathEnd && *pattern == *path)
555 if (pattern == patternEnd)
556 return (path == pathEnd);
557 else if (*pattern == '*')
559 for (; path != pathEnd; ++path)
561 if (matchWildcards(pattern + 1, patternEnd, path, pathEnd, allowPrefix))
565 if (matchWildcards(pattern + 1, patternEnd, pathEnd, pathEnd, allowPrefix))
568 else if (path == pathEnd && allowPrefix)
574 #if defined(TCU_HIERARCHICAL_CASEPATHS)
575 // Match a list of pattern components to a list of path components. A pattern
576 // component may contain *-wildcards. A pattern component "**" matches zero or
577 // more whole path components.
578 static bool patternMatches(vector<string>::const_iterator patternStart,
579 vector<string>::const_iterator patternEnd,
580 vector<string>::const_iterator pathStart,
581 vector<string>::const_iterator pathEnd,
584 vector<string>::const_iterator pattern = patternStart;
585 vector<string>::const_iterator path = pathStart;
587 while (pattern != patternEnd && path != pathEnd && *pattern != "**" &&
588 (*pattern == *path || matchWildcards(pattern->begin(), pattern->end(),
589 path->begin(), path->end(), false)))
595 if (path == pathEnd && (allowPrefix || pattern == patternEnd))
597 else if (pattern != patternEnd && *pattern == "**")
599 for (; path != pathEnd; ++path)
600 if (patternMatches(pattern + 1, patternEnd, path, pathEnd, allowPrefix))
602 if (patternMatches(pattern + 1, patternEnd, path, pathEnd, allowPrefix))
610 bool CasePaths::matches (const string& caseName, bool allowPrefix) const
612 const vector<string> components = de::splitString(caseName, '.');
614 for (size_t ndx = 0; ndx < m_casePatterns.size(); ++ndx)
616 #if defined(TCU_HIERARCHICAL_CASEPATHS)
617 const vector<string> patternComponents = de::splitString(m_casePatterns[ndx], '.');
619 if (patternMatches(patternComponents.begin(), patternComponents.end(),
620 components.begin(), components.end(), allowPrefix))
623 if (matchWildcards(m_casePatterns[ndx].begin(), m_casePatterns[ndx].end(),
624 caseName.begin(), caseName.end(), allowPrefix))
632 /*--------------------------------------------------------------------*//*!
633 * \brief Construct command line
634 * \note CommandLine is not fully initialized until parse() has been called.
635 *//*--------------------------------------------------------------------*/
636 CommandLine::CommandLine (void)
638 , m_caseTree (DE_NULL)
642 /*--------------------------------------------------------------------*//*!
643 * \brief Construct command line from standard argc, argv pair.
645 * Calls parse() with given arguments
646 * \param argc Number of arguments
647 * \param argv Command line arguments
648 *//*--------------------------------------------------------------------*/
649 CommandLine::CommandLine (int argc, const char* const* argv)
651 , m_caseTree (DE_NULL)
653 if (!parse(argc, argv))
654 throw Exception("Failed to parse command line");
657 /*--------------------------------------------------------------------*//*!
658 * \brief Construct command line from string.
660 * Calls parse() with given argument.
661 * \param cmdLine Full command line string.
662 *//*--------------------------------------------------------------------*/
663 CommandLine::CommandLine (const std::string& cmdLine)
665 , m_caseTree (DE_NULL)
668 throw Exception("Failed to parse command line");
671 CommandLine::~CommandLine (void)
676 void CommandLine::clear (void)
682 m_caseTree = DE_NULL;
685 const de::cmdline::CommandLine& CommandLine::getCommandLine (void) const
690 void CommandLine::registerExtendedOptions (de::cmdline::Parser& parser)
695 /*--------------------------------------------------------------------*//*!
696 * \brief Parse command line from standard argc, argv pair.
697 * \note parse() must be called exactly once.
698 * \param argc Number of arguments
699 * \param argv Command line arguments
700 *//*--------------------------------------------------------------------*/
701 bool CommandLine::parse (int argc, const char* const* argv)
703 DebugOutStreambuf sbuf;
704 std::ostream debugOut (&sbuf);
705 de::cmdline::Parser parser;
707 opt::registerOptions(parser);
708 opt::registerLegacyOptions(parser);
709 registerExtendedOptions(parser);
713 if (!parser.parse(argc-1, argv+1, &m_cmdLine, std::cerr))
715 debugOut << "\n" << de::FilePath(argv[0]).getBaseName() << " [options]\n\n";
716 parser.help(debugOut);
722 if (!m_cmdLine.getOption<opt::LogImages>())
723 m_logFlags |= QP_TEST_LOG_EXCLUDE_IMAGES;
725 if (!m_cmdLine.getOption<opt::LogShaderSources>())
726 m_logFlags |= QP_TEST_LOG_EXCLUDE_SHADER_SOURCES;
728 if ((m_cmdLine.hasOption<opt::CasePath>()?1:0) +
729 (m_cmdLine.hasOption<opt::CaseList>()?1:0) +
730 (m_cmdLine.hasOption<opt::CaseListFile>()?1:0) +
731 (m_cmdLine.getOption<opt::StdinCaseList>()?1:0) > 1)
733 debugOut << "ERROR: multiple test case list options given!\n" << std::endl;
740 if (m_cmdLine.hasOption<opt::CaseList>())
742 std::istringstream str(m_cmdLine.getOption<opt::CaseList>());
744 m_caseTree = parseCaseList(str);
746 else if (m_cmdLine.hasOption<opt::CaseListFile>())
748 std::ifstream in(m_cmdLine.getOption<opt::CaseListFile>().c_str(), std::ios_base::binary);
750 if (!in.is_open() || !in.good())
751 throw Exception("Failed to open case list file '" + m_cmdLine.getOption<opt::CaseListFile>() + "'");
753 m_caseTree = parseCaseList(in);
755 else if (m_cmdLine.getOption<opt::StdinCaseList>())
757 m_caseTree = parseCaseList(std::cin);
759 else if (m_cmdLine.hasOption<opt::CasePath>())
760 m_casePaths = de::MovePtr<const CasePaths>(new CasePaths(m_cmdLine.getOption<opt::CasePath>()));
762 catch (const std::exception& e)
764 debugOut << "ERROR: Failed to parse test case list: " << e.what() << "\n";
772 /*--------------------------------------------------------------------*//*!
773 * \brief Parse command line from string.
774 * \note parse() must be called exactly once.
775 * \param cmdLine Full command line string.
776 *//*--------------------------------------------------------------------*/
777 bool CommandLine::parse (const std::string& cmdLine)
779 deCommandLine* parsedCmdLine = deCommandLine_parse(cmdLine.c_str());
781 throw std::bad_alloc();
786 isOk = parse(parsedCmdLine->numArgs, parsedCmdLine->args);
790 deCommandLine_destroy(parsedCmdLine);
794 deCommandLine_destroy(parsedCmdLine);
798 const char* CommandLine::getLogFileName (void) const { return m_cmdLine.getOption<opt::LogFilename>().c_str(); }
799 deUint32 CommandLine::getLogFlags (void) const { return m_logFlags; }
800 RunMode CommandLine::getRunMode (void) const { return m_cmdLine.getOption<opt::RunMode>(); }
801 const char* CommandLine::getCaseListExportFile (void) const { return m_cmdLine.getOption<opt::ExportFilenamePattern>().c_str(); }
802 WindowVisibility CommandLine::getVisibility (void) const { return m_cmdLine.getOption<opt::Visibility>(); }
803 bool CommandLine::isWatchDogEnabled (void) const { return m_cmdLine.getOption<opt::WatchDog>(); }
804 bool CommandLine::isCrashHandlingEnabled (void) const { return m_cmdLine.getOption<opt::CrashHandler>(); }
805 int CommandLine::getBaseSeed (void) const { return m_cmdLine.getOption<opt::BaseSeed>(); }
806 int CommandLine::getTestIterationCount (void) const { return m_cmdLine.getOption<opt::TestIterationCount>(); }
807 int CommandLine::getSurfaceWidth (void) const { return m_cmdLine.getOption<opt::SurfaceWidth>(); }
808 int CommandLine::getSurfaceHeight (void) const { return m_cmdLine.getOption<opt::SurfaceHeight>(); }
809 SurfaceType CommandLine::getSurfaceType (void) const { return m_cmdLine.getOption<opt::SurfaceType>(); }
810 ScreenRotation CommandLine::getScreenRotation (void) const { return m_cmdLine.getOption<opt::ScreenRotation>(); }
811 int CommandLine::getGLConfigId (void) const { return m_cmdLine.getOption<opt::GLConfigID>(); }
812 int CommandLine::getCLPlatformId (void) const { return m_cmdLine.getOption<opt::CLPlatformID>(); }
813 const std::vector<int>& CommandLine::getCLDeviceIds (void) const { return m_cmdLine.getOption<opt::CLDeviceIDs>(); }
814 int CommandLine::getVKDeviceId (void) const { return m_cmdLine.getOption<opt::VKDeviceID>(); }
815 bool CommandLine::isOutOfMemoryTestEnabled (void) const { return m_cmdLine.getOption<opt::TestOOM>(); }
817 const char* CommandLine::getGLContextType (void) const
819 if (m_cmdLine.hasOption<opt::GLContextType>())
820 return m_cmdLine.getOption<opt::GLContextType>().c_str();
824 const char* CommandLine::getGLConfigName (void) const
826 if (m_cmdLine.hasOption<opt::GLConfigName>())
827 return m_cmdLine.getOption<opt::GLConfigName>().c_str();
832 const char* CommandLine::getGLContextFlags (void) const
834 if (m_cmdLine.hasOption<opt::GLContextFlags>())
835 return m_cmdLine.getOption<opt::GLContextFlags>().c_str();
840 const char* CommandLine::getCLBuildOptions (void) const
842 if (m_cmdLine.hasOption<opt::CLBuildOptions>())
843 return m_cmdLine.getOption<opt::CLBuildOptions>().c_str();
848 const char* CommandLine::getEGLDisplayType (void) const
850 if (m_cmdLine.hasOption<opt::EGLDisplayType>())
851 return m_cmdLine.getOption<opt::EGLDisplayType>().c_str();
856 const char* CommandLine::getEGLWindowType (void) const
858 if (m_cmdLine.hasOption<opt::EGLWindowType>())
859 return m_cmdLine.getOption<opt::EGLWindowType>().c_str();
864 const char* CommandLine::getEGLPixmapType (void) const
866 if (m_cmdLine.hasOption<opt::EGLPixmapType>())
867 return m_cmdLine.getOption<opt::EGLPixmapType>().c_str();
872 static bool checkTestGroupName (const CaseTreeNode* root, const char* groupPath)
874 const CaseTreeNode* node = findNode(root, groupPath);
875 return node && node->hasChildren();
878 static bool checkTestCaseName (const CaseTreeNode* root, const char* casePath)
880 const CaseTreeNode* node = findNode(root, casePath);
881 return node && !node->hasChildren();
884 bool CommandLine::checkTestGroupName (const char* groupName) const
887 return m_casePaths->matches(groupName, true);
889 return groupName[0] == 0 || tcu::checkTestGroupName(m_caseTree, groupName);
894 bool CommandLine::checkTestCaseName (const char* caseName) const
897 return m_casePaths->matches(caseName, false);
899 return tcu::checkTestCaseName(m_caseTree, caseName);