Home | History | Annotate | Download | only in common
      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 
     29 using std::string;
     30 using std::map;
     31 using std::ostringstream;
     32 
     33 namespace tcu
     34 {
     35 
     36 StringTemplate::StringTemplate (void)
     37 {
     38 }
     39 
     40 StringTemplate::StringTemplate (const std::string& str)
     41 {
     42 	setString(str);
     43 }
     44 
     45 StringTemplate::~StringTemplate (void)
     46 {
     47 }
     48 
     49 void StringTemplate::setString (const std::string& str)
     50 {
     51 	m_template = str;
     52 }
     53 
     54 string 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