IniFile: Remove support for comments anywhere but the beginning of lines

The MS INI parser and most other INI parsing libraries APIs only support
comments at the beginning of lines. Right now, some Game INI files use sections
like:

  [OnFrame]#Add memory patches here

But these section headers are parsed separately, so this should not break
them.
This commit is contained in:
Jasper St. Pierre 2013-08-11 09:19:46 -04:00
parent 3066d8471e
commit 0eaea5f4df
2 changed files with 17 additions and 32 deletions

View File

@ -20,45 +20,30 @@
namespace { namespace {
static void ParseLine(const std::string& line, std::string* keyOut, std::string* valueOut, std::string* commentOut) static void ParseLine(const std::string& line, std::string* keyOut, std::string* valueOut)
{ {
if (line[0] == '#')
return;
int FirstEquals = (int)line.find("=", 0); int FirstEquals = (int)line.find("=", 0);
int FirstCommentChar = -1;
// Comments if (FirstEquals >= 0)
if (FirstCommentChar < 0)
FirstCommentChar =
(int)line.find("#", FirstEquals > 0 ? FirstEquals : 0);
if (FirstCommentChar < 0 && line[0] == ';')
FirstCommentChar = 0;
// Allow preservation of spacing before comment
if (FirstCommentChar > 0)
{
while (line[FirstCommentChar - 1] == ' ' || line[FirstCommentChar - 1] == 9) // 9 == tab
{
FirstCommentChar--;
}
}
if ((FirstEquals >= 0) && ((FirstCommentChar < 0) || (FirstEquals < FirstCommentChar)))
{ {
// Yes, a valid line! // Yes, a valid line!
*keyOut = StripSpaces(line.substr(0, FirstEquals)); *keyOut = StripSpaces(line.substr(0, FirstEquals));
if (commentOut) *commentOut = FirstCommentChar > 0 ? line.substr(FirstCommentChar) : std::string(""); if (valueOut) *valueOut = StripQuotes(StripSpaces(line.substr(FirstEquals + 1, std::string::npos)));
if (valueOut) *valueOut = StripQuotes(StripSpaces(line.substr(FirstEquals + 1, FirstCommentChar - FirstEquals - 1)));
} }
} }
} }
std::string* IniFile::Section::GetLine(const char* key, std::string* valueOut, std::string* commentOut) std::string* IniFile::Section::GetLine(const char* key, std::string* valueOut)
{ {
for (std::vector<std::string>::iterator iter = lines.begin(); iter != lines.end(); ++iter) for (std::vector<std::string>::iterator iter = lines.begin(); iter != lines.end(); ++iter)
{ {
std::string& line = *iter; std::string& line = *iter;
std::string lineKey; std::string lineKey;
ParseLine(line, &lineKey, valueOut, commentOut); ParseLine(line, &lineKey, valueOut);
if (!strcasecmp(lineKey.c_str(), key)) if (!strcasecmp(lineKey.c_str(), key))
return &line; return &line;
} }
@ -67,12 +52,12 @@ std::string* IniFile::Section::GetLine(const char* key, std::string* valueOut, s
void IniFile::Section::Set(const char* key, const char* newValue) void IniFile::Section::Set(const char* key, const char* newValue)
{ {
std::string value, commented; std::string value;
std::string* line = GetLine(key, &value, &commented); std::string* line = GetLine(key, &value);
if (line) if (line)
{ {
// Change the value - keep the key and comment // Change the value - keep the key and comment
*line = StripSpaces(key) + " = " + newValue + commented; *line = StripSpaces(key) + " = " + newValue;
} }
else else
{ {
@ -91,7 +76,7 @@ void IniFile::Section::Set(const char* key, const std::string& newValue, const s
bool IniFile::Section::Get(const char* key, std::string* value, const char* defaultValue) bool IniFile::Section::Get(const char* key, std::string* value, const char* defaultValue)
{ {
std::string* line = GetLine(key, value, 0); std::string* line = GetLine(key, value);
if (!line) if (!line)
{ {
if (defaultValue) if (defaultValue)
@ -224,7 +209,7 @@ bool IniFile::Section::Exists(const char *key) const
for (std::vector<std::string>::const_iterator iter = lines.begin(); iter != lines.end(); ++iter) for (std::vector<std::string>::const_iterator iter = lines.begin(); iter != lines.end(); ++iter)
{ {
std::string lineKey; std::string lineKey;
ParseLine(*iter, &lineKey, NULL, NULL); ParseLine(*iter, &lineKey, NULL);
if (!strcasecmp(lineKey.c_str(), key)) if (!strcasecmp(lineKey.c_str(), key))
return true; return true;
} }
@ -233,7 +218,7 @@ bool IniFile::Section::Exists(const char *key) const
bool IniFile::Section::Delete(const char *key) bool IniFile::Section::Delete(const char *key)
{ {
std::string* line = GetLine(key, 0, 0); std::string* line = GetLine(key, 0);
for (std::vector<std::string>::iterator liter = lines.begin(); liter != lines.end(); ++liter) for (std::vector<std::string>::iterator liter = lines.begin(); liter != lines.end(); ++liter)
{ {
if (line == &*liter) if (line == &*liter)
@ -313,7 +298,7 @@ bool IniFile::DeleteKey(const char* sectionName, const char* key)
Section* section = GetSection(sectionName); Section* section = GetSection(sectionName);
if (!section) if (!section)
return false; return false;
std::string* line = section->GetLine(key, 0, 0); std::string* line = section->GetLine(key, 0);
for (std::vector<std::string>::iterator liter = section->lines.begin(); liter != section->lines.end(); ++liter) for (std::vector<std::string>::iterator liter = section->lines.begin(); liter != section->lines.end(); ++liter)
{ {
if (line == &(*liter)) if (line == &(*liter))
@ -335,7 +320,7 @@ bool IniFile::GetKeys(const char* sectionName, std::vector<std::string>& keys) c
for (std::vector<std::string>::const_iterator liter = section->lines.begin(); liter != section->lines.end(); ++liter) for (std::vector<std::string>::const_iterator liter = section->lines.begin(); liter != section->lines.end(); ++liter)
{ {
std::string key; std::string key;
ParseLine(*liter, &key, 0, 0); ParseLine(*liter, &key, 0);
keys.push_back(key); keys.push_back(key);
} }
return true; return true;

View File

@ -25,7 +25,7 @@ public:
bool Exists(const char *key) const; bool Exists(const char *key) const;
bool Delete(const char *key); bool Delete(const char *key);
std::string* GetLine(const char* key, std::string* valueOut, std::string* commentOut); std::string* GetLine(const char* key, std::string* valueOut);
void Set(const char* key, const char* newValue); void Set(const char* key, const char* newValue);
void Set(const char* key, const std::string& newValue, const std::string& defaultValue); void Set(const char* key, const std::string& newValue, const std::string& defaultValue);