mirror of
https://github.com/electronicarts/CNC_TS_and_RA2_Mission_Editor.git
synced 2025-07-17 19:56:38 -04:00
Enhance:ini registry sequence (#121)
* '+=' supported . * introduced registry list value deduplication . * TechnoType listing now parse data both from ini and map . * added UT case .
This commit is contained in:
parent
3e90dca667
commit
93e956e7ac
8 changed files with 164 additions and 50 deletions
|
@ -24,10 +24,12 @@
|
|||
|
||||
#include "stdafx.h"
|
||||
#include "IniFile.h"
|
||||
#include "Helpers.h"
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <set>
|
||||
#include <unordered_set>
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
@ -92,64 +94,121 @@ CIniFileSection::~CIniFileSection()
|
|||
value_pairs.clear();
|
||||
};
|
||||
|
||||
bool isSectionRegistry(const CString& secName)
|
||||
{
|
||||
static std::unordered_set<std::string_view> registryNames = {
|
||||
"BuildingTypes",
|
||||
"InfantryTypes",
|
||||
"AircraftTypes",
|
||||
"VehicleTypes",
|
||||
"Animations",
|
||||
};
|
||||
|
||||
auto const nameView = std::string_view(secName.GetString(), secName.GetLength());
|
||||
return registryNames.find(nameView) != registryNames.end();
|
||||
}
|
||||
|
||||
WORD CIniFile::InsertFile(const CString& filename, const char* Section, BOOL bNoSpaces)
|
||||
{
|
||||
return InsertFile(std::string(filename.GetString()), Section, bNoSpaces);
|
||||
}
|
||||
|
||||
WORD CIniFile::InsertFile(const std::string& filename, const char* Section, BOOL bNoSpaces)
|
||||
WORD CIniFile::InsertFile(const std::string& filename, const char* pSectionSpecified, BOOL bNoSpaces)
|
||||
{
|
||||
if (filename.size() == 0)
|
||||
if (filename.size() == 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
fstream file;
|
||||
|
||||
file.open(filename, ios::in);
|
||||
if (!file.good())
|
||||
if (!file.good()) {
|
||||
return 2;
|
||||
|
||||
}
|
||||
|
||||
//char cSec[256];
|
||||
//char cLine[4096];
|
||||
|
||||
//memset(cSec, 0, 256);
|
||||
//memset(cLine, 0, 4096);
|
||||
CString cSec;
|
||||
std::string cLine;
|
||||
CString curSecParsed;
|
||||
std::string curLineParsed;
|
||||
|
||||
const auto npos = std::string::npos;
|
||||
|
||||
#if 0
|
||||
std::map<CString, std::list<std::pair<CString, CString>>> registryMap;
|
||||
#endif
|
||||
std::set<CString> registryValues;
|
||||
|
||||
while (!file.eof()) {
|
||||
std::getline(file, cLine);
|
||||
std::getline(file, curLineParsed);
|
||||
|
||||
// strip to left side of newline or comment
|
||||
cLine.erase(std::find_if(cLine.begin(), cLine.end(), [](const char c) { return c == '\r' || c == '\n' || c == ';'; }), cLine.end());
|
||||
curLineParsed.erase(std::find_if(curLineParsed.begin(), curLineParsed.end(), [](const char c) { return c == '\r' || c == '\n' || c == ';'; }), curLineParsed.end());
|
||||
|
||||
const auto openBracket = cLine.find('[');
|
||||
const auto closeBracket = cLine.find(']');
|
||||
const auto equals = cLine.find('=');
|
||||
const auto openBracketPos = curLineParsed.find('[');
|
||||
const auto closeBracketPos = curLineParsed.find(']');
|
||||
const auto equalPos = curLineParsed.find('=');
|
||||
|
||||
if (openBracket != npos && closeBracket != npos && openBracket < closeBracket && (equals == npos || equals > openBracket)) {
|
||||
if ((Section != nullptr) && cSec == Section)
|
||||
return 0; // the section we want to insert is finished
|
||||
if (openBracketPos != npos && closeBracketPos != npos && openBracketPos < closeBracketPos && (equalPos == npos || equalPos > openBracketPos)) {
|
||||
if ((pSectionSpecified != nullptr) && curSecParsed == pSectionSpecified) {
|
||||
break; // the section we want to insert is finished
|
||||
}
|
||||
|
||||
cSec = cLine.substr(openBracket + 1, closeBracket - openBracket - 1).c_str();
|
||||
} else if (equals != npos && !cSec.IsEmpty()) {
|
||||
if (Section == NULL || cSec == Section) {
|
||||
curSecParsed = curLineParsed.substr(openBracketPos + 1, closeBracketPos - openBracketPos - 1).c_str();
|
||||
registryValues.clear();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (equalPos != npos && !curSecParsed.IsEmpty()) {
|
||||
if (pSectionSpecified == NULL || curSecParsed == pSectionSpecified) {
|
||||
// a value is set and we have a valid current section!
|
||||
CString name = cLine.substr(0, equals).c_str();
|
||||
CString value = cLine.substr(equals + 1, cLine.size() - equals - 1).c_str();
|
||||
CString keyName = curLineParsed.substr(0, equalPos).c_str();
|
||||
CString value = curLineParsed.substr(equalPos + 1, curLineParsed.size() - equalPos - 1).c_str();
|
||||
auto& curSectionMap = sections[curSecParsed];
|
||||
|
||||
if (bNoSpaces) {
|
||||
name.Trim();
|
||||
keyName.Trim();
|
||||
value.Trim();
|
||||
}
|
||||
sections[cSec].SetString(name, value);
|
||||
|
||||
if (isSectionRegistry(curSecParsed) && IsNumeric(keyName)) {
|
||||
auto const [_, inserted] = registryValues.insert(value);
|
||||
// WW's duplicated record, skip
|
||||
if (!inserted) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// this is a duplicated number, and already added
|
||||
// so we will append in the end of the list later
|
||||
#if 0
|
||||
if (IsNumeric(keyName) && curSectionMap.Exists(keyName)) {
|
||||
registryMap[curSecParsed].push_back({ keyName, value });
|
||||
}
|
||||
#endif
|
||||
|
||||
// special handling for +=
|
||||
if (keyName == '+') {
|
||||
keyName += value;
|
||||
}
|
||||
|
||||
curSectionMap.SetString(keyName, value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// now we append all items to the list
|
||||
#if 0
|
||||
for (auto const& [secName, registry] : registryMap) {
|
||||
auto& secMap = sections[secName];
|
||||
for (auto const& [key, value] : registry) {
|
||||
secMap.SetString("auto" + key, value);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
file.close();
|
||||
|
@ -183,7 +242,12 @@ BOOL CIniFile::SaveFile(const std::string& Filename) const
|
|||
for (auto const& sec : sections) {
|
||||
file << "[" << sec.first << "]" << endl;
|
||||
for (auto const& pair : sec.second) {
|
||||
file << pair.first << "=" << pair.second << endl;
|
||||
auto keyName = pair.first;
|
||||
// restore +=
|
||||
if (keyName[0] == '+') {
|
||||
keyName = '+';
|
||||
}
|
||||
file << keyName << "=" << pair.second << endl;
|
||||
}
|
||||
file << endl;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue