#include <iostream>
#include <map>
#include <string>
bool FindVariableString(
const std::string &str,
const std::string::size_type pos,
std::string::size_type &beginVarStringPos,
std::string::size_type &endVarStringPos,
std::string::size_type &beginVarNamePos,
std::string::size_type &endVarNamePos)
{
const char *TestString = "%$#";
const char PercentSign = '%';
const char LeftParenthesis = '(';
const char LeftSquareBracket = '[';
const char LeftCurlyBracket = '{';
const char RightParenthesis = ')';
const char RightSquareBracket = ']';
const char RightCurlyBracket = '}';
beginVarStringPos = std::string::npos;
endVarStringPos = std::string::npos;
beginVarNamePos = std::string::npos;
endVarNamePos = std::string::npos;
if (str.empty())
{
return false;
}
beginVarStringPos = str.find_first_of(TestString, pos);
if (std::string::npos == beginVarStringPos)
{
return false;
}
if (beginVarStringPos >= str.length() - 1)
{
return false;
}
char ch = str[beginVarStringPos];
char ch1 = str[beginVarStringPos + 1];
if (
PercentSign == ch
&& LeftParenthesis != ch1 && LeftSquareBracket != ch1
&& LeftCurlyBracket != ch1
)
{
beginVarNamePos = beginVarStringPos + 1;
endVarStringPos = str.find(PercentSign, beginVarNamePos);
if (std::string::npos == endVarStringPos)
{
return false;
}
}
else if (
LeftParenthesis != ch1 && LeftSquareBracket != ch1
&& LeftCurlyBracket != ch1
)
{
return false;
}
else
{
beginVarNamePos = beginVarStringPos + 2;
char closeChar = 0;
if (LeftParenthesis == ch1)
{
closeChar = RightParenthesis;
}
else if (LeftSquareBracket == ch1)
{
closeChar = RightSquareBracket;
}
else if (LeftCurlyBracket == ch1)
{
closeChar = RightCurlyBracket;
}
endVarStringPos = str.find(closeChar, beginVarNamePos);
if (std::string::npos == endVarStringPos)
{
return false;
}
}
endVarNamePos = endVarStringPos - 1;
return true;
}
bool StringContainsVariableStrings(const std::string &str)
{
std::string::size_type beginVarStringPos = 0;
std::string::size_type endVarStringPos = 0;
std::string::size_type beginVarNamePos = 0;
std::string::size_type endVarNamePos = 0;
bool ret = FindVariableString(str, 0, beginVarStringPos, endVarStringPos, beginVarNamePos, endVarNamePos);
return ret;
}
std::string GetVariableValue(
const std::string &varName,
const std::map<std::string, std::string> &env,
bool &fromEnvMap, bool &valueContainsVariableStrings)
{
typedef std::map<std::string, std::string> my_map;
fromEnvMap = false;
valueContainsVariableStrings = false;
std::string ret;
my_map::const_iterator itFind = env.find(varName);
if (itFind != env.end())
{
ret = (*itFind).second;
if (!ret.empty())
{
fromEnvMap = true;
valueContainsVariableStrings = StringContainsVariableStrings(ret);
}
}
if (ret.empty())
{
ret = ::getenv(varName.c_str());
}
return ret;
}
std::string ExpandVars(
const std::string &original,
const std::map<std::string, std::string> &env)
{
std::string ret = original;
if (original.empty())
{
return ret;
}
bool foundVar = false;
std::string::size_type pos = 0;
do
{
std::string::size_type beginVarStringPos = 0;
std::string::size_type endVarStringPos = 0;
std::string::size_type beginVarNamePos = 0;
std::string::size_type endVarNamePos = 0;
foundVar = FindVariableString(ret, pos, beginVarStringPos, endVarStringPos, beginVarNamePos, endVarNamePos);
if (foundVar)
{
std::string::size_type varStringLen = endVarStringPos - beginVarStringPos + 1;
std::string varString = ret.substr(beginVarStringPos, varStringLen);
std::string::size_type varNameLen = endVarNamePos - beginVarNamePos + 1;
std::string varName = ret.substr(beginVarNamePos, varNameLen);
bool fromEnvMap;
bool valueContainsVariableStrings;
std::string value = GetVariableValue(varName, env, fromEnvMap, valueContainsVariableStrings);
if (!value.empty())
{
ret = ret.replace(beginVarStringPos, varStringLen, value);
pos = beginVarStringPos;
}
else
{
pos = endVarStringPos + 1;
}
}
} while (foundVar);
return ret;
}
std::string GetDateFormatStringExpandVars(const std::string& langCode)
{
if (
0 == langCode.compare(0, 2, "en")
|| 0 == langCode.compare(0, 2, "EN")
)
{
return std::string("${month}/${day}/${year}");
}
else if (
0 == langCode.compare(0, 2, "fr")
|| 0 == langCode.compare(0, 2, "FR")
)
{
return std::string("${day}/${month}/${year}");
}
else if (
0 == langCode.compare(0, 2, "ja")
|| 0 == langCode.compare(0, 2, "JA")
|| 0 == langCode.compare(0, 2, "jp")
|| 0 == langCode.compare(0, 2, "JP")
)
{
return std::string("${year}/${day}/${month}");
}
return std::string("${month}/${day}/${year}");
}
std::string GetDateStringExpandVars(
const std::string &langCode, int month, int day, int year)
{
std::string fmt = GetDateFormatStringExpandVars(langCode);
std::map<std::string,std::string> env{
{"month", std::to_string(month)},
{"day", std::to_string(day)},
{"year", std::to_string(year)}
};
std::string ret = ExpandVars(fmt, env);
return ret;
}
int main()
{
std::cout << GetDateStringExpandVars("en", 11, 7, 2018) << "\n";
return 0;
}