fork download
  1. #include <iostream>
  2. #include <map>
  3. #include <string>
  4.  
  5. bool FindVariableString(
  6. const std::string &str,
  7. const std::string::size_type pos,
  8. std::string::size_type &beginVarStringPos,
  9. std::string::size_type &endVarStringPos,
  10. std::string::size_type &beginVarNamePos,
  11. std::string::size_type &endVarNamePos)
  12. {
  13. const char *TestString = "%$#";
  14. const char PercentSign = '%';
  15. const char LeftParenthesis = '(';
  16. const char LeftSquareBracket = '[';
  17. const char LeftCurlyBracket = '{';
  18. const char RightParenthesis = ')';
  19. const char RightSquareBracket = ']';
  20. const char RightCurlyBracket = '}';
  21. beginVarStringPos = std::string::npos;
  22. endVarStringPos = std::string::npos;
  23. beginVarNamePos = std::string::npos;
  24. endVarNamePos = std::string::npos;
  25. if (str.empty())
  26. {
  27. return false;
  28. }
  29. beginVarStringPos = str.find_first_of(TestString, pos);
  30. if (std::string::npos == beginVarStringPos)
  31. {
  32. return false;
  33. }
  34. if (beginVarStringPos >= str.length() - 1)
  35. {
  36. return false;
  37. }
  38. char ch = str[beginVarStringPos];
  39. char ch1 = str[beginVarStringPos + 1];
  40. if (
  41. PercentSign == ch
  42. && LeftParenthesis != ch1 && LeftSquareBracket != ch1
  43. && LeftCurlyBracket != ch1
  44. )
  45. {
  46. beginVarNamePos = beginVarStringPos + 1;
  47. endVarStringPos = str.find(PercentSign, beginVarNamePos);
  48. if (std::string::npos == endVarStringPos)
  49. {
  50. return false;
  51. }
  52. }
  53. else if (
  54. LeftParenthesis != ch1 && LeftSquareBracket != ch1
  55. && LeftCurlyBracket != ch1
  56. )
  57. {
  58. return false;
  59. }
  60. else
  61. {
  62. beginVarNamePos = beginVarStringPos + 2;
  63. char closeChar = 0;
  64. if (LeftParenthesis == ch1)
  65. {
  66. closeChar = RightParenthesis;
  67. }
  68. else if (LeftSquareBracket == ch1)
  69. {
  70. closeChar = RightSquareBracket;
  71. }
  72. else if (LeftCurlyBracket == ch1)
  73. {
  74. closeChar = RightCurlyBracket;
  75. }
  76. endVarStringPos = str.find(closeChar, beginVarNamePos);
  77. if (std::string::npos == endVarStringPos)
  78. {
  79. return false;
  80. }
  81. }
  82. endVarNamePos = endVarStringPos - 1;
  83. return true;
  84. }
  85.  
  86. bool StringContainsVariableStrings(const std::string &str)
  87. {
  88. std::string::size_type beginVarStringPos = 0;
  89. std::string::size_type endVarStringPos = 0;
  90. std::string::size_type beginVarNamePos = 0;
  91. std::string::size_type endVarNamePos = 0;
  92. bool ret = FindVariableString(str, 0, beginVarStringPos, endVarStringPos, beginVarNamePos, endVarNamePos);
  93. return ret;
  94. }
  95.  
  96. std::string GetVariableValue(
  97. const std::string &varName,
  98. const std::map<std::string, std::string> &env,
  99. bool &fromEnvMap, bool &valueContainsVariableStrings)
  100. {
  101. typedef std::map<std::string, std::string> my_map;
  102. fromEnvMap = false;
  103. valueContainsVariableStrings = false;
  104. std::string ret;
  105. my_map::const_iterator itFind = env.find(varName);
  106. if (itFind != env.end())
  107. {
  108. ret = (*itFind).second;
  109. if (!ret.empty())
  110. {
  111. fromEnvMap = true;
  112. valueContainsVariableStrings = StringContainsVariableStrings(ret);
  113. }
  114. }
  115. if (ret.empty())
  116. {
  117. ret = ::getenv(varName.c_str());
  118. }
  119. return ret;
  120. }
  121.  
  122. std::string ExpandVars(
  123. const std::string &original,
  124. const std::map<std::string, std::string> &env)
  125. {
  126. std::string ret = original;
  127. if (original.empty())
  128. {
  129. return ret;
  130. }
  131. bool foundVar = false;
  132. std::string::size_type pos = 0;
  133. do
  134. {
  135. std::string::size_type beginVarStringPos = 0;
  136. std::string::size_type endVarStringPos = 0;
  137. std::string::size_type beginVarNamePos = 0;
  138. std::string::size_type endVarNamePos = 0;
  139. foundVar = FindVariableString(ret, pos, beginVarStringPos, endVarStringPos, beginVarNamePos, endVarNamePos);
  140. if (foundVar)
  141. {
  142. std::string::size_type varStringLen = endVarStringPos - beginVarStringPos + 1;
  143. std::string varString = ret.substr(beginVarStringPos, varStringLen);
  144. std::string::size_type varNameLen = endVarNamePos - beginVarNamePos + 1;
  145. std::string varName = ret.substr(beginVarNamePos, varNameLen);
  146. bool fromEnvMap;
  147. bool valueContainsVariableStrings;
  148. std::string value = GetVariableValue(varName, env, fromEnvMap, valueContainsVariableStrings);
  149. if (!value.empty())
  150. {
  151. ret = ret.replace(beginVarStringPos, varStringLen, value);
  152. pos = beginVarStringPos;
  153. }
  154. else
  155. {
  156. pos = endVarStringPos + 1;
  157. }
  158. }
  159. } while (foundVar);
  160. return ret;
  161. }
  162.  
  163. std::string GetDateFormatStringExpandVars(const std::string& langCode)
  164. {
  165. if (
  166. 0 == langCode.compare(0, 2, "en")
  167. || 0 == langCode.compare(0, 2, "EN")
  168. )
  169. {
  170. return std::string("${month}/${day}/${year}");
  171. }
  172. else if (
  173. 0 == langCode.compare(0, 2, "fr")
  174. || 0 == langCode.compare(0, 2, "FR")
  175. )
  176. {
  177. return std::string("${day}/${month}/${year}");
  178. }
  179. else if (
  180. 0 == langCode.compare(0, 2, "ja")
  181. || 0 == langCode.compare(0, 2, "JA")
  182. || 0 == langCode.compare(0, 2, "jp")
  183. || 0 == langCode.compare(0, 2, "JP")
  184. )
  185. {
  186. return std::string("${year}/${day}/${month}");
  187. }
  188. return std::string("${month}/${day}/${year}");
  189. }
  190.  
  191. std::string GetDateStringExpandVars(
  192. const std::string &langCode, int month, int day, int year)
  193. {
  194. std::string fmt = GetDateFormatStringExpandVars(langCode);
  195. std::map<std::string,std::string> env{
  196. {"month", std::to_string(month)},
  197. {"day", std::to_string(day)},
  198. {"year", std::to_string(year)}
  199. };
  200. std::string ret = ExpandVars(fmt, env);
  201. return ret;
  202. }
  203.  
  204. int main()
  205. {
  206. std::cout << GetDateStringExpandVars("en", 11, 7, 2018) << "\n";
  207. return 0;
  208. }
  209.  
Success #stdin #stdout 0s 15240KB
stdin
Standard input is empty
stdout
11/7/2018