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);
87 DE_DECLARE_COMMAND_LINE_OPT(LogFlush, bool);
89 static void parseIntList (const char* src, std::vector<int>* dst)
91 std::istringstream str (src);
94 while (std::getline(str, val, ','))
97 de::cmdline::parseType(val.c_str(), &intVal);
98 dst->push_back(intVal);
102 void registerOptions (de::cmdline::Parser& parser)
104 using de::cmdline::Option;
105 using de::cmdline::NamedValue;
107 static const NamedValue<bool> s_enableNames[] =
112 static const NamedValue<tcu::RunMode> s_runModes[] =
114 { "execute", RUNMODE_EXECUTE },
115 { "xml-caselist", RUNMODE_DUMP_XML_CASELIST },
116 { "txt-caselist", RUNMODE_DUMP_TEXT_CASELIST },
117 { "stdout-caselist",RUNMODE_DUMP_STDOUT_CASELIST}
119 static const NamedValue<WindowVisibility> s_visibilites[] =
121 { "windowed", WINDOWVISIBILITY_WINDOWED },
122 { "fullscreen", WINDOWVISIBILITY_FULLSCREEN },
123 { "hidden", WINDOWVISIBILITY_HIDDEN }
125 static const NamedValue<tcu::SurfaceType> s_surfaceTypes[] =
127 { "window", SURFACETYPE_WINDOW },
128 { "pixmap", SURFACETYPE_OFFSCREEN_NATIVE },
129 { "pbuffer", SURFACETYPE_OFFSCREEN_GENERIC },
130 { "fbo", SURFACETYPE_FBO }
132 static const NamedValue<tcu::ScreenRotation> s_screenRotations[] =
134 { "unspecified", SCREENROTATION_UNSPECIFIED },
135 { "0", SCREENROTATION_0 },
136 { "90", SCREENROTATION_90 },
137 { "180", SCREENROTATION_180 },
138 { "270", SCREENROTATION_270 }
142 << Option<CasePath> ("n", "deqp-case", "Test case(s) to run, supports wildcards (e.g. dEQP-GLES2.info.*)")
143 << Option<CaseList> (DE_NULL, "deqp-caselist", "Case list to run in trie format (e.g. {dEQP-GLES2{info{version,renderer}}})")
144 << Option<CaseListFile> (DE_NULL, "deqp-caselist-file", "Read case list (in trie format) from given file")
145 << Option<StdinCaseList> (DE_NULL, "deqp-stdin-caselist", "Read case list (in trie format) from stdin")
146 << Option<LogFilename> (DE_NULL, "deqp-log-filename", "Write test results to given file", "TestResults.qpa")
147 << Option<RunMode> (DE_NULL, "deqp-runmode", "Execute tests, or write list of test cases into a file",
148 s_runModes, "execute")
149 << Option<ExportFilenamePattern>(DE_NULL, "deqp-caselist-export-file", "Set the target file name pattern for caselist export", "${packageName}-cases.${typeExtension}")
150 << Option<WatchDog> (DE_NULL, "deqp-watchdog", "Enable test watchdog", s_enableNames, "disable")
151 << Option<CrashHandler> (DE_NULL, "deqp-crashhandler", "Enable crash handling", s_enableNames, "disable")
152 << Option<BaseSeed> (DE_NULL, "deqp-base-seed", "Base seed for test cases that use randomization", "0")
153 << Option<TestIterationCount> (DE_NULL, "deqp-test-iteration-count", "Iteration count for cases that support variable number of iterations", "0")
154 << Option<Visibility> (DE_NULL, "deqp-visibility", "Default test window visibility", s_visibilites, "windowed")
155 << Option<SurfaceWidth> (DE_NULL, "deqp-surface-width", "Use given surface width if possible", "-1")
156 << Option<SurfaceHeight> (DE_NULL, "deqp-surface-height", "Use given surface height if possible", "-1")
157 << Option<SurfaceType> (DE_NULL, "deqp-surface-type", "Use given surface type", s_surfaceTypes, "window")
158 << Option<ScreenRotation> (DE_NULL, "deqp-screen-rotation", "Screen rotation for platforms that support it", s_screenRotations, "0")
159 << Option<GLContextType> (DE_NULL, "deqp-gl-context-type", "OpenGL context type for platforms that support multiple")
160 << Option<GLConfigID> (DE_NULL, "deqp-gl-config-id", "OpenGL (ES) render config ID (EGL config id on EGL platforms)", "-1")
161 << Option<GLConfigName> (DE_NULL, "deqp-gl-config-name", "Symbolic OpenGL (ES) render config name")
162 << Option<GLContextFlags> (DE_NULL, "deqp-gl-context-flags", "OpenGL context flags (comma-separated, supports debug and robust)")
163 << Option<CLPlatformID> (DE_NULL, "deqp-cl-platform-id", "Execute tests on given OpenCL platform (IDs start from 1)", "1")
164 << Option<CLDeviceIDs> (DE_NULL, "deqp-cl-device-ids", "Execute tests on given CL devices (comma-separated, IDs start from 1)", parseIntList, "")
165 << Option<CLBuildOptions> (DE_NULL, "deqp-cl-build-options", "Extra build options for OpenCL compiler")
166 << Option<EGLDisplayType> (DE_NULL, "deqp-egl-display-type", "EGL native display type")
167 << Option<EGLWindowType> (DE_NULL, "deqp-egl-window-type", "EGL native window type")
168 << Option<EGLPixmapType> (DE_NULL, "deqp-egl-pixmap-type", "EGL native pixmap type")
169 << Option<VKDeviceID> (DE_NULL, "deqp-vk-device-id", "Vulkan device ID (IDs start from 1)", "1")
170 << Option<LogImages> (DE_NULL, "deqp-log-images", "Enable or disable logging of result images", s_enableNames, "enable")
171 << Option<LogShaderSources> (DE_NULL, "deqp-log-shader-sources", "Enable or disable logging of shader sources", s_enableNames, "enable")
172 << Option<TestOOM> (DE_NULL, "deqp-test-oom", "Run tests that exhaust memory on purpose", s_enableNames, TEST_OOM_DEFAULT)
173 << Option<LogFlush> (DE_NULL, "deqp-log-flush", "Enable or disable log file fflush", s_enableNames, "enable");
176 void registerLegacyOptions (de::cmdline::Parser& parser)
178 using de::cmdline::Option;
181 << Option<GLConfigID> (DE_NULL, "deqp-egl-config-id", "Legacy name for --deqp-gl-config-id", "-1")
182 << Option<GLConfigName> (DE_NULL, "deqp-egl-config-name", "Legacy name for --deqp-gl-config-name");
187 // \todo [2014-02-13 pyry] This could be useful elsewhere as well.
188 class DebugOutStreambuf : public std::streambuf
191 DebugOutStreambuf (void);
192 ~DebugOutStreambuf (void);
195 std::streamsize xsputn (const char* s, std::streamsize count);
196 int overflow (int ch = -1);
199 void flushLine (void);
201 std::ostringstream m_curLine;
204 DebugOutStreambuf::DebugOutStreambuf (void)
208 DebugOutStreambuf::~DebugOutStreambuf (void)
210 if (m_curLine.tellp() != std::streampos(0))
214 std::streamsize DebugOutStreambuf::xsputn (const char* s, std::streamsize count)
216 for (std::streamsize pos = 0; pos < count; pos++)
218 m_curLine.put(s[pos]);
227 int DebugOutStreambuf::overflow (int ch)
233 DE_ASSERT((ch & 0xff) == ch);
234 const char chVal = (char)(deUint8)(ch & 0xff);
235 return xsputn(&chVal, 1) == 1 ? ch : -1;
239 void DebugOutStreambuf::flushLine (void)
241 qpPrint(m_curLine.str().c_str());
248 CaseTreeNode (const std::string& name) : m_name(name) {}
249 ~CaseTreeNode (void);
251 const std::string& getName (void) const { return m_name; }
252 bool hasChildren (void) const { return !m_children.empty(); }
254 bool hasChild (const std::string& name) const;
255 const CaseTreeNode* getChild (const std::string& name) const;
256 CaseTreeNode* getChild (const std::string& name);
258 void addChild (CaseTreeNode* child) { m_children.push_back(child); }
261 CaseTreeNode (const CaseTreeNode&);
262 CaseTreeNode& operator= (const CaseTreeNode&);
264 enum { NOT_FOUND = -1 };
266 // \todo [2014-10-30 pyry] Speed up with hash / sorting
267 int findChildNdx (const std::string& name) const;
270 std::vector<CaseTreeNode*> m_children;
273 CaseTreeNode::~CaseTreeNode (void)
275 for (vector<CaseTreeNode*>::const_iterator i = m_children.begin(); i != m_children.end(); ++i)
279 int CaseTreeNode::findChildNdx (const std::string& name) const
281 for (int ndx = 0; ndx < (int)m_children.size(); ++ndx)
283 if (m_children[ndx]->getName() == name)
289 inline bool CaseTreeNode::hasChild (const std::string& name) const
291 return findChildNdx(name) != NOT_FOUND;
294 inline const CaseTreeNode* CaseTreeNode::getChild (const std::string& name) const
296 const int ndx = findChildNdx(name);
297 return ndx == NOT_FOUND ? DE_NULL : m_children[ndx];
300 inline CaseTreeNode* CaseTreeNode::getChild (const std::string& name)
302 const int ndx = findChildNdx(name);
303 return ndx == NOT_FOUND ? DE_NULL : m_children[ndx];
306 static int getCurrentComponentLen (const char* path)
309 for (; path[ndx] != 0 && path[ndx] != '.'; ++ndx);
313 static const CaseTreeNode* findNode (const CaseTreeNode* root, const char* path)
315 const CaseTreeNode* curNode = root;
316 const char* curPath = path;
317 int curLen = getCurrentComponentLen(curPath);
321 curNode = curNode->getChild(std::string(curPath, curPath+curLen));
332 DE_ASSERT(curPath[0] == '.');
334 curLen = getCurrentComponentLen(curPath);
341 static void parseCaseTrie (CaseTreeNode* root, std::istream& in)
343 vector<CaseTreeNode*> nodeStack;
345 bool expectNode = true;
348 throw std::invalid_argument("Malformed case trie");
350 nodeStack.push_back(root);
352 while (!nodeStack.empty())
354 const int curChr = in.get();
356 if (curChr == std::char_traits<char>::eof() || curChr == 0)
357 throw std::invalid_argument("Unterminated case tree");
359 if (curChr == '{' || curChr == ',' || curChr == '}')
361 if (!curName.empty() && expectNode)
363 CaseTreeNode* const newChild = new CaseTreeNode(curName);
367 nodeStack.back()->addChild(newChild);
376 nodeStack.push_back(newChild);
380 else if (curName.empty() == expectNode)
381 throw std::invalid_argument(expectNode ? "Empty node name" : "Missing node separator");
386 nodeStack.pop_back();
388 // consume trailing new line
389 if (nodeStack.empty())
391 if (in.peek() == '\r')
393 if (in.peek() == '\n')
400 else if (isValidTestCaseNameChar((char)curChr))
401 curName += (char)curChr;
403 throw std::invalid_argument("Illegal character in node name");
407 static void parseCaseList (CaseTreeNode* root, std::istream& in)
409 // \note Algorithm assumes that cases are sorted by groups, but will
410 // function fine, albeit more slowly, if that is not the case.
411 vector<CaseTreeNode*> nodeStack;
415 nodeStack.resize(8, DE_NULL);
421 const int curChr = in.get();
423 if (curChr == std::char_traits<char>::eof() || curChr == 0 || curChr == '\n' || curChr == '\r')
426 throw std::invalid_argument("Empty test case name");
428 if (nodeStack[stackPos]->hasChild(curName))
429 throw std::invalid_argument("Duplicate test case");
431 CaseTreeNode* const newChild = new CaseTreeNode(curName);
435 nodeStack[stackPos]->addChild(newChild);
446 if (curChr == '\r' && in.peek() == '\n')
450 const int nextChr = in.peek();
452 if (nextChr == std::char_traits<char>::eof() || nextChr == 0)
456 else if (curChr == '.')
459 throw std::invalid_argument("Empty test group name");
461 if ((int)nodeStack.size() <= stackPos+1)
462 nodeStack.resize(nodeStack.size()*2, DE_NULL);
464 if (!nodeStack[stackPos+1] || nodeStack[stackPos+1]->getName() != curName)
466 CaseTreeNode* curGroup = nodeStack[stackPos]->getChild(curName);
470 curGroup = new CaseTreeNode(curName);
474 nodeStack[stackPos]->addChild(curGroup);
483 nodeStack[stackPos+1] = curGroup;
485 if ((int)nodeStack.size() > stackPos+2)
486 nodeStack[stackPos+2] = DE_NULL; // Invalidate rest of entries
489 DE_ASSERT(nodeStack[stackPos+1]->getName() == curName);
494 else if (isValidTestCaseNameChar((char)curChr))
495 curName += (char)curChr;
497 throw std::invalid_argument("Illegal character in test case name");
501 static CaseTreeNode* parseCaseList (std::istream& in)
503 CaseTreeNode* const root = new CaseTreeNode("");
506 if (in.peek() == '{')
507 parseCaseTrie(root, in);
509 parseCaseList(root, in);
512 const int curChr = in.get();
513 if (curChr != std::char_traits<char>::eof() && curChr != 0)
514 throw std::invalid_argument("Trailing characters at end of case list");
529 CasePaths (const string& pathList);
530 bool matches (const string& caseName, bool allowPrefix=false) const;
533 const vector<string> m_casePatterns;
536 CasePaths::CasePaths (const string& pathList)
537 : m_casePatterns(de::splitString(pathList, ','))
541 // Match a single path component against a pattern component that may contain *-wildcards.
542 static bool matchWildcards(string::const_iterator patternStart,
543 string::const_iterator patternEnd,
544 string::const_iterator pathStart,
545 string::const_iterator pathEnd,
548 string::const_iterator pattern = patternStart;
549 string::const_iterator path = pathStart;
551 while (pattern != patternEnd && path != pathEnd && *pattern == *path)
557 if (pattern == patternEnd)
558 return (path == pathEnd);
559 else if (*pattern == '*')
561 for (; path != pathEnd; ++path)
563 if (matchWildcards(pattern + 1, patternEnd, path, pathEnd, allowPrefix))
567 if (matchWildcards(pattern + 1, patternEnd, pathEnd, pathEnd, allowPrefix))
570 else if (path == pathEnd && allowPrefix)
576 #if defined(TCU_HIERARCHICAL_CASEPATHS)
577 // Match a list of pattern components to a list of path components. A pattern
578 // component may contain *-wildcards. A pattern component "**" matches zero or
579 // more whole path components.
580 static bool patternMatches(vector<string>::const_iterator patternStart,
581 vector<string>::const_iterator patternEnd,
582 vector<string>::const_iterator pathStart,
583 vector<string>::const_iterator pathEnd,
586 vector<string>::const_iterator pattern = patternStart;
587 vector<string>::const_iterator path = pathStart;
589 while (pattern != patternEnd && path != pathEnd && *pattern != "**" &&
590 (*pattern == *path || matchWildcards(pattern->begin(), pattern->end(),
591 path->begin(), path->end(), false)))
597 if (path == pathEnd && (allowPrefix || pattern == patternEnd))
599 else if (pattern != patternEnd && *pattern == "**")
601 for (; path != pathEnd; ++path)
602 if (patternMatches(pattern + 1, patternEnd, path, pathEnd, allowPrefix))
604 if (patternMatches(pattern + 1, patternEnd, path, pathEnd, allowPrefix))
612 bool CasePaths::matches (const string& caseName, bool allowPrefix) const
614 const vector<string> components = de::splitString(caseName, '.');
616 for (size_t ndx = 0; ndx < m_casePatterns.size(); ++ndx)
618 #if defined(TCU_HIERARCHICAL_CASEPATHS)
619 const vector<string> patternComponents = de::splitString(m_casePatterns[ndx], '.');
621 if (patternMatches(patternComponents.begin(), patternComponents.end(),
622 components.begin(), components.end(), allowPrefix))
625 if (matchWildcards(m_casePatterns[ndx].begin(), m_casePatterns[ndx].end(),
626 caseName.begin(), caseName.end(), allowPrefix))
634 /*--------------------------------------------------------------------*//*!
635 * \brief Construct command line
636 * \note CommandLine is not fully initialized until parse() has been called.
637 *//*--------------------------------------------------------------------*/
638 CommandLine::CommandLine (void)
640 , m_caseTree (DE_NULL)
644 /*--------------------------------------------------------------------*//*!
645 * \brief Construct command line from standard argc, argv pair.
647 * Calls parse() with given arguments
648 * \param argc Number of arguments
649 * \param argv Command line arguments
650 *//*--------------------------------------------------------------------*/
651 CommandLine::CommandLine (int argc, const char* const* argv)
653 , m_caseTree (DE_NULL)
655 if (!parse(argc, argv))
656 throw Exception("Failed to parse command line");
659 /*--------------------------------------------------------------------*//*!
660 * \brief Construct command line from string.
662 * Calls parse() with given argument.
663 * \param cmdLine Full command line string.
664 *//*--------------------------------------------------------------------*/
665 CommandLine::CommandLine (const std::string& cmdLine)
667 , m_caseTree (DE_NULL)
670 throw Exception("Failed to parse command line");
673 CommandLine::~CommandLine (void)
678 void CommandLine::clear (void)
684 m_caseTree = DE_NULL;
687 const de::cmdline::CommandLine& CommandLine::getCommandLine (void) const
692 void CommandLine::registerExtendedOptions (de::cmdline::Parser& parser)
697 /*--------------------------------------------------------------------*//*!
698 * \brief Parse command line from standard argc, argv pair.
699 * \note parse() must be called exactly once.
700 * \param argc Number of arguments
701 * \param argv Command line arguments
702 *//*--------------------------------------------------------------------*/
703 bool CommandLine::parse (int argc, const char* const* argv)
705 DebugOutStreambuf sbuf;
706 std::ostream debugOut (&sbuf);
707 de::cmdline::Parser parser;
709 opt::registerOptions(parser);
710 opt::registerLegacyOptions(parser);
711 registerExtendedOptions(parser);
715 if (!parser.parse(argc-1, argv+1, &m_cmdLine, std::cerr))
717 debugOut << "\n" << de::FilePath(argv[0]).getBaseName() << " [options]\n\n";
718 parser.help(debugOut);
724 if (!m_cmdLine.getOption<opt::LogImages>())
725 m_logFlags |= QP_TEST_LOG_EXCLUDE_IMAGES;
727 if (!m_cmdLine.getOption<opt::LogShaderSources>())
728 m_logFlags |= QP_TEST_LOG_EXCLUDE_SHADER_SOURCES;
730 if (!m_cmdLine.getOption<opt::LogFlush>())
731 m_logFlags |= QP_TEST_LOG_NO_FLUSH;
733 if ((m_cmdLine.hasOption<opt::CasePath>()?1:0) +
734 (m_cmdLine.hasOption<opt::CaseList>()?1:0) +
735 (m_cmdLine.hasOption<opt::CaseListFile>()?1:0) +
736 (m_cmdLine.getOption<opt::StdinCaseList>()?1:0) > 1)
738 debugOut << "ERROR: multiple test case list options given!\n" << std::endl;
745 if (m_cmdLine.hasOption<opt::CaseList>())
747 std::istringstream str(m_cmdLine.getOption<opt::CaseList>());
749 m_caseTree = parseCaseList(str);
751 else if (m_cmdLine.hasOption<opt::CaseListFile>())
753 std::ifstream in(m_cmdLine.getOption<opt::CaseListFile>().c_str(), std::ios_base::binary);
755 if (!in.is_open() || !in.good())
756 throw Exception("Failed to open case list file '" + m_cmdLine.getOption<opt::CaseListFile>() + "'");
758 m_caseTree = parseCaseList(in);
760 else if (m_cmdLine.getOption<opt::StdinCaseList>())
762 m_caseTree = parseCaseList(std::cin);
764 else if (m_cmdLine.hasOption<opt::CasePath>())
765 m_casePaths = de::MovePtr<const CasePaths>(new CasePaths(m_cmdLine.getOption<opt::CasePath>()));
767 catch (const std::exception& e)
769 debugOut << "ERROR: Failed to parse test case list: " << e.what() << "\n";
777 /*--------------------------------------------------------------------*//*!
778 * \brief Parse command line from string.
779 * \note parse() must be called exactly once.
780 * \param cmdLine Full command line string.
781 *//*--------------------------------------------------------------------*/
782 bool CommandLine::parse (const std::string& cmdLine)
784 deCommandLine* parsedCmdLine = deCommandLine_parse(cmdLine.c_str());
786 throw std::bad_alloc();
791 isOk = parse(parsedCmdLine->numArgs, parsedCmdLine->args);
795 deCommandLine_destroy(parsedCmdLine);
799 deCommandLine_destroy(parsedCmdLine);
803 const char* CommandLine::getLogFileName (void) const { return m_cmdLine.getOption<opt::LogFilename>().c_str(); }
804 deUint32 CommandLine::getLogFlags (void) const { return m_logFlags; }
805 RunMode CommandLine::getRunMode (void) const { return m_cmdLine.getOption<opt::RunMode>(); }
806 const char* CommandLine::getCaseListExportFile (void) const { return m_cmdLine.getOption<opt::ExportFilenamePattern>().c_str(); }
807 WindowVisibility CommandLine::getVisibility (void) const { return m_cmdLine.getOption<opt::Visibility>(); }
808 bool CommandLine::isWatchDogEnabled (void) const { return m_cmdLine.getOption<opt::WatchDog>(); }
809 bool CommandLine::isCrashHandlingEnabled (void) const { return m_cmdLine.getOption<opt::CrashHandler>(); }
810 int CommandLine::getBaseSeed (void) const { return m_cmdLine.getOption<opt::BaseSeed>(); }
811 int CommandLine::getTestIterationCount (void) const { return m_cmdLine.getOption<opt::TestIterationCount>(); }
812 int CommandLine::getSurfaceWidth (void) const { return m_cmdLine.getOption<opt::SurfaceWidth>(); }
813 int CommandLine::getSurfaceHeight (void) const { return m_cmdLine.getOption<opt::SurfaceHeight>(); }
814 SurfaceType CommandLine::getSurfaceType (void) const { return m_cmdLine.getOption<opt::SurfaceType>(); }
815 ScreenRotation CommandLine::getScreenRotation (void) const { return m_cmdLine.getOption<opt::ScreenRotation>(); }
816 int CommandLine::getGLConfigId (void) const { return m_cmdLine.getOption<opt::GLConfigID>(); }
817 int CommandLine::getCLPlatformId (void) const { return m_cmdLine.getOption<opt::CLPlatformID>(); }
818 const std::vector<int>& CommandLine::getCLDeviceIds (void) const { return m_cmdLine.getOption<opt::CLDeviceIDs>(); }
819 int CommandLine::getVKDeviceId (void) const { return m_cmdLine.getOption<opt::VKDeviceID>(); }
820 bool CommandLine::isOutOfMemoryTestEnabled (void) const { return m_cmdLine.getOption<opt::TestOOM>(); }
822 const char* CommandLine::getGLContextType (void) const
824 if (m_cmdLine.hasOption<opt::GLContextType>())
825 return m_cmdLine.getOption<opt::GLContextType>().c_str();
829 const char* CommandLine::getGLConfigName (void) const
831 if (m_cmdLine.hasOption<opt::GLConfigName>())
832 return m_cmdLine.getOption<opt::GLConfigName>().c_str();
837 const char* CommandLine::getGLContextFlags (void) const
839 if (m_cmdLine.hasOption<opt::GLContextFlags>())
840 return m_cmdLine.getOption<opt::GLContextFlags>().c_str();
845 const char* CommandLine::getCLBuildOptions (void) const
847 if (m_cmdLine.hasOption<opt::CLBuildOptions>())
848 return m_cmdLine.getOption<opt::CLBuildOptions>().c_str();
853 const char* CommandLine::getEGLDisplayType (void) const
855 if (m_cmdLine.hasOption<opt::EGLDisplayType>())
856 return m_cmdLine.getOption<opt::EGLDisplayType>().c_str();
861 const char* CommandLine::getEGLWindowType (void) const
863 if (m_cmdLine.hasOption<opt::EGLWindowType>())
864 return m_cmdLine.getOption<opt::EGLWindowType>().c_str();
869 const char* CommandLine::getEGLPixmapType (void) const
871 if (m_cmdLine.hasOption<opt::EGLPixmapType>())
872 return m_cmdLine.getOption<opt::EGLPixmapType>().c_str();
877 static bool checkTestGroupName (const CaseTreeNode* root, const char* groupPath)
879 const CaseTreeNode* node = findNode(root, groupPath);
880 return node && node->hasChildren();
883 static bool checkTestCaseName (const CaseTreeNode* root, const char* casePath)
885 const CaseTreeNode* node = findNode(root, casePath);
886 return node && !node->hasChildren();
889 bool CommandLine::checkTestGroupName (const char* groupName) const
892 return m_casePaths->matches(groupName, true);
894 return groupName[0] == 0 || tcu::checkTestGroupName(m_caseTree, groupName);
899 bool CommandLine::checkTestCaseName (const char* caseName) const
902 return m_casePaths->matches(caseName, false);
904 return tcu::checkTestCaseName(m_caseTree, caseName);