• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "deStringUtil.hpp"
28 
29 #include <sstream>
30 
31 using std::string;
32 using std::map;
33 using std::ostringstream;
34 
35 namespace tcu
36 {
37 
StringTemplate(void)38 StringTemplate::StringTemplate (void)
39 {
40 }
41 
StringTemplate(const std::string & str)42 StringTemplate::StringTemplate (const std::string& str)
43 {
44 	setString(str);
45 }
46 
StringTemplate(StringTemplate && other)47 StringTemplate::StringTemplate (StringTemplate&& other)
48 	: m_template(std::move(other.m_template))
49 {}
50 
~StringTemplate(void)51 StringTemplate::~StringTemplate (void)
52 {
53 }
54 
setString(const std::string & str)55 void StringTemplate::setString (const std::string& str)
56 {
57 	m_template = str;
58 }
59 
60 const string kSingleLineFlag = "single-line";
61 const string kOptFlag = "opt";
62 const string kDefaultFlag = "default=";
63 
specialize(const map<string,string> & params) const64 string StringTemplate::specialize (const map<string, string>& params) const
65 {
66 	ostringstream res;
67 
68 	size_t curNdx = 0;
69 	for (;;)
70 	{
71 		size_t paramNdx = m_template.find("${", curNdx);
72 		if (paramNdx != string::npos)
73 		{
74 			// Append in-between stuff.
75 			res << m_template.substr(curNdx, paramNdx - curNdx);
76 
77 			// Find end-of-param.
78 			size_t paramEndNdx = m_template.find("}", paramNdx);
79 			if (paramEndNdx == string::npos)
80 				TCU_THROW(InternalError, "No '}' found in template parameter");
81 
82 			// Parse parameter contents.
83 			string	paramStr		= m_template.substr(paramNdx+2, paramEndNdx-2-paramNdx);
84 			bool	paramSingleLine	= false;
85 			bool	paramOptional	= false;
86 			bool	paramDefault	= false;
87 			string	paramName;
88 			string	defaultValue;
89 			size_t colonNdx = paramStr.find(":");
90 			if (colonNdx != string::npos)
91 			{
92 				paramName = paramStr.substr(0, colonNdx);
93 				string flagsStr = paramStr.substr(colonNdx+1);
94 				if (flagsStr == kSingleLineFlag)
95 				{
96 					paramSingleLine = true;
97 				}
98 				else if (flagsStr == kOptFlag)
99 				{
100 					paramOptional = true;
101 				}
102 				else if (de::beginsWith(flagsStr, kDefaultFlag))
103 				{
104 					paramDefault = true;
105 					defaultValue = flagsStr.substr(kDefaultFlag.size());
106 				}
107 				else
108 				{
109 					TCU_THROW(InternalError, (string("Unrecognized flag") + paramStr).c_str());
110 				}
111 			}
112 			else
113 				paramName = paramStr;
114 
115 			// Fill in parameter value.
116 			if (params.find(paramName) != params.end())
117 			{
118 				const string& val = (*params.find(paramName)).second;
119 				if (paramSingleLine)
120 				{
121 					string tmp = val;
122 					for (size_t ndx = tmp.find("\n"); ndx != string::npos; ndx = tmp.find("\n"))
123 						tmp = tmp.replace(ndx, 1, " ");
124 					res << tmp;
125 				}
126 				else
127 					res << val;
128 			}
129 			else if (paramDefault)
130 				res << defaultValue;
131 			else if (!paramOptional)
132 				TCU_THROW(InternalError, (string("Value for parameter '") + paramName + "' not found in map").c_str());
133 
134 			// Skip over template.
135 			curNdx = paramEndNdx + 1;
136 		}
137 		else
138 		{
139 			if (curNdx < m_template.length())
140 				res << &m_template[curNdx];
141 
142 			break;
143 		}
144 	}
145 
146 	return res.str();
147 }
148 
149 } // tcu
150