127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi/*-------------------------------------------------------------------------
227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * drawElements Quality Program Test Executor
327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * ------------------------------------------
427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi *
527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * Copyright 2014 The Android Open Source Project
627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi *
727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * Licensed under the Apache License, Version 2.0 (the "License");
827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * you may not use this file except in compliance with the License.
927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * You may obtain a copy of the License at
1027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi *
1127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi *      http://www.apache.org/licenses/LICENSE-2.0
1227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi *
1327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * Unless required by applicable law or agreed to in writing, software
1427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * distributed under the License is distributed on an "AS IS" BASIS,
1527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * See the License for the specific language governing permissions and
1727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * limitations under the License.
1827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi *
1927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi *//*!
2027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * \file
2127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * \brief Extract shader programs from log.
2227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi *//*--------------------------------------------------------------------*/
2327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
2427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include "xeTestLogParser.hpp"
2527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include "xeTestResultParser.hpp"
2627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include "deFilePath.hpp"
2727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include "deStringUtil.hpp"
2827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include "deString.h"
2927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
3027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include <vector>
3127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include <string>
3227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include <cstdio>
3327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include <cstdlib>
3427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include <fstream>
3527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include <iostream>
3627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include <stdexcept>
3727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
3827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiusing std::vector;
393473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimiusing std::string;
403473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimiusing std::set;
4127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiusing std::map;
4227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
4327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshistruct CommandLine
4427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi{
4527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	CommandLine (void)
4627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	{
4727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	}
4827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
4927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	string		filename;
5027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	string		dstPath;
512272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi};
5227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
5327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshistatic const char* getShaderTypeSuffix (const xe::ri::Shader::ShaderType shaderType)
5427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi{
5527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	switch (shaderType)
5627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	{
5727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi		case xe::ri::Shader::SHADERTYPE_VERTEX:				return "vert";
5827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi		case xe::ri::Shader::SHADERTYPE_FRAGMENT:			return "frag";
5927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi		case xe::ri::Shader::SHADERTYPE_GEOMETRY:			return "geom";
6027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi		case xe::ri::Shader::SHADERTYPE_TESS_CONTROL:		return "tesc";
6127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi		case xe::ri::Shader::SHADERTYPE_TESS_EVALUATION:	return "tese";
622272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi		case xe::ri::Shader::SHADERTYPE_COMPUTE:			return "comp";
6327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi		default:
642272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi			throw xe::Error("Invalid shader type");
65a2cd44cb5067b4fe98794860690394254d3ac73cGloria Wang	}
6627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
6727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
6827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshistatic void writeShaderProgram (const CommandLine& cmdLine, const std::string& casePath, const xe::ri::ShaderProgram& shaderProgram, int programNdx)
6927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi{
702272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi	const string basePath = string(de::FilePath::join(cmdLine.dstPath, casePath).getPath()) + "." + de::toString(programNdx);
7127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
722272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi	for (int shaderNdx = 0; shaderNdx < shaderProgram.shaders.getNumItems(); shaderNdx++)
7327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	{
742272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi		const xe::ri::Shader&	shader		= dynamic_cast<const xe::ri::Shader&>(shaderProgram.shaders.getItem(shaderNdx));
7527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi		const string			shaderPath	= basePath + "." + getShaderTypeSuffix(shader.shaderType);
7627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
7727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi		if (de::FilePath(shaderPath).exists())
7827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi			throw xe::Error("File '" + shaderPath + "' exists already");
7927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
8027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi		{
8127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi			std::ofstream out(shaderPath.c_str(), std::ifstream::binary|std::ifstream::out);
8227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
839d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong			if (!out.good())
849d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong				throw xe::Error("Failed to open '" + shaderPath + "'");
8527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
86e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi			out.write(shader.source.source.c_str(), shader.source.source.size());
879d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong		}
889d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong	}
89e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi}
902272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi
9127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshistruct StackEntry
922272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi{
9327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	const xe::ri::List*		list;
9427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	int						curNdx;
952272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi
962272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi	explicit StackEntry (const xe::ri::List* list_) : list(list_), curNdx(0) {}
9727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi};
982272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi
9927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshistatic void extractShaderPrograms (const CommandLine& cmdLine, const std::string& casePath, const xe::TestCaseResult& result)
10027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi{
101a2cd44cb5067b4fe98794860690394254d3ac73cGloria Wang	vector<StackEntry>	itemListStack;
10227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	int					programNdx		= 0;
10327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
10427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	itemListStack.push_back(StackEntry(&result.resultItems));
10527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
10627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	while (!itemListStack.empty())
10727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	{
10827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi		StackEntry& curEntry = itemListStack.back();
10927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
11027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi		if (curEntry.curNdx < curEntry.list->getNumItems())
11127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi		{
11227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi			const xe::ri::Item&	curItem	= curEntry.list->getItem(curEntry.curNdx);
11327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi			curEntry.curNdx += 1;
11427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
11527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi			if (curItem.getType() == xe::ri::TYPE_SHADERPROGRAM)
11627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi			{
11727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi				writeShaderProgram(cmdLine, casePath, static_cast<const xe::ri::ShaderProgram&>(curItem), programNdx);
11827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi				programNdx += 1;
11927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi			}
12027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi			else if (curItem.getType() == xe::ri::TYPE_SECTION)
12127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi				itemListStack.push_back(StackEntry(&static_cast<const xe::ri::Section&>(curItem).items));
12227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi		}
12327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi		else
1243473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi			itemListStack.pop_back();
1253473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi	}
1263473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi
1273473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi	if (programNdx == 0)
1283473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi		std::cout << "WARNING: no shader programs found in '" << casePath << "'\n";
1293473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi}
1303473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi
1313473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimiclass ShaderProgramExtractHandler : public xe::TestLogHandler
1323473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi{
1333473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimipublic:
1343473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi	ShaderProgramExtractHandler (const CommandLine& cmdLine)
1353473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi		: m_cmdLine(cmdLine)
13627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	{
13727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	}
13827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
13927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	void setSessionInfo (const xe::SessionInfo&)
14027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	{
14127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi		// Ignored.
14227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	}
14327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
14427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	xe::TestCaseResultPtr startTestCaseResult (const char* casePath)
14527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	{
14627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi		return xe::TestCaseResultPtr(new xe::TestCaseResultData(casePath));
14727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	}
1488f00151cbe693d52f3e233757c57fab3b6396d21Gloria Wang
1498f00151cbe693d52f3e233757c57fab3b6396d21Gloria Wang	void testCaseResultUpdated (const xe::TestCaseResultPtr&)
1508f00151cbe693d52f3e233757c57fab3b6396d21Gloria Wang	{
1518f00151cbe693d52f3e233757c57fab3b6396d21Gloria Wang		// Ignored.
1528f00151cbe693d52f3e233757c57fab3b6396d21Gloria Wang	}
1538f00151cbe693d52f3e233757c57fab3b6396d21Gloria Wang
1548f00151cbe693d52f3e233757c57fab3b6396d21Gloria Wang	void testCaseResultComplete (const xe::TestCaseResultPtr& caseData)
15527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	{
15627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi		if (caseData->getDataSize() > 0)
15727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi		{
15827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi			xe::TestCaseResult					fullResult;
15927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi			xe::TestResultParser::ParseResult	parseResult;
16027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
16127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi			m_testResultParser.init(&fullResult);
16227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi			parseResult = m_testResultParser.parse(caseData->getData(), caseData->getDataSize());
16327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi			DE_UNREF(parseResult);
16427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
16527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi			extractShaderPrograms(m_cmdLine, caseData->getTestCasePath(), fullResult);
16627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi		}
16727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	}
16827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
16927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiprivate:
17027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	const CommandLine&		m_cmdLine;
17127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	xe::TestResultParser	m_testResultParser;
17227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi};
17327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
17427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshistatic void extractShaderProgramsFromLogFile (const CommandLine& cmdLine)
17527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi{
17627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	std::ifstream					in				(cmdLine.filename.c_str(), std::ifstream::binary|std::ifstream::in);
17727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	ShaderProgramExtractHandler		resultHandler	(cmdLine);
17827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	xe::TestLogParser				parser			(&resultHandler);
17927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	deUint8							buf				[1024];
18027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	int								numRead			= 0;
18127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
18227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	if (!in.good())
18327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi		throw std::runtime_error(string("Failed to open '") + cmdLine.filename + "'");
18427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
18527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	for (;;)
18627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	{
18727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi		in.read((char*)&buf[0], DE_LENGTH_OF_ARRAY(buf));
18827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi		numRead = (int)in.gcount();
18927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
19027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi		if (numRead <= 0)
19127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi			break;
19227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
19327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi		parser.parse(&buf[0], numRead);
19427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	}
19527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
19627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	in.close();
19727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
19827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
19927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshistatic void printHelp (const char* binName)
2002272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi{
2012272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi	printf("%s: [filename] [dst path (optional)]\n", binName);
20227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
2032272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi
20427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshistatic bool parseCommandLine (CommandLine& cmdLine, int argc, const char* const* argv)
20527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi{
20627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	for (int argNdx = 1; argNdx < argc; argNdx++)
20727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	{
20827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi		const char* arg = argv[argNdx];
20927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
21027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi		if (!deStringBeginsWith(arg, "--"))
21127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi		{
21227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi			if (cmdLine.filename.empty())
21327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi				cmdLine.filename = arg;
21427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi			else if (cmdLine.dstPath.empty())
21527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi				cmdLine.dstPath = arg;
21627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi			else
21727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi				return false;
21827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi		}
21927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi		else
22027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi			return false;
22127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	}
22227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
22327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	if (cmdLine.filename.empty())
22427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi		return false;
22527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
22627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	return true;
22727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
22827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
22927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiint main (int argc, const char* const* argv)
23027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi{
23127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	try
23227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	{
23327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi		CommandLine cmdLine;
23427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
23527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi		if (!parseCommandLine(cmdLine, argc, argv))
23627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi		{
23727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi			printHelp(argv[0]);
23827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi			return -1;
23927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi		}
24027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
24127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi		extractShaderProgramsFromLogFile(cmdLine);
24227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	}
24327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	catch (const std::exception& e)
24427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	{
24527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi		printf("FATAL ERROR: %s\n", e.what());
24627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi		return -1;
24727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	}
24827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
24927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi	return 0;
25027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
25127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi