expander.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /*
  2. ** Command & Conquer Generals(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. // ---------------------------------------------------------------------------
  19. // File: expander.cpp
  20. // Author: Matthew D. Campbell
  21. // Creation Date: 9/13/2002
  22. // Description: Key/value pair template expansion class
  23. // ---------------------------------------------------------------------------
  24. #include "debug.h"
  25. #include "expander.h"
  26. Expander::Expander( const std::string& leftMarker, const std::string& rightMarker ) :
  27. m_left(leftMarker), m_right(rightMarker)
  28. {
  29. }
  30. void Expander::addExpansion( const std::string& key, const std::string val )
  31. {
  32. m_expansions[key] = val;
  33. }
  34. void Expander::clear( void )
  35. {
  36. m_expansions.clear();
  37. }
  38. void Expander::expand( const std::string& input,
  39. std::string& output,
  40. bool stripUnknown )
  41. {
  42. output = "";
  43. unsigned int pos = input.find(m_left);
  44. unsigned int lastpos = input.npos;
  45. while (pos != input.npos)
  46. {
  47. // first, tack on the non-expansion part we just skipped over
  48. if (pos > 0)
  49. {
  50. if (lastpos == input.npos)
  51. {
  52. // first time
  53. output.append(input.substr(0, pos));
  54. //DEBUG_LOG(("First time, output='%s'\n", output.c_str()));
  55. }
  56. else
  57. {
  58. // done this before
  59. std::string sub = input.substr(lastpos, pos-lastpos);
  60. //DEBUG_LOG(("*** lastpos = %d, pos=%d, sub='%s'\n", lastpos, pos, sub.c_str()));
  61. output.append(sub);
  62. //DEBUG_LOG(("output='%s'\n", output.c_str()));
  63. }
  64. }
  65. else
  66. {
  67. //DEBUG_LOG(("pos == 0\n"));
  68. }
  69. // pos is the first position of a possible expansion
  70. //DEBUG_LOG(("Looking for endpos via '%s' in '%s'\n", m_right.c_str(), input.substr(pos+m_left.length()).c_str()));
  71. unsigned int endpos = input.find(m_right, pos+m_left.length());
  72. //DEBUG_LOG(("substr is %d-%d of '%s'\n", pos, endpos, input.c_str()));
  73. if (endpos != input.npos)
  74. {
  75. // found a complete token - expand it
  76. std::string sub = input.substr(pos+m_left.length(), endpos-pos-m_left.length());
  77. //DEBUG_LOG(("found token: '%s'\n", sub.c_str()));
  78. ExpansionMap::iterator it = m_expansions.find(sub);
  79. if (it == m_expansions.end())
  80. {
  81. // unknown key
  82. if (stripUnknown)
  83. {
  84. //output.append("<<CENSORED>>");
  85. }
  86. else
  87. {
  88. output.append(input.substr(pos, endpos-pos+m_right.length()));
  89. }
  90. }
  91. else
  92. {
  93. std::string toExpand = it->second;
  94. std::string expanded = "";
  95. //DEBUG_LOG(("###### expanding '%s'\n", toExpand.c_str()));
  96. expand(toExpand, expanded, stripUnknown);
  97. //DEBUG_LOG(("###### expanded '%s'\n", expanded.c_str()));
  98. output.append(expanded);
  99. }
  100. }
  101. lastpos = endpos+m_right.length();
  102. pos = input.find(m_left, pos+m_left.length());
  103. }
  104. if (lastpos != input.npos)
  105. {
  106. // tack on last bit
  107. output.append(input.substr(lastpos));
  108. }
  109. else if (!output.length() && pos == input.npos && lastpos == input.npos)
  110. {
  111. output = input;
  112. }
  113. }