13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program Test Executor
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 Extract values by name from logs.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "xeTestLogParser.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "xeTestResultParser.hpp"
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deFilePath.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deString.h"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <vector>
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <string>
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <cstdio>
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <cstdlib>
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <fstream>
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <iostream>
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <stdexcept>
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string;
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::set;
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::map;
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct CommandLine
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CommandLine (void)
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: statusCode(false)
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string			filename;
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<string>	tagNames;
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool			statusCode;
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef xe::ri::NumericValue Value;
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct CaseValues
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string				casePath;
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	xe::TestCaseType	caseType;
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	xe::TestStatusCode	statusCode;
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string				statusDetails;
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<Value>		values;
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass BatchResultValues
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	BatchResultValues (const vector<string>& tagNames)
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: m_tagNames(tagNames)
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	~BatchResultValues (void)
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (vector<CaseValues*>::iterator i = m_caseValues.begin(); i != m_caseValues.end(); ++i)
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			delete *i;
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void add (const CaseValues& result)
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CaseValues* copy = new CaseValues(result);
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		try
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_caseValues.push_back(copy);
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		catch (...)
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			delete copy;
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw;
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const vector<string>&	getTagNames		(void) const		{ return m_tagNames;			}
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	size_t					size			(void) const		{ return m_caseValues.size();	}
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CaseValues&		operator[]		(size_t ndx) const	{ return *m_caseValues[ndx];	}
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<string>		m_tagNames;
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<CaseValues*>	m_caseValues;
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Value findValueByTag (const xe::ri::List& items, const string& tagName)
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < items.getNumItems(); ndx++)
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const xe::ri::Item& item = items.getItem(ndx);
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (item.getType() == xe::ri::TYPE_SECTION)
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Value value = findValueByTag(static_cast<const xe::ri::Section&>(item).items, tagName);
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (value.getType() != Value::TYPE_EMPTY)
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return value;
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (item.getType() == xe::ri::TYPE_NUMBER)
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const xe::ri::Number& value = static_cast<const xe::ri::Number&>(item);
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return value.value;
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return Value();
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass TagParser : public xe::TestLogHandler
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TagParser (BatchResultValues& result)
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: m_result(result)
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void setSessionInfo (const xe::SessionInfo&)
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Ignored.
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	xe::TestCaseResultPtr startTestCaseResult (const char* casePath)
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return xe::TestCaseResultPtr(new xe::TestCaseResultData(casePath));
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void testCaseResultUpdated (const xe::TestCaseResultPtr&)
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Ignored.
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void testCaseResultComplete (const xe::TestCaseResultPtr& caseData)
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const vector<string>&	tagNames	= m_result.getTagNames();
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CaseValues				tagResult;
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tagResult.casePath		= caseData->getTestCasePath();
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tagResult.caseType		= xe::TESTCASETYPE_SELF_VALIDATE;
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tagResult.statusCode	= caseData->getStatusCode();
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tagResult.statusDetails	= caseData->getStatusDetails();
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tagResult.values.resize(tagNames.size());
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (caseData->getDataSize() > 0 && caseData->getStatusCode() == xe::TESTSTATUSCODE_LAST)
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			xe::TestCaseResult					fullResult;
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			xe::TestResultParser::ParseResult	parseResult;
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testResultParser.init(&fullResult);
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			parseResult = m_testResultParser.parse(caseData->getData(), caseData->getDataSize());
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if ((parseResult != xe::TestResultParser::PARSERESULT_ERROR && fullResult.statusCode != xe::TESTSTATUSCODE_LAST) ||
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				(tagResult.statusCode == xe::TESTSTATUSCODE_LAST && fullResult.statusCode != xe::TESTSTATUSCODE_LAST))
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tagResult.statusCode	= fullResult.statusCode;
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tagResult.statusDetails	= fullResult.statusDetails;
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if (tagResult.statusCode == xe::TESTSTATUSCODE_LAST)
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(parseResult == xe::TestResultParser::PARSERESULT_ERROR);
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tagResult.statusCode	= xe::TESTSTATUSCODE_INTERNAL_ERROR;
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tagResult.statusDetails	= "Test case result parsing failed";
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (parseResult != xe::TestResultParser::PARSERESULT_ERROR)
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int valNdx = 0; valNdx < (int)tagNames.size(); valNdx++)
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					tagResult.values[valNdx] = findValueByTag(fullResult.resultItems, tagNames[valNdx]);
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_result.add(tagResult);
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	BatchResultValues&		m_result;
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	xe::TestResultParser	m_testResultParser;
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void readLogFile (BatchResultValues& batchResult, const char* filename)
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ifstream		in				(filename, std::ifstream::binary|std::ifstream::in);
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TagParser			resultHandler	(batchResult);
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	xe::TestLogParser	parser			(&resultHandler);
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint8				buf				[1024];
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					numRead			= 0;
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!in.good())
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw std::runtime_error(string("Failed to open '") + filename + "'");
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (;;)
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		in.read((char*)&buf[0], DE_LENGTH_OF_ARRAY(buf));
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		numRead = (int)in.gcount();
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (numRead <= 0)
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		parser.parse(&buf[0], numRead);
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	in.close();
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void printTaggedValues (const CommandLine& cmdLine, std::ostream& dst)
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	BatchResultValues values(cmdLine.tagNames);
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	readLogFile(values, cmdLine.filename.c_str());
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Header
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dst << "CasePath";
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (cmdLine.statusCode)
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dst << ",StatusCode";
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (vector<string>::const_iterator tagName = values.getTagNames().begin(); tagName != values.getTagNames().end(); ++tagName)
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dst << "," << *tagName;
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dst << "\n";
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int resultNdx = 0; resultNdx < (int)values.size(); resultNdx++)
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const CaseValues& result = values[resultNdx];
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dst << result.casePath;
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (cmdLine.statusCode)
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dst << "," << xe::getTestStatusCodeName(result.statusCode);
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (vector<Value>::const_iterator value = result.values.begin(); value != result.values.end(); ++value)
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dst << "," << *value;
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dst << "\n";
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void printHelp (const char* binName)
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	printf("%s: [filename] [name 1] [[name 2]...]\n", binName);
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	printf(" --statuscode     Include status code as first entry.\n");
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool parseCommandLine (CommandLine& cmdLine, int argc, const char* const* argv)
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int argNdx = 1; argNdx < argc; argNdx++)
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char* arg = argv[argNdx];
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (deStringEqual(arg, "--statuscode"))
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			cmdLine.statusCode = true;
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (!deStringBeginsWith(arg, "--"))
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (cmdLine.filename.empty())
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				cmdLine.filename = arg;
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				cmdLine.tagNames.push_back(arg);
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (cmdLine.filename.empty())
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return true;
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint main (int argc, const char* const* argv)
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	try
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CommandLine cmdLine;
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!parseCommandLine(cmdLine, argc, argv))
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			printHelp(argv[0]);
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return -1;
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		printTaggedValues(cmdLine, std::cout);
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	catch (const std::exception& e)
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		printf("FATAL ERROR: %s\n", e.what());
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return -1;
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return 0;
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
307