xref: /aosp_15_r20/external/deqp/framework/common/tcuStringTemplate.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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::map;
32 using std::ostringstream;
33 using std::string;
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) : m_template(std::move(other.m_template))
48 {
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 } // namespace tcu
150