1/*-------------------------------------------------------------------------
2 * drawElements Quality Program Tester Core
3 * ----------------------------------------
4 *
5 * Copyright 2014 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief String template class.
22 *//*--------------------------------------------------------------------*/
23
24#include "tcuStringTemplate.hpp"
25#include "tcuDefs.hpp"
26
27#include <sstream>
28
29using std::string;
30using std::map;
31using std::ostringstream;
32
33namespace tcu
34{
35
36StringTemplate::StringTemplate (void)
37{
38}
39
40StringTemplate::StringTemplate (const std::string& str)
41{
42	setString(str);
43}
44
45StringTemplate::~StringTemplate (void)
46{
47}
48
49void StringTemplate::setString (const std::string& str)
50{
51	m_template = str;
52}
53
54string StringTemplate::specialize (const map<string, string>& params) const
55{
56	ostringstream res;
57
58	size_t curNdx = 0;
59	for (;;)
60	{
61		size_t paramNdx = m_template.find("${", curNdx);
62		if (paramNdx != string::npos)
63		{
64			// Append in-between stuff.
65			res << m_template.substr(curNdx, paramNdx - curNdx);
66
67			// Find end-of-param.
68			size_t paramEndNdx = m_template.find("}", paramNdx);
69			if (paramEndNdx == string::npos)
70				TCU_THROW(InternalError, "No '}' found in template parameter");
71
72			// Parse parameter contents.
73			string	paramStr		= m_template.substr(paramNdx+2, paramEndNdx-2-paramNdx);
74			bool	paramSingleLine	= false;
75			bool	paramOptional	= false;
76			string	paramName;
77			size_t colonNdx = paramStr.find(":");
78			if (colonNdx != string::npos)
79			{
80				paramName = paramStr.substr(0, colonNdx);
81				string flagsStr = paramStr.substr(colonNdx+1);
82				if (flagsStr == "single-line")
83				{
84					paramSingleLine = true;
85				}
86				else if (flagsStr == "opt")
87				{
88					paramOptional = true;
89				}
90				else
91				{
92					TCU_THROW(InternalError, (string("Unrecognized flag") + paramStr).c_str());
93				}
94			}
95			else
96				paramName = paramStr;
97
98			// Fill in parameter value.
99			if (params.find(paramName) != params.end())
100			{
101				const string& val = (*params.find(paramName)).second;
102				if (paramSingleLine)
103				{
104					string tmp = val;
105					for (size_t ndx = tmp.find("\n"); ndx != string::npos; ndx = tmp.find("\n"))
106						tmp = tmp.replace(ndx, 1, " ");
107					res << tmp;
108				}
109				else
110					res << val;
111			}
112			else if (!paramOptional)
113				TCU_THROW(InternalError, (string("Value for parameter '") + paramName + "' not found in map").c_str());
114
115			// Skip over template.
116			curNdx = paramEndNdx + 1;
117		}
118		else
119		{
120			if (curNdx < m_template.length())
121				res << &m_template[curNdx];
122
123			break;
124		}
125	}
126
127	return res.str();
128}
129
130} // tcu
131