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);
88 DE_DECLARE_COMMAND_LINE_OPT(Validation, bool);
90 static void parseIntList (const char* src, std::vector<int>* dst)
92 std::istringstream str (src);
95 while (std::getline(str, val, ','))
98 de::cmdline::parseType(val.c_str(), &intVal);
99 dst->push_back(intVal);
103 void registerOptions (de::cmdline::Parser& parser)
105 using de::cmdline::Option;
106 using de::cmdline::NamedValue;
108 static const NamedValue<bool> s_enableNames[] =
113 static const NamedValue<tcu::RunMode> s_runModes[] =
115 { "execute", RUNMODE_EXECUTE },
116 { "xml-caselist", RUNMODE_DUMP_XML_CASELIST },
117 { "txt-caselist", RUNMODE_DUMP_TEXT_CASELIST },
118 { "stdout-caselist",RUNMODE_DUMP_STDOUT_CASELIST}
120 static const NamedValue<WindowVisibility> s_visibilites[] =
122 { "windowed", WINDOWVISIBILITY_WINDOWED },
123 { "fullscreen", WINDOWVISIBILITY_FULLSCREEN },
124 { "hidden", WINDOWVISIBILITY_HIDDEN }
126 static const NamedValue<tcu::SurfaceType> s_surfaceTypes[] =
128 { "window", SURFACETYPE_WINDOW },
129 { "pixmap", SURFACETYPE_OFFSCREEN_NATIVE },
130 { "pbuffer", SURFACETYPE_OFFSCREEN_GENERIC },
131 { "fbo", SURFACETYPE_FBO }
133 static const NamedValue<tcu::ScreenRotation> s_screenRotations[] =
135 { "unspecified", SCREENROTATION_UNSPECIFIED },
136 { "0", SCREENROTATION_0 },
137 { "90", SCREENROTATION_90 },
138 { "180", SCREENROTATION_180 },
139 { "270", SCREENROTATION_270 }
143 << Option<CasePath> ("n", "deqp-case", "Test case(s) to run, supports wildcards (e.g. dEQP-GLES2.info.*)")
144 << Option<CaseList> (DE_NULL, "deqp-caselist", "Case list to run in trie format (e.g. {dEQP-GLES2{info{version,renderer}}})")
145 << Option<CaseListFile> (DE_NULL, "deqp-caselist-file", "Read case list (in trie format) from given file")
146 << Option<StdinCaseList> (DE_NULL, "deqp-stdin-caselist", "Read case list (in trie format) from stdin")
147 << Option<LogFilename> (DE_NULL, "deqp-log-filename", "Write test results to given file", "TestResults.qpa")
148 << Option<RunMode> (DE_NULL, "deqp-runmode", "Execute tests, or write list of test cases into a file",
149 s_runModes, "execute")
150 << Option<ExportFilenamePattern>(DE_NULL, "deqp-caselist-export-file", "Set the target file name pattern for caselist export", "${packageName}-cases.${typeExtension}")
151 << Option<WatchDog> (DE_NULL, "deqp-watchdog", "Enable test watchdog", s_enableNames, "disable")
152 << Option<CrashHandler> (DE_NULL, "deqp-crashhandler", "Enable crash handling", s_enableNames, "disable")
153 << Option<BaseSeed> (DE_NULL, "deqp-base-seed", "Base seed for test cases that use randomization", "0")
154 << Option<TestIterationCount> (DE_NULL, "deqp-test-iteration-count", "Iteration count for cases that support variable number of iterations", "0")
155 << Option<Visibility> (DE_NULL, "deqp-visibility", "Default test window visibility", s_visibilites, "windowed")
156 << Option<SurfaceWidth> (DE_NULL, "deqp-surface-width", "Use given surface width if possible", "-1")
157 << Option<SurfaceHeight> (DE_NULL, "deqp-surface-height", "Use given surface height if possible", "-1")
158 << Option<SurfaceType> (DE_NULL, "deqp-surface-type", "Use given surface type", s_surfaceTypes, "window")
159 << Option<ScreenRotation> (DE_NULL, "deqp-screen-rotation", "Screen rotation for platforms that support it", s_screenRotations, "0")
160 << Option<GLContextType> (DE_NULL, "deqp-gl-context-type", "OpenGL context type for platforms that support multiple")
161 << Option<GLConfigID> (DE_NULL, "deqp-gl-config-id", "OpenGL (ES) render config ID (EGL config id on EGL platforms)", "-1")
162 << Option<GLConfigName> (DE_NULL, "deqp-gl-config-name", "Symbolic OpenGL (ES) render config name")
163 << Option<GLContextFlags> (DE_NULL, "deqp-gl-context-flags", "OpenGL context flags (comma-separated, supports debug and robust)")
164 << Option<CLPlatformID> (DE_NULL, "deqp-cl-platform-id", "Execute tests on given OpenCL platform (IDs start from 1)", "1")
165 << Option<CLDeviceIDs> (DE_NULL, "deqp-cl-device-ids", "Execute tests on given CL devices (comma-separated, IDs start from 1)", parseIntList, "")
166 << Option<CLBuildOptions> (DE_NULL, "deqp-cl-build-options", "Extra build options for OpenCL compiler")
167 << Option<EGLDisplayType> (DE_NULL, "deqp-egl-display-type", "EGL native display type")
168 << Option<EGLWindowType> (DE_NULL, "deqp-egl-window-type", "EGL native window type")
169 << Option<EGLPixmapType> (DE_NULL, "deqp-egl-pixmap-type", "EGL native pixmap type")
170 << Option<VKDeviceID> (DE_NULL, "deqp-vk-device-id", "Vulkan device ID (IDs start from 1)", "1")
171 << Option<LogImages> (DE_NULL, "deqp-log-images", "Enable or disable logging of result images", s_enableNames, "enable")
172 << Option<LogShaderSources> (DE_NULL, "deqp-log-shader-sources", "Enable or disable logging of shader sources", s_enableNames, "enable")
173 << Option<TestOOM> (DE_NULL, "deqp-test-oom", "Run tests that exhaust memory on purpose", s_enableNames, TEST_OOM_DEFAULT)
174 << Option<LogFlush> (DE_NULL, "deqp-log-flush", "Enable or disable log file fflush", s_enableNames, "enable")
175 << Option<Validation> (DE_NULL, "deqp-validation", "Enable or disable test case validation", s_enableNames, "disable");
178 void registerLegacyOptions (de::cmdline::Parser& parser)
180 using de::cmdline::Option;
183 << Option<GLConfigID> (DE_NULL, "deqp-egl-config-id", "Legacy name for --deqp-gl-config-id", "-1")
184 << Option<GLConfigName> (DE_NULL, "deqp-egl-config-name", "Legacy name for --deqp-gl-config-name");
189 // \todo [2014-02-13 pyry] This could be useful elsewhere as well.
190 class DebugOutStreambuf : public std::streambuf
193 DebugOutStreambuf (void);
194 ~DebugOutStreambuf (void);
197 std::streamsize xsputn (const char* s, std::streamsize count);
198 int overflow (int ch = -1);
201 void flushLine (void);
203 std::ostringstream m_curLine;
206 DebugOutStreambuf::DebugOutStreambuf (void)
210 DebugOutStreambuf::~DebugOutStreambuf (void)
212 if (m_curLine.tellp() != std::streampos(0))
216 std::streamsize DebugOutStreambuf::xsputn (const char* s, std::streamsize count)
218 for (std::streamsize pos = 0; pos < count; pos++)
220 m_curLine.put(s[pos]);
229 int DebugOutStreambuf::overflow (int ch)
235 DE_ASSERT((ch & 0xff) == ch);
236 const char chVal = (char)(deUint8)(ch & 0xff);
237 return xsputn(&chVal, 1) == 1 ? ch : -1;
241 void DebugOutStreambuf::flushLine (void)
243 qpPrint(m_curLine.str().c_str());
250 CaseTreeNode (const std::string& name) : m_name(name) {}
251 ~CaseTreeNode (void);
253 const std::string& getName (void) const { return m_name; }
254 bool hasChildren (void) const { return !m_children.empty(); }
256 bool hasChild (const std::string& name) const;
257 const CaseTreeNode* getChild (const std::string& name) const;
258 CaseTreeNode* getChild (const std::string& name);
260 void addChild (CaseTreeNode* child) { m_children.push_back(child); }
263 CaseTreeNode (const CaseTreeNode&);
264 CaseTreeNode& operator= (const CaseTreeNode&);
266 enum { NOT_FOUND = -1 };
268 // \todo [2014-10-30 pyry] Speed up with hash / sorting
269 int findChildNdx (const std::string& name) const;
272 std::vector<CaseTreeNode*> m_children;
275 CaseTreeNode::~CaseTreeNode (void)
277 for (vector<CaseTreeNode*>::const_iterator i = m_children.begin(); i != m_children.end(); ++i)
281 int CaseTreeNode::findChildNdx (const std::string& name) const
283 for (int ndx = 0; ndx < (int)m_children.size(); ++ndx)
285 if (m_children[ndx]->getName() == name)
291 inline bool CaseTreeNode::hasChild (const std::string& name) const
293 return findChildNdx(name) != NOT_FOUND;
296 inline const CaseTreeNode* CaseTreeNode::getChild (const std::string& name) const
298 const int ndx = findChildNdx(name);
299 return ndx == NOT_FOUND ? DE_NULL : m_children[ndx];
302 inline CaseTreeNode* CaseTreeNode::getChild (const std::string& name)
304 const int ndx = findChildNdx(name);
305 return ndx == NOT_FOUND ? DE_NULL : m_children[ndx];
308 static int getCurrentComponentLen (const char* path)
311 for (; path[ndx] != 0 && path[ndx] != '.'; ++ndx);
315 static const CaseTreeNode* findNode (const CaseTreeNode* root, const char* path)
317 const CaseTreeNode* curNode = root;
318 const char* curPath = path;
319 int curLen = getCurrentComponentLen(curPath);
323 curNode = curNode->getChild(std::string(curPath, curPath+curLen));
334 DE_ASSERT(curPath[0] == '.');
336 curLen = getCurrentComponentLen(curPath);
343 static void parseCaseTrie (CaseTreeNode* root, std::istream& in)
345 vector<CaseTreeNode*> nodeStack;
347 bool expectNode = true;
350 throw std::invalid_argument("Malformed case trie");
352 nodeStack.push_back(root);
354 while (!nodeStack.empty())
356 const int curChr = in.get();
358 if (curChr == std::char_traits<char>::eof() || curChr == 0)
359 throw std::invalid_argument("Unterminated case tree");
361 if (curChr == '{' || curChr == ',' || curChr == '}')
363 if (!curName.empty() && expectNode)
365 CaseTreeNode* const newChild = new CaseTreeNode(curName);
369 nodeStack.back()->addChild(newChild);
378 nodeStack.push_back(newChild);
382 else if (curName.empty() == expectNode)
383 throw std::invalid_argument(expectNode ? "Empty node name" : "Missing node separator");
388 nodeStack.pop_back();
390 // consume trailing new line
391 if (nodeStack.empty())
393 if (in.peek() == '\r')
395 if (in.peek() == '\n')
402 else if (isValidTestCaseNameChar((char)curChr))
403 curName += (char)curChr;
405 throw std::invalid_argument("Illegal character in node name");
409 static void parseCaseList (CaseTreeNode* root, std::istream& in)
411 // \note Algorithm assumes that cases are sorted by groups, but will
412 // function fine, albeit more slowly, if that is not the case.
413 vector<CaseTreeNode*> nodeStack;
417 nodeStack.resize(8, DE_NULL);
423 const int curChr = in.get();
425 if (curChr == std::char_traits<char>::eof() || curChr == 0 || curChr == '\n' || curChr == '\r')
428 throw std::invalid_argument("Empty test case name");
430 if (nodeStack[stackPos]->hasChild(curName))
431 throw std::invalid_argument("Duplicate test case");
433 CaseTreeNode* const newChild = new CaseTreeNode(curName);
437 nodeStack[stackPos]->addChild(newChild);
448 if (curChr == '\r' && in.peek() == '\n')
452 const int nextChr = in.peek();
454 if (nextChr == std::char_traits<char>::eof() || nextChr == 0)
458 else if (curChr == '.')
461 throw std::invalid_argument("Empty test group name");
463 if ((int)nodeStack.size() <= stackPos+1)
464 nodeStack.resize(nodeStack.size()*2, DE_NULL);
466 if (!nodeStack[stackPos+1] || nodeStack[stackPos+1]->getName() != curName)
468 CaseTreeNode* curGroup = nodeStack[stackPos]->getChild(curName);
472 curGroup = new CaseTreeNode(curName);
476 nodeStack[stackPos]->addChild(curGroup);
485 nodeStack[stackPos+1] = curGroup;
487 if ((int)nodeStack.size() > stackPos+2)
488 nodeStack[stackPos+2] = DE_NULL; // Invalidate rest of entries
491 DE_ASSERT(nodeStack[stackPos+1]->getName() == curName);
496 else if (isValidTestCaseNameChar((char)curChr))
497 curName += (char)curChr;
499 throw std::invalid_argument("Illegal character in test case name");
503 static CaseTreeNode* parseCaseList (std::istream& in)
505 CaseTreeNode* const root = new CaseTreeNode("");
508 if (in.peek() == '{')
509 parseCaseTrie(root, in);
511 parseCaseList(root, in);
514 const int curChr = in.get();
515 if (curChr != std::char_traits<char>::eof() && curChr != 0)
516 throw std::invalid_argument("Trailing characters at end of case list");
531 CasePaths (const string& pathList);
532 bool matches (const string& caseName, bool allowPrefix=false) const;
535 const vector<string> m_casePatterns;
538 CasePaths::CasePaths (const string& pathList)
539 : m_casePatterns(de::splitString(pathList, ','))
543 // Match a single path component against a pattern component that may contain *-wildcards.
544 static bool matchWildcards(string::const_iterator patternStart,
545 string::const_iterator patternEnd,
546 string::const_iterator pathStart,
547 string::const_iterator pathEnd,
550 string::const_iterator pattern = patternStart;
551 string::const_iterator path = pathStart;
553 while (pattern != patternEnd && path != pathEnd && *pattern == *path)
559 if (pattern == patternEnd)
560 return (path == pathEnd);
561 else if (*pattern == '*')
563 for (; path != pathEnd; ++path)
565 if (matchWildcards(pattern + 1, patternEnd, path, pathEnd, allowPrefix))
569 if (matchWildcards(pattern + 1, patternEnd, pathEnd, pathEnd, allowPrefix))
572 else if (path == pathEnd && allowPrefix)
578 #if defined(TCU_HIERARCHICAL_CASEPATHS)
579 // Match a list of pattern components to a list of path components. A pattern
580 // component may contain *-wildcards. A pattern component "**" matches zero or
581 // more whole path components.
582 static bool patternMatches(vector<string>::const_iterator patternStart,
583 vector<string>::const_iterator patternEnd,
584 vector<string>::const_iterator pathStart,
585 vector<string>::const_iterator pathEnd,
588 vector<string>::const_iterator pattern = patternStart;
589 vector<string>::const_iterator path = pathStart;
591 while (pattern != patternEnd && path != pathEnd && *pattern != "**" &&
592 (*pattern == *path || matchWildcards(pattern->begin(), pattern->end(),
593 path->begin(), path->end(), false)))
599 if (path == pathEnd && (allowPrefix || pattern == patternEnd))
601 else if (pattern != patternEnd && *pattern == "**")
603 for (; path != pathEnd; ++path)
604 if (patternMatches(pattern + 1, patternEnd, path, pathEnd, allowPrefix))
606 if (patternMatches(pattern + 1, patternEnd, path, pathEnd, allowPrefix))
614 bool CasePaths::matches (const string& caseName, bool allowPrefix) const
616 const vector<string> components = de::splitString(caseName, '.');
618 for (size_t ndx = 0; ndx < m_casePatterns.size(); ++ndx)
620 #if defined(TCU_HIERARCHICAL_CASEPATHS)
621 const vector<string> patternComponents = de::splitString(m_casePatterns[ndx], '.');
623 if (patternMatches(patternComponents.begin(), patternComponents.end(),
624 components.begin(), components.end(), allowPrefix))
627 if (matchWildcards(m_casePatterns[ndx].begin(), m_casePatterns[ndx].end(),
628 caseName.begin(), caseName.end(), allowPrefix))
636 /*--------------------------------------------------------------------*//*!
637 * \brief Construct command line
638 * \note CommandLine is not fully initialized until parse() has been called.
639 *//*--------------------------------------------------------------------*/
640 CommandLine::CommandLine (void)
642 , m_caseTree (DE_NULL)
646 /*--------------------------------------------------------------------*//*!
647 * \brief Construct command line from standard argc, argv pair.
649 * Calls parse() with given arguments
650 * \param argc Number of arguments
651 * \param argv Command line arguments
652 *//*--------------------------------------------------------------------*/
653 CommandLine::CommandLine (int argc, const char* const* argv)
655 , m_caseTree (DE_NULL)
657 if (!parse(argc, argv))
658 throw Exception("Failed to parse command line");
661 /*--------------------------------------------------------------------*//*!
662 * \brief Construct command line from string.
664 * Calls parse() with given argument.
665 * \param cmdLine Full command line string.
666 *//*--------------------------------------------------------------------*/
667 CommandLine::CommandLine (const std::string& cmdLine)
669 , m_caseTree (DE_NULL)
672 throw Exception("Failed to parse command line");
675 CommandLine::~CommandLine (void)
680 void CommandLine::clear (void)
686 m_caseTree = DE_NULL;
689 const de::cmdline::CommandLine& CommandLine::getCommandLine (void) const
694 void CommandLine::registerExtendedOptions (de::cmdline::Parser& parser)
699 /*--------------------------------------------------------------------*//*!
700 * \brief Parse command line from standard argc, argv pair.
701 * \note parse() must be called exactly once.
702 * \param argc Number of arguments
703 * \param argv Command line arguments
704 *//*--------------------------------------------------------------------*/
705 bool CommandLine::parse (int argc, const char* const* argv)
707 DebugOutStreambuf sbuf;
708 std::ostream debugOut (&sbuf);
709 de::cmdline::Parser parser;
711 opt::registerOptions(parser);
712 opt::registerLegacyOptions(parser);
713 registerExtendedOptions(parser);
717 if (!parser.parse(argc-1, argv+1, &m_cmdLine, std::cerr))
719 debugOut << "\n" << de::FilePath(argv[0]).getBaseName() << " [options]\n\n";
720 parser.help(debugOut);
726 if (!m_cmdLine.getOption<opt::LogImages>())
727 m_logFlags |= QP_TEST_LOG_EXCLUDE_IMAGES;
729 if (!m_cmdLine.getOption<opt::LogShaderSources>())
730 m_logFlags |= QP_TEST_LOG_EXCLUDE_SHADER_SOURCES;
732 if (!m_cmdLine.getOption<opt::LogFlush>())
733 m_logFlags |= QP_TEST_LOG_NO_FLUSH;
735 if ((m_cmdLine.hasOption<opt::CasePath>()?1:0) +
736 (m_cmdLine.hasOption<opt::CaseList>()?1:0) +
737 (m_cmdLine.hasOption<opt::CaseListFile>()?1:0) +
738 (m_cmdLine.getOption<opt::StdinCaseList>()?1:0) > 1)
740 debugOut << "ERROR: multiple test case list options given!\n" << std::endl;
747 if (m_cmdLine.hasOption<opt::CaseList>())
749 std::istringstream str(m_cmdLine.getOption<opt::CaseList>());
751 m_caseTree = parseCaseList(str);
753 else if (m_cmdLine.hasOption<opt::CaseListFile>())
755 std::ifstream in(m_cmdLine.getOption<opt::CaseListFile>().c_str(), std::ios_base::binary);
757 if (!in.is_open() || !in.good())
758 throw Exception("Failed to open case list file '" + m_cmdLine.getOption<opt::CaseListFile>() + "'");
760 m_caseTree = parseCaseList(in);
762 else if (m_cmdLine.getOption<opt::StdinCaseList>())
764 m_caseTree = parseCaseList(std::cin);
766 else if (m_cmdLine.hasOption<opt::CasePath>())
767 m_casePaths = de::MovePtr<const CasePaths>(new CasePaths(m_cmdLine.getOption<opt::CasePath>()));
769 catch (const std::exception& e)
771 debugOut << "ERROR: Failed to parse test case list: " << e.what() << "\n";
779 /*--------------------------------------------------------------------*//*!
780 * \brief Parse command line from string.
781 * \note parse() must be called exactly once.
782 * \param cmdLine Full command line string.
783 *//*--------------------------------------------------------------------*/
784 bool CommandLine::parse (const std::string& cmdLine)
786 deCommandLine* parsedCmdLine = deCommandLine_parse(cmdLine.c_str());
788 throw std::bad_alloc();
793 isOk = parse(parsedCmdLine->numArgs, parsedCmdLine->args);
797 deCommandLine_destroy(parsedCmdLine);
801 deCommandLine_destroy(parsedCmdLine);
805 const char* CommandLine::getLogFileName (void) const { return m_cmdLine.getOption<opt::LogFilename>().c_str(); }
806 deUint32 CommandLine::getLogFlags (void) const { return m_logFlags; }
807 RunMode CommandLine::getRunMode (void) const { return m_cmdLine.getOption<opt::RunMode>(); }
808 const char* CommandLine::getCaseListExportFile (void) const { return m_cmdLine.getOption<opt::ExportFilenamePattern>().c_str(); }
809 WindowVisibility CommandLine::getVisibility (void) const { return m_cmdLine.getOption<opt::Visibility>(); }
810 bool CommandLine::isWatchDogEnabled (void) const { return m_cmdLine.getOption<opt::WatchDog>(); }
811 bool CommandLine::isCrashHandlingEnabled (void) const { return m_cmdLine.getOption<opt::CrashHandler>(); }
812 int CommandLine::getBaseSeed (void) const { return m_cmdLine.getOption<opt::BaseSeed>(); }
813 int CommandLine::getTestIterationCount (void) const { return m_cmdLine.getOption<opt::TestIterationCount>(); }
814 int CommandLine::getSurfaceWidth (void) const { return m_cmdLine.getOption<opt::SurfaceWidth>(); }
815 int CommandLine::getSurfaceHeight (void) const { return m_cmdLine.getOption<opt::SurfaceHeight>(); }
816 SurfaceType CommandLine::getSurfaceType (void) const { return m_cmdLine.getOption<opt::SurfaceType>(); }
817 ScreenRotation CommandLine::getScreenRotation (void) const { return m_cmdLine.getOption<opt::ScreenRotation>(); }
818 int CommandLine::getGLConfigId (void) const { return m_cmdLine.getOption<opt::GLConfigID>(); }
819 int CommandLine::getCLPlatformId (void) const { return m_cmdLine.getOption<opt::CLPlatformID>(); }
820 const std::vector<int>& CommandLine::getCLDeviceIds (void) const { return m_cmdLine.getOption<opt::CLDeviceIDs>(); }
821 int CommandLine::getVKDeviceId (void) const { return m_cmdLine.getOption<opt::VKDeviceID>(); }
822 bool CommandLine::isValidationEnabled (void) const { return m_cmdLine.getOption<opt::Validation>(); }
823 bool CommandLine::isOutOfMemoryTestEnabled (void) const { return m_cmdLine.getOption<opt::TestOOM>(); }
825 const char* CommandLine::getGLContextType (void) const
827 if (m_cmdLine.hasOption<opt::GLContextType>())
828 return m_cmdLine.getOption<opt::GLContextType>().c_str();
832 const char* CommandLine::getGLConfigName (void) const
834 if (m_cmdLine.hasOption<opt::GLConfigName>())
835 return m_cmdLine.getOption<opt::GLConfigName>().c_str();
840 const char* CommandLine::getGLContextFlags (void) const
842 if (m_cmdLine.hasOption<opt::GLContextFlags>())
843 return m_cmdLine.getOption<opt::GLContextFlags>().c_str();
848 const char* CommandLine::getCLBuildOptions (void) const
850 if (m_cmdLine.hasOption<opt::CLBuildOptions>())
851 return m_cmdLine.getOption<opt::CLBuildOptions>().c_str();
856 const char* CommandLine::getEGLDisplayType (void) const
858 if (m_cmdLine.hasOption<opt::EGLDisplayType>())
859 return m_cmdLine.getOption<opt::EGLDisplayType>().c_str();
864 const char* CommandLine::getEGLWindowType (void) const
866 if (m_cmdLine.hasOption<opt::EGLWindowType>())
867 return m_cmdLine.getOption<opt::EGLWindowType>().c_str();
872 const char* CommandLine::getEGLPixmapType (void) const
874 if (m_cmdLine.hasOption<opt::EGLPixmapType>())
875 return m_cmdLine.getOption<opt::EGLPixmapType>().c_str();
880 static bool checkTestGroupName (const CaseTreeNode* root, const char* groupPath)
882 const CaseTreeNode* node = findNode(root, groupPath);
883 return node && node->hasChildren();
886 static bool checkTestCaseName (const CaseTreeNode* root, const char* casePath)
888 const CaseTreeNode* node = findNode(root, casePath);
889 return node && !node->hasChildren();
892 bool CommandLine::checkTestGroupName (const char* groupName) const
895 return m_casePaths->matches(groupName, true);
897 return groupName[0] == 0 || tcu::checkTestGroupName(m_caseTree, groupName);
902 bool CommandLine::checkTestCaseName (const char* caseName) const
905 return m_casePaths->matches(caseName, false);
907 return tcu::checkTestCaseName(m_caseTree, caseName);