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