13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*------------------------------------------------------------------------- 23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program Tester Core 33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ---------------------------------------- 43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project 63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License"); 83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License. 93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at 103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * http://www.apache.org/licenses/LICENSE-2.0 123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software 143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS, 153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and 173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License. 183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*! 203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file 213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Command line parsing. 223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuCommandLine.hpp" 253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuPlatform.hpp" 26ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos#include "tcuTestCase.hpp" 273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deFilePath.hpp" 283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp" 293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deString.h" 303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deInt32.h" 313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deCommandLine.h" 323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "qpTestLog.h" 333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "qpDebugOut.h" 343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <string> 363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <vector> 373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <sstream> 383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <fstream> 393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <iostream> 403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string; 423c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector; 433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// OOM tests are enabled by default only on platforms that don't do memory overcommit (Win32) 453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if (DE_OS == DE_OS_WIN32) 463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry# define TEST_OOM_DEFAULT "enable" 473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#else 483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry# define TEST_OOM_DEFAULT "disable" 493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif 503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 513c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace tcu 523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace opt 553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 573c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_DECLARE_COMMAND_LINE_OPT(CasePath, std::string); 583c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_DECLARE_COMMAND_LINE_OPT(CaseList, std::string); 593c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_DECLARE_COMMAND_LINE_OPT(CaseListFile, std::string); 603c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_DECLARE_COMMAND_LINE_OPT(StdinCaseList, bool); 613c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_DECLARE_COMMAND_LINE_OPT(LogFilename, std::string); 623c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_DECLARE_COMMAND_LINE_OPT(RunMode, tcu::RunMode); 633c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_DECLARE_COMMAND_LINE_OPT(WatchDog, bool); 643c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_DECLARE_COMMAND_LINE_OPT(CrashHandler, bool); 653c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_DECLARE_COMMAND_LINE_OPT(BaseSeed, int); 663c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_DECLARE_COMMAND_LINE_OPT(TestIterationCount, int); 673c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_DECLARE_COMMAND_LINE_OPT(Visibility, WindowVisibility); 683c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_DECLARE_COMMAND_LINE_OPT(SurfaceWidth, int); 693c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_DECLARE_COMMAND_LINE_OPT(SurfaceHeight, int); 703c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_DECLARE_COMMAND_LINE_OPT(SurfaceType, tcu::SurfaceType); 713c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_DECLARE_COMMAND_LINE_OPT(ScreenRotation, tcu::ScreenRotation); 723c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_DECLARE_COMMAND_LINE_OPT(GLContextType, std::string); 733c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_DECLARE_COMMAND_LINE_OPT(GLConfigID, int); 743c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_DECLARE_COMMAND_LINE_OPT(GLConfigName, std::string); 753c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_DECLARE_COMMAND_LINE_OPT(GLContextFlags, std::string); 763c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_DECLARE_COMMAND_LINE_OPT(CLPlatformID, int); 773c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_DECLARE_COMMAND_LINE_OPT(CLDeviceIDs, std::vector<int>); 783c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_DECLARE_COMMAND_LINE_OPT(CLBuildOptions, std::string); 793c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_DECLARE_COMMAND_LINE_OPT(EGLDisplayType, std::string); 803c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_DECLARE_COMMAND_LINE_OPT(EGLWindowType, std::string); 813c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_DECLARE_COMMAND_LINE_OPT(EGLPixmapType, std::string); 823c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_DECLARE_COMMAND_LINE_OPT(LogImages, bool); 833c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_DECLARE_COMMAND_LINE_OPT(TestOOM, bool); 843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void parseIntList (const char* src, std::vector<int>* dst) 863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::istringstream str (src); 883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string val; 893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry while (std::getline(str, val, ',')) 913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int intVal = 0; 933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry de::cmdline::parseType(val.c_str(), &intVal); 943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst->push_back(intVal); 953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 983c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid registerOptions (de::cmdline::Parser& parser) 993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry using de::cmdline::Option; 1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry using de::cmdline::NamedValue; 1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const NamedValue<bool> s_enableNames[] = 1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "enable", true }, 1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "disable", false } 1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const NamedValue<tcu::RunMode> s_runModes[] = 1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "execute", RUNMODE_EXECUTE }, 1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "xml-caselist", RUNMODE_DUMP_XML_CASELIST }, 1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "txt-caselist", RUNMODE_DUMP_TEXT_CASELIST } 1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const NamedValue<WindowVisibility> s_visibilites[] = 1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "windowed", WINDOWVISIBILITY_WINDOWED }, 1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "fullscreen", WINDOWVISIBILITY_FULLSCREEN }, 1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "hidden", WINDOWVISIBILITY_HIDDEN } 1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const NamedValue<tcu::SurfaceType> s_surfaceTypes[] = 1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "window", SURFACETYPE_WINDOW }, 1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "pixmap", SURFACETYPE_OFFSCREEN_NATIVE }, 1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "pbuffer", SURFACETYPE_OFFSCREEN_GENERIC }, 1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "fbo", SURFACETYPE_FBO } 1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const NamedValue<tcu::ScreenRotation> s_screenRotations[] = 1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1292dac2cccd65e5f837c3433c73c54790e6d0903d3Pyry Haulos { "unspecified", SCREENROTATION_UNSPECIFIED }, 1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "0", SCREENROTATION_0 }, 1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "90", SCREENROTATION_90 }, 1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "180", SCREENROTATION_180 }, 1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "270", SCREENROTATION_270 } 1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry parser 1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << Option<CasePath> ("n", "deqp-case", "Test case(s) to run, supports wildcards (e.g. dEQP-GLES2.info.*)") 1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << Option<CaseList> (DE_NULL, "deqp-caselist", "Case list to run in trie format (e.g. {dEQP-GLES2{info{version,renderer}}})") 1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << Option<CaseListFile> (DE_NULL, "deqp-caselist-file", "Read case list (in trie format) from given file") 1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << Option<StdinCaseList> (DE_NULL, "deqp-stdin-caselist", "Read case list (in trie format) from stdin") 1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << Option<LogFilename> (DE_NULL, "deqp-log-filename", "Write test results to given file", "TestResults.qpa") 1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << Option<RunMode> (DE_NULL, "deqp-runmode", "Execute tests, or write list of test cases into a file", 143ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos s_runModes, "execute") 1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << Option<WatchDog> (DE_NULL, "deqp-watchdog", "Enable test watchdog", s_enableNames, "disable") 1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << Option<CrashHandler> (DE_NULL, "deqp-crashhandler", "Enable crash handling", s_enableNames, "disable") 146ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos << Option<BaseSeed> (DE_NULL, "deqp-base-seed", "Base seed for test cases that use randomization", "0") 147ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos << Option<TestIterationCount> (DE_NULL, "deqp-test-iteration-count", "Iteration count for cases that support variable number of iterations", "0") 1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << Option<Visibility> (DE_NULL, "deqp-visibility", "Default test window visibility", s_visibilites, "windowed") 149ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos << Option<SurfaceWidth> (DE_NULL, "deqp-surface-width", "Use given surface width if possible", "-1") 150ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos << Option<SurfaceHeight> (DE_NULL, "deqp-surface-height", "Use given surface height if possible", "-1") 1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << Option<SurfaceType> (DE_NULL, "deqp-surface-type", "Use given surface type", s_surfaceTypes, "window") 1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << Option<ScreenRotation> (DE_NULL, "deqp-screen-rotation", "Screen rotation for platforms that support it", s_screenRotations, "0") 1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << Option<GLContextType> (DE_NULL, "deqp-gl-context-type", "OpenGL context type for platforms that support multiple") 154ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos << Option<GLConfigID> (DE_NULL, "deqp-gl-config-id", "OpenGL (ES) render config ID (EGL config id on EGL platforms)", "-1") 1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << Option<GLConfigName> (DE_NULL, "deqp-gl-config-name", "Symbolic OpenGL (ES) render config name") 1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << Option<GLContextFlags> (DE_NULL, "deqp-gl-context-flags", "OpenGL context flags (comma-separated, supports debug and robust)") 157ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos << Option<CLPlatformID> (DE_NULL, "deqp-cl-platform-id", "Execute tests on given OpenCL platform (IDs start from 1)", "1") 158ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos << Option<CLDeviceIDs> (DE_NULL, "deqp-cl-device-ids", "Execute tests on given CL devices (comma-separated, IDs start from 1)", parseIntList, "") 1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << Option<CLBuildOptions> (DE_NULL, "deqp-cl-build-options", "Extra build options for OpenCL compiler") 1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << Option<EGLDisplayType> (DE_NULL, "deqp-egl-display-type", "EGL native display type") 1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << Option<EGLWindowType> (DE_NULL, "deqp-egl-window-type", "EGL native window type") 1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << Option<EGLPixmapType> (DE_NULL, "deqp-egl-pixmap-type", "EGL native pixmap type") 1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << Option<LogImages> (DE_NULL, "deqp-log-images", "Enable or disable logging of result images", s_enableNames, "enable") 1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << Option<TestOOM> (DE_NULL, "deqp-test-oom", "Run tests that exhaust memory on purpose", s_enableNames, TEST_OOM_DEFAULT); 1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid registerLegacyOptions (de::cmdline::Parser& parser) 1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry using de::cmdline::Option; 1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry parser 1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << Option<GLConfigID> (DE_NULL, "deqp-egl-config-id", "Legacy name for --deqp-gl-config-id", "-1") 1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << Option<GLConfigName> (DE_NULL, "deqp-egl-config-name", "Legacy name for --deqp-gl-config-name"); 1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // opt 1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \todo [2014-02-13 pyry] This could be useful elsewhere as well. 1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass DebugOutStreambuf : public std::streambuf 1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DebugOutStreambuf (void); 1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ~DebugOutStreambuf (void); 1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::streamsize xsputn (const char* s, std::streamsize count); 1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int overflow (int ch = -1); 1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void flushLine (void); 1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream m_curLine; 1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1953c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDebugOutStreambuf::DebugOutStreambuf (void) 1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1993c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDebugOutStreambuf::~DebugOutStreambuf (void) 2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_curLine.tellp() != std::streampos(0)) 2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry flushLine(); 2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::streamsize DebugOutStreambuf::xsputn (const char* s, std::streamsize count) 2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (std::streamsize pos = 0; pos < count; pos++) 2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_curLine.put(s[pos]); 2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (s[pos] == '\n') 2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry flushLine(); 2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return count; 2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint DebugOutStreambuf::overflow (int ch) 2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (ch == -1) 2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return -1; 2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT((ch & 0xff) == ch); 2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char chVal = (char)(deUint8)(ch & 0xff); 2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return xsputn(&chVal, 1) == 1 ? ch : -1; 2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid DebugOutStreambuf::flushLine (void) 2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry qpPrint(m_curLine.str().c_str()); 2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_curLine.str(""); 2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass CaseTreeNode 2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CaseTreeNode (const std::string& name) : m_name(name) {} 2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ~CaseTreeNode (void); 2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 242ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos const std::string& getName (void) const { return m_name; } 243ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos bool hasChildren (void) const { return !m_children.empty(); } 244ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos 245ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos bool hasChild (const std::string& name) const; 246ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos const CaseTreeNode* getChild (const std::string& name) const; 247ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos CaseTreeNode* getChild (const std::string& name); 2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 249ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos void addChild (CaseTreeNode* child) { m_children.push_back(child); } 2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CaseTreeNode (const CaseTreeNode&); 2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CaseTreeNode& operator= (const CaseTreeNode&); 2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 255ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos enum { NOT_FOUND = -1 }; 256ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos 257ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos // \todo [2014-10-30 pyry] Speed up with hash / sorting 258ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos int findChildNdx (const std::string& name) const; 259ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos 2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string m_name; 2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<CaseTreeNode*> m_children; 2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2643c827367444ee418f129b2c238299f49d3264554Jarkko PoyryCaseTreeNode::~CaseTreeNode (void) 2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (vector<CaseTreeNode*>::const_iterator i = m_children.begin(); i != m_children.end(); ++i) 2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete *i; 2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 270ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulosint CaseTreeNode::findChildNdx (const std::string& name) const 271ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos{ 272ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos for (int ndx = 0; ndx < (int)m_children.size(); ++ndx) 273ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos { 274ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos if (m_children[ndx]->getName() == name) 275ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos return ndx; 276ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos } 277ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos return NOT_FOUND; 278ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos} 279ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos 280ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulosinline bool CaseTreeNode::hasChild (const std::string& name) const 281ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos{ 282ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos return findChildNdx(name) != NOT_FOUND; 283ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos} 284ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos 285ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulosinline const CaseTreeNode* CaseTreeNode::getChild (const std::string& name) const 286ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos{ 287ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos const int ndx = findChildNdx(name); 288ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos return ndx == NOT_FOUND ? DE_NULL : m_children[ndx]; 289ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos} 290ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos 291ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulosinline CaseTreeNode* CaseTreeNode::getChild (const std::string& name) 292ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos{ 293ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos const int ndx = findChildNdx(name); 294ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos return ndx == NOT_FOUND ? DE_NULL : m_children[ndx]; 295ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos} 296ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos 297ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulosstatic int getCurrentComponentLen (const char* path) 298ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos{ 299ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos int ndx = 0; 300ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos for (; path[ndx] != 0 && path[ndx] != '.'; ++ndx); 301ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos return ndx; 302ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos} 303ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos 304ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulosstatic const CaseTreeNode* findNode (const CaseTreeNode* root, const char* path) 305ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos{ 306ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos const CaseTreeNode* curNode = root; 307ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos const char* curPath = path; 308ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos int curLen = getCurrentComponentLen(curPath); 309ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos 310ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos for (;;) 311ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos { 312ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos curNode = curNode->getChild(std::string(curPath, curPath+curLen)); 313ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos 314ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos if (!curNode) 315ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos break; 316ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos 317ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos curPath += curLen; 318ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos 319ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos if (curPath[0] == 0) 320ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos break; 321ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos else 322ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos { 323ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos DE_ASSERT(curPath[0] == '.'); 324ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos curPath += 1; 325ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos curLen = getCurrentComponentLen(curPath); 326ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos } 327ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos } 328ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos 329ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos return curNode; 330ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos} 331ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos 332ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulosstatic void parseCaseTrie (CaseTreeNode* root, std::istream& in) 3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<CaseTreeNode*> nodeStack; 3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string curName; 336ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos bool expectNode = true; 3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (in.get() != '{') 339ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos throw std::invalid_argument("Malformed case trie"); 3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 341ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos nodeStack.push_back(root); 3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 343ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos while (!nodeStack.empty()) 3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 345ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos const int curChr = in.get(); 346ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos 347ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos if (curChr == std::char_traits<char>::eof() || curChr == 0) 348ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos throw std::invalid_argument("Unterminated case tree"); 349ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos 350ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos if (curChr == '{' || curChr == ',' || curChr == '}') 3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 352ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos if (!curName.empty() && expectNode) 353ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos { 354ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos CaseTreeNode* const newChild = new CaseTreeNode(curName); 3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 356ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos try 357ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos { 358ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos nodeStack.back()->addChild(newChild); 359ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos } 360ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos catch (...) 361ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos { 362ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos delete newChild; 363ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos throw; 364ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos } 3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 366ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos if (curChr == '{') 367ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos nodeStack.push_back(newChild); 3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 369ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos curName.clear(); 370ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos } 371ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos else if (curName.empty() == expectNode) 372ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos throw std::invalid_argument(expectNode ? "Empty node name" : "Missing node separator"); 373ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos 374ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos if (curChr == '}') 3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 376ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos expectNode = false; 377ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos nodeStack.pop_back(); 378831962c779a19a1822b0074012763b604ac42d24Jarkko Pöyry 379831962c779a19a1822b0074012763b604ac42d24Jarkko Pöyry // consume trailing new line 380831962c779a19a1822b0074012763b604ac42d24Jarkko Pöyry if (nodeStack.empty()) 381831962c779a19a1822b0074012763b604ac42d24Jarkko Pöyry { 382831962c779a19a1822b0074012763b604ac42d24Jarkko Pöyry if (in.peek() == '\r') 383831962c779a19a1822b0074012763b604ac42d24Jarkko Pöyry in.get(); 384831962c779a19a1822b0074012763b604ac42d24Jarkko Pöyry if (in.peek() == '\n') 385831962c779a19a1822b0074012763b604ac42d24Jarkko Pöyry in.get(); 386831962c779a19a1822b0074012763b604ac42d24Jarkko Pöyry } 387ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos } 388ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos else 389ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos expectNode = true; 390ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos } 391ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos else if (isValidTestCaseNameChar((char)curChr)) 392ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos curName += (char)curChr; 393ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos else 394ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos throw std::invalid_argument("Illegal character in node name"); 395ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos } 396ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos} 3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 398ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulosstatic void parseCaseList (CaseTreeNode* root, std::istream& in) 399ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos{ 400ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos // \note Algorithm assumes that cases are sorted by groups, but will 401ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos // function fine, albeit more slowly, if that is not the case. 402ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos vector<CaseTreeNode*> nodeStack; 403ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos int stackPos = 0; 404ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos string curName; 405ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos 406ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos nodeStack.resize(8, DE_NULL); 407ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos 408ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos nodeStack[0] = root; 409ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos 410ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos for (;;) 411ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos { 412ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos const int curChr = in.get(); 413ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos 414ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos if (curChr == std::char_traits<char>::eof() || curChr == 0 || curChr == '\n' || curChr == '\r') 415ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos { 416ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos if (curName.empty()) 417ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos throw std::invalid_argument("Empty test case name"); 418ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos 419ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos if (nodeStack[stackPos]->hasChild(curName)) 420ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos throw std::invalid_argument("Duplicate test case"); 421ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos 422ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos CaseTreeNode* const newChild = new CaseTreeNode(curName); 423ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos 424ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos try 425ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos { 426ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos nodeStack[stackPos]->addChild(newChild); 4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 428ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos catch (...) 429ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos { 430ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos delete newChild; 431ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos throw; 432ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos } 433ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos 434ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos curName.clear(); 435ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos stackPos = 0; 436ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos 437ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos if (curChr == '\r' && in.peek() == '\n') 438ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos in.get(); 4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 441ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos const int nextChr = in.peek(); 4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 443ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos if (nextChr == std::char_traits<char>::eof() || nextChr == 0) 444ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos break; 4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 447ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos else if (curChr == '.') 448ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos { 449ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos if (curName.empty()) 450ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos throw std::invalid_argument("Empty test group name"); 4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 452ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos if ((int)nodeStack.size() <= stackPos+1) 453ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos nodeStack.resize(nodeStack.size()*2, DE_NULL); 454ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos 455ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos if (!nodeStack[stackPos+1] || nodeStack[stackPos+1]->getName() != curName) 456ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos { 457ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos CaseTreeNode* curGroup = nodeStack[stackPos]->getChild(curName); 458ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos 459ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos if (!curGroup) 460ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos { 461ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos curGroup = new CaseTreeNode(curName); 462ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos 463ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos try 464ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos { 465ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos nodeStack[stackPos]->addChild(curGroup); 466ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos } 467ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos catch (...) 468ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos { 469ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos delete curGroup; 470ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos throw; 471ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos } 472ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos } 473ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos 474ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos nodeStack[stackPos+1] = curGroup; 475ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos 476ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos if ((int)nodeStack.size() > stackPos+2) 477ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos nodeStack[stackPos+2] = DE_NULL; // Invalidate rest of entries 478ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos } 479ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos 480ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos DE_ASSERT(nodeStack[stackPos+1]->getName() == curName); 481ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos 482ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos curName.clear(); 483ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos stackPos += 1; 484ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos } 485ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos else if (isValidTestCaseNameChar((char)curChr)) 486ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos curName += (char)curChr; 487ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos else 488ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos throw std::invalid_argument("Illegal character in test case name"); 4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 490ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos} 491ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos 492ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulosstatic CaseTreeNode* parseCaseList (std::istream& in) 493ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos{ 494ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos CaseTreeNode* const root = new CaseTreeNode(""); 495ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos try 4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 497ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos if (in.peek() == '{') 498ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos parseCaseTrie(root, in); 499ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos else 500ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos parseCaseList(root, in); 501ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos 502ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos { 503ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos const int curChr = in.get(); 504ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos if (curChr != std::char_traits<char>::eof() && curChr != 0) 505ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos throw std::invalid_argument("Trailing characters at end of case list"); 506ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos } 5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 508ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos return root; 509ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos } 510ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos catch (...) 511ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos { 512ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos delete root; 5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw; 5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass CasePaths 5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CasePaths (const string& pathList); 5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool matches (const string& caseName, bool allowPrefix=false) const; 5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<string> m_casePatterns; 5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5273c827367444ee418f129b2c238299f49d3264554Jarkko PoyryCasePaths::CasePaths (const string& pathList) 5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_casePatterns(de::splitString(pathList, ',')) 5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Match a single path component against a pattern component that may contain *-wildcards. 5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool matchWildcards(string::const_iterator patternStart, 5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string::const_iterator patternEnd, 5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string::const_iterator pathStart, 5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string::const_iterator pathEnd, 5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool allowPrefix) 5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string::const_iterator pattern = patternStart; 5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string::const_iterator path = pathStart; 5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry while (pattern != patternEnd && path != pathEnd && *pattern == *path) 5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ++pattern; 5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ++path; 5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (pattern == patternEnd) 5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return (path == pathEnd); 5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (*pattern == '*') 5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (; path != pathEnd; ++path) 5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (matchWildcards(pattern + 1, patternEnd, path, pathEnd, allowPrefix)) 5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (matchWildcards(pattern + 1, patternEnd, pathEnd, pathEnd, allowPrefix)) 5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (path == pathEnd && allowPrefix) 5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(TCU_HIERARCHICAL_CASEPATHS) 5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Match a list of pattern components to a list of path components. A pattern 5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// component may contain *-wildcards. A pattern component "**" matches zero or 5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// more whole path components. 5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool patternMatches(vector<string>::const_iterator patternStart, 5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<string>::const_iterator patternEnd, 5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<string>::const_iterator pathStart, 5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<string>::const_iterator pathEnd, 5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool allowPrefix) 5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<string>::const_iterator pattern = patternStart; 5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<string>::const_iterator path = pathStart; 5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry while (pattern != patternEnd && path != pathEnd && *pattern != "**" && 5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (*pattern == *path || matchWildcards(pattern->begin(), pattern->end(), 5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry path->begin(), path->end(), false))) 5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ++pattern; 5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ++path; 5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (path == pathEnd && (allowPrefix || pattern == patternEnd)) 5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (pattern != patternEnd && *pattern == "**") 5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (; path != pathEnd; ++path) 5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (patternMatches(pattern + 1, patternEnd, path, pathEnd, allowPrefix)) 5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (patternMatches(pattern + 1, patternEnd, path, pathEnd, allowPrefix)) 5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif 6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool CasePaths::matches (const string& caseName, bool allowPrefix) const 6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<string> components = de::splitString(caseName, '.'); 6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t ndx = 0; ndx < m_casePatterns.size(); ++ndx) 6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(TCU_HIERARCHICAL_CASEPATHS) 6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<string> patternComponents = de::splitString(m_casePatterns[ndx], '.'); 6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (patternMatches(patternComponents.begin(), patternComponents.end(), 6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry components.begin(), components.end(), allowPrefix)) 6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#else 6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (matchWildcards(m_casePatterns[ndx].begin(), m_casePatterns[ndx].end(), 6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry caseName.begin(), caseName.end(), allowPrefix)) 6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif 6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Construct command line 6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \note CommandLine is not fully initialized until parse() has been called. 6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 6293c827367444ee418f129b2c238299f49d3264554Jarkko PoyryCommandLine::CommandLine (void) 6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_logFlags (0) 6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_caseTree (DE_NULL) 6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Construct command line from standard argc, argv pair. 6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Calls parse() with given arguments 6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param argc Number of arguments 6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param argv Command line arguments 6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 6423c827367444ee418f129b2c238299f49d3264554Jarkko PoyryCommandLine::CommandLine (int argc, const char* const* argv) 6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_logFlags (0) 6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_caseTree (DE_NULL) 6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!parse(argc, argv)) 6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw Exception("Failed to parse command line"); 6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Construct command line from string. 6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Calls parse() with given argument. 6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param cmdLine Full command line string. 6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 6563c827367444ee418f129b2c238299f49d3264554Jarkko PoyryCommandLine::CommandLine (const std::string& cmdLine) 6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_logFlags (0) 6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_caseTree (DE_NULL) 6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!parse(cmdLine)) 6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw Exception("Failed to parse command line"); 6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6643c827367444ee418f129b2c238299f49d3264554Jarkko PoyryCommandLine::~CommandLine (void) 6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete m_caseTree; 6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid CommandLine::clear (void) 6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_cmdLine.clear(); 6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_logFlags = 0; 6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete m_caseTree; 6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_caseTree = DE_NULL; 6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 678bf44c5c30440b0c7a8c7c87f2b7c3ff984e77018Jarkko Pöyryconst de::cmdline::CommandLine& CommandLine::getCommandLine (void) const 679bf44c5c30440b0c7a8c7c87f2b7c3ff984e77018Jarkko Pöyry{ 680bf44c5c30440b0c7a8c7c87f2b7c3ff984e77018Jarkko Pöyry return m_cmdLine; 681bf44c5c30440b0c7a8c7c87f2b7c3ff984e77018Jarkko Pöyry} 682bf44c5c30440b0c7a8c7c87f2b7c3ff984e77018Jarkko Pöyry 683bf44c5c30440b0c7a8c7c87f2b7c3ff984e77018Jarkko Pöyryvoid CommandLine::registerExtendedOptions (de::cmdline::Parser& parser) 684bf44c5c30440b0c7a8c7c87f2b7c3ff984e77018Jarkko Pöyry{ 685bf44c5c30440b0c7a8c7c87f2b7c3ff984e77018Jarkko Pöyry DE_UNREF(parser); 686bf44c5c30440b0c7a8c7c87f2b7c3ff984e77018Jarkko Pöyry} 687bf44c5c30440b0c7a8c7c87f2b7c3ff984e77018Jarkko Pöyry 6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Parse command line from standard argc, argv pair. 6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \note parse() must be called exactly once. 6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param argc Number of arguments 6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param argv Command line arguments 6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool CommandLine::parse (int argc, const char* const* argv) 6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DebugOutStreambuf sbuf; 6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostream debugOut (&sbuf); 6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry de::cmdline::Parser parser; 6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry opt::registerOptions(parser); 7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry opt::registerLegacyOptions(parser); 702bf44c5c30440b0c7a8c7c87f2b7c3ff984e77018Jarkko Pöyry registerExtendedOptions(parser); 7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry clear(); 7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!parser.parse(argc-1, argv+1, &m_cmdLine, std::cerr)) 7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry debugOut << "\n" << de::FilePath(argv[0]).getBaseName() << " [options]\n\n"; 7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry parser.help(debugOut); 7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry clear(); 7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_cmdLine.getOption<opt::LogImages>()) 7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_logFlags |= QP_TEST_LOG_EXCLUDE_IMAGES; 7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 718ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos if ((m_cmdLine.hasOption<opt::CasePath>()?1:0) + 719ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos (m_cmdLine.hasOption<opt::CaseList>()?1:0) + 720ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos (m_cmdLine.hasOption<opt::CaseListFile>()?1:0) + 7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (m_cmdLine.getOption<opt::StdinCaseList>()?1:0) > 1) 7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry debugOut << "ERROR: multiple test case list options given!\n" << std::endl; 7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry clear(); 7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry try 7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 730ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos if (m_cmdLine.hasOption<opt::CaseList>()) 7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::istringstream str(m_cmdLine.getOption<opt::CaseList>()); 7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 734ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos m_caseTree = parseCaseList(str); 7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 736ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos else if (m_cmdLine.hasOption<opt::CaseListFile>()) 7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ifstream in(m_cmdLine.getOption<opt::CaseListFile>().c_str(), std::ios_base::binary); 7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!in.is_open() || !in.good()) 7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw Exception("Failed to open case list file '" + m_cmdLine.getOption<opt::CaseListFile>() + "'"); 7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 743ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos m_caseTree = parseCaseList(in); 7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_cmdLine.getOption<opt::StdinCaseList>()) 7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 747ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos m_caseTree = parseCaseList(std::cin); 7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 749ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos else if (m_cmdLine.hasOption<opt::CasePath>()) 7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_casePaths = de::MovePtr<const CasePaths>(new CasePaths(m_cmdLine.getOption<opt::CasePath>())); 7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry catch (const std::exception& e) 7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry debugOut << "ERROR: Failed to parse test case list: " << e.what() << "\n"; 7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry clear(); 7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Parse command line from string. 7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \note parse() must be called exactly once. 7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param cmdLine Full command line string. 7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool CommandLine::parse (const std::string& cmdLine) 7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deCommandLine* parsedCmdLine = deCommandLine_parse(cmdLine.c_str()); 7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!parsedCmdLine) 7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw std::bad_alloc(); 7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool isOk = false; 7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry try 7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry isOk = parse(parsedCmdLine->numArgs, parsedCmdLine->args); 7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry catch (...) 7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deCommandLine_destroy(parsedCmdLine); 7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw; 7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deCommandLine_destroy(parsedCmdLine); 7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return isOk; 7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* CommandLine::getLogFileName (void) const { return m_cmdLine.getOption<opt::LogFilename>().c_str(); } 7893c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeUint32 CommandLine::getLogFlags (void) const { return m_logFlags; } 7903c827367444ee418f129b2c238299f49d3264554Jarkko PoyryRunMode CommandLine::getRunMode (void) const { return m_cmdLine.getOption<opt::RunMode>(); } 7913c827367444ee418f129b2c238299f49d3264554Jarkko PoyryWindowVisibility CommandLine::getVisibility (void) const { return m_cmdLine.getOption<opt::Visibility>(); } 7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool CommandLine::isWatchDogEnabled (void) const { return m_cmdLine.getOption<opt::WatchDog>(); } 7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool CommandLine::isCrashHandlingEnabled (void) const { return m_cmdLine.getOption<opt::CrashHandler>(); } 7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint CommandLine::getBaseSeed (void) const { return m_cmdLine.getOption<opt::BaseSeed>(); } 7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint CommandLine::getTestIterationCount (void) const { return m_cmdLine.getOption<opt::TestIterationCount>(); } 7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint CommandLine::getSurfaceWidth (void) const { return m_cmdLine.getOption<opt::SurfaceWidth>(); } 7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint CommandLine::getSurfaceHeight (void) const { return m_cmdLine.getOption<opt::SurfaceHeight>(); } 7983c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySurfaceType CommandLine::getSurfaceType (void) const { return m_cmdLine.getOption<opt::SurfaceType>(); } 7993c827367444ee418f129b2c238299f49d3264554Jarkko PoyryScreenRotation CommandLine::getScreenRotation (void) const { return m_cmdLine.getOption<opt::ScreenRotation>(); } 8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint CommandLine::getGLConfigId (void) const { return m_cmdLine.getOption<opt::GLConfigID>(); } 8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint CommandLine::getCLPlatformId (void) const { return m_cmdLine.getOption<opt::CLPlatformID>(); } 8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst std::vector<int>& CommandLine::getCLDeviceIds (void) const { return m_cmdLine.getOption<opt::CLDeviceIDs>(); } 8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool CommandLine::isOutOfMemoryTestEnabled (void) const { return m_cmdLine.getOption<opt::TestOOM>(); } 8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* CommandLine::getGLContextType (void) const 8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 807ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos if (m_cmdLine.hasOption<opt::GLContextType>()) 8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return m_cmdLine.getOption<opt::GLContextType>().c_str(); 8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_NULL; 8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* CommandLine::getGLConfigName (void) const 8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 814ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos if (m_cmdLine.hasOption<opt::GLConfigName>()) 8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return m_cmdLine.getOption<opt::GLConfigName>().c_str(); 8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_NULL; 8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* CommandLine::getGLContextFlags (void) const 8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 822ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos if (m_cmdLine.hasOption<opt::GLContextFlags>()) 8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return m_cmdLine.getOption<opt::GLContextFlags>().c_str(); 8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_NULL; 8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* CommandLine::getCLBuildOptions (void) const 8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 830ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos if (m_cmdLine.hasOption<opt::CLBuildOptions>()) 8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return m_cmdLine.getOption<opt::CLBuildOptions>().c_str(); 8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_NULL; 8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 836ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulosconst char* CommandLine::getEGLDisplayType (void) const 8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 838ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos if (m_cmdLine.hasOption<opt::EGLDisplayType>()) 839ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos return m_cmdLine.getOption<opt::EGLDisplayType>().c_str(); 840ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos else 841ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos return DE_NULL; 8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 844ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulosconst char* CommandLine::getEGLWindowType (void) const 8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 846ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos if (m_cmdLine.hasOption<opt::EGLWindowType>()) 847ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos return m_cmdLine.getOption<opt::EGLWindowType>().c_str(); 848ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos else 849ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos return DE_NULL; 850ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos} 8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 852ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulosconst char* CommandLine::getEGLPixmapType (void) const 853ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos{ 854ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos if (m_cmdLine.hasOption<opt::EGLPixmapType>()) 855ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos return m_cmdLine.getOption<opt::EGLPixmapType>().c_str(); 856ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos else 857ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos return DE_NULL; 858ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos} 8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 860ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulosstatic bool checkTestGroupName (const CaseTreeNode* root, const char* groupPath) 861ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos{ 862ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos const CaseTreeNode* node = findNode(root, groupPath); 863ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos return node && node->hasChildren(); 864ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos} 8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 866ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulosstatic bool checkTestCaseName (const CaseTreeNode* root, const char* casePath) 867ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos{ 868ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos const CaseTreeNode* node = findNode(root, casePath); 869ee2e173d445e87e1f98245f4377f66b081cc320dPyry Haulos return node && !node->hasChildren(); 8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool CommandLine::checkTestGroupName (const char* groupName) const 8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_casePaths) 8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return m_casePaths->matches(groupName, true); 8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_caseTree) 8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return groupName[0] == 0 || tcu::checkTestGroupName(m_caseTree, groupName); 8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool CommandLine::checkTestCaseName (const char* caseName) const 8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_casePaths) 8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return m_casePaths->matches(caseName, false); 8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_caseTree) 8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return tcu::checkTestCaseName(m_caseTree, caseName); 8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // tcu 893