Skip to content

Commit

Permalink
Merge pull request #34 from amelsmajic/master
Browse files Browse the repository at this point in the history
Option to throw exception when duplicate fields in section
  • Loading branch information
Rookfighter authored Feb 1, 2024
2 parents 91293f7 + 3d48174 commit 437df6b
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 0 deletions.
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,21 @@ int main()
}
```

When duplicate fields are decoded the previous value is simply overwritten by default. You can disallow duplicate fields from being overwritten by using the ```allowOverwriteDuplicateFields(false)``` function. If you do this, an exception will be thrown if a duplicate field is found inside a section.

```cpp
#include <inicpp.h>

int main()
{
// load an ini file
ini::IniFile myIni;
myIni.allowOverwriteDuplicateFields(false);
// throws an exception if the ini file has duplicate fields
myIni.load("some/ini/path");
}
```

Sections and fields can be accessed using the index operator ```[]```.
The values can be converted to various native types:

Expand Down
18 changes: 18 additions & 0 deletions include/inicpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,7 @@ namespace ini
char esc_ = '\\';
std::vector<std::string> commentPrefixes_ = { "#" , ";" };
bool multiLineValues_ = false;
bool overwriteDuplicateFields_ = true;

void eraseComment(const std::string &commentPrefix,
std::string &str,
Expand Down Expand Up @@ -581,6 +582,16 @@ namespace ini
multiLineValues_ = enable;
}

/** Sets whether or not overwriting duplicate fields is allowed.
* If overwriting duplicate fields is not allowed,
* an exception is thrown when a duplicate field is found inside a section.
* Default is true.
* @param allowed Is overwriting duplicate fields allowed or not? */
void allowOverwriteDuplicateFields(bool allowed)
{
overwriteDuplicateFields_ = allowed;
}

/** Tries to decode a ini file from the given input stream.
* @param is input stream from which data should be read. */
void decode(std::istream &is)
Expand Down Expand Up @@ -670,6 +681,13 @@ namespace ini
// retrieve field name and value
std::string name = line.substr(0, pos);
trim(name);
if (!overwriteDuplicateFields_ && currentSection->count(name) != 0)
{
std::stringstream ss;
ss << "l." << lineNo
<< ": ini parsing failed, duplicate field found";
throw std::logic_error(ss.str());
}
std::string value = line.substr(pos + 1, std::string::npos);
trim(value);
(*currentSection)[name] = value;
Expand Down
18 changes: 18 additions & 0 deletions test/test_inifile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,17 @@ TEST_CASE("parse section with duplicate field", "IniFile")
REQUIRE(inif["Foo"]["bar"].as<std::string>() == "world");
}

TEST_CASE("parse section with duplicate field and overwriteDuplicateFields_ set to true", "IniFile")
{
ini::IniFile inif;
inif.allowOverwriteDuplicateFields(true);
inif.decode("[Foo]\nbar=hello\nbar=world");

REQUIRE(inif.size() == 1);
REQUIRE(inif["Foo"].size() == 1);
REQUIRE(inif["Foo"]["bar"].as<std::string>() == "world");
}

TEST_CASE("parse field as bool", "IniFile")
{
std::istringstream ss("[Foo]\nbar1=true\nbar2=false\nbar3=tRuE");
Expand Down Expand Up @@ -865,3 +876,10 @@ TEST_CASE("spaces are not taken into account in sections", "IniFile")

REQUIRE(inif.find("Foo") != inif.end());
}

TEST_CASE("parse section with duplicate field and overwriteDuplicateFields_ set to false", "IniFile")
{
ini::IniFile inif;
inif.allowOverwriteDuplicateFields(false);
REQUIRE_THROWS(inif.decode("[Foo]\nbar=hello\nbar=world"));
}

0 comments on commit 437df6b

Please sign in to comment.