127 lines
3.5 KiB
C++
127 lines
3.5 KiB
C++
/*
|
|
** Command & Conquer Generals Zero Hour(tm)
|
|
** Copyright 2025 Electronic Arts Inc.
|
|
**
|
|
** This program is free software: you can redistribute it and/or modify
|
|
** it under the terms of the GNU General Public License as published by
|
|
** the Free Software Foundation, either version 3 of the License, or
|
|
** (at your option) any later version.
|
|
**
|
|
** This program is distributed in the hope that it will be useful,
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
** GNU General Public License for more details.
|
|
**
|
|
** You should have received a copy of the GNU General Public License
|
|
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// File: expander.cpp
|
|
// Author: Matthew D. Campbell
|
|
// Creation Date: 9/13/2002
|
|
// Description: Key/value pair template expansion class
|
|
// ---------------------------------------------------------------------------
|
|
|
|
#include "debug.h"
|
|
#include "expander.h"
|
|
|
|
Expander::Expander( const std::string& leftMarker, const std::string& rightMarker ) :
|
|
m_left(leftMarker), m_right(rightMarker)
|
|
{
|
|
}
|
|
|
|
void Expander::addExpansion( const std::string& key, const std::string val )
|
|
{
|
|
m_expansions[key] = val;
|
|
}
|
|
|
|
void Expander::clear( void )
|
|
{
|
|
m_expansions.clear();
|
|
}
|
|
|
|
void Expander::expand( const std::string& input,
|
|
std::string& output,
|
|
bool stripUnknown )
|
|
{
|
|
output = "";
|
|
unsigned int pos = input.find(m_left);
|
|
unsigned int lastpos = input.npos;
|
|
while (pos != input.npos)
|
|
{
|
|
// first, tack on the non-expansion part we just skipped over
|
|
if (pos > 0)
|
|
{
|
|
if (lastpos == input.npos)
|
|
{
|
|
// first time
|
|
output.append(input.substr(0, pos));
|
|
//DEBUG_LOG(("First time, output='%s'\n", output.c_str()));
|
|
}
|
|
else
|
|
{
|
|
// done this before
|
|
std::string sub = input.substr(lastpos, pos-lastpos);
|
|
//DEBUG_LOG(("*** lastpos = %d, pos=%d, sub='%s'\n", lastpos, pos, sub.c_str()));
|
|
output.append(sub);
|
|
//DEBUG_LOG(("output='%s'\n", output.c_str()));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//DEBUG_LOG(("pos == 0\n"));
|
|
}
|
|
|
|
// pos is the first position of a possible expansion
|
|
//DEBUG_LOG(("Looking for endpos via '%s' in '%s'\n", m_right.c_str(), input.substr(pos+m_left.length()).c_str()));
|
|
unsigned int endpos = input.find(m_right, pos+m_left.length());
|
|
//DEBUG_LOG(("substr is %d-%d of '%s'\n", pos, endpos, input.c_str()));
|
|
if (endpos != input.npos)
|
|
{
|
|
// found a complete token - expand it
|
|
std::string sub = input.substr(pos+m_left.length(), endpos-pos-m_left.length());
|
|
//DEBUG_LOG(("found token: '%s'\n", sub.c_str()));
|
|
|
|
ExpansionMap::iterator it = m_expansions.find(sub);
|
|
if (it == m_expansions.end())
|
|
{
|
|
// unknown key
|
|
if (stripUnknown)
|
|
{
|
|
//output.append("<<CENSORED>>");
|
|
}
|
|
else
|
|
{
|
|
output.append(input.substr(pos, endpos-pos+m_right.length()));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
std::string toExpand = it->second;
|
|
std::string expanded = "";
|
|
//DEBUG_LOG(("###### expanding '%s'\n", toExpand.c_str()));
|
|
expand(toExpand, expanded, stripUnknown);
|
|
//DEBUG_LOG(("###### expanded '%s'\n", expanded.c_str()));
|
|
output.append(expanded);
|
|
}
|
|
}
|
|
|
|
lastpos = endpos+m_right.length();
|
|
|
|
pos = input.find(m_left, pos+m_left.length());
|
|
}
|
|
|
|
if (lastpos != input.npos)
|
|
{
|
|
// tack on last bit
|
|
output.append(input.substr(lastpos));
|
|
}
|
|
else if (!output.length() && pos == input.npos && lastpos == input.npos)
|
|
{
|
|
output = input;
|
|
}
|
|
}
|
|
|
|
|