xref: /aosp_15_r20/external/deqp/framework/common/tcuStringTemplate.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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> &params) 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