1
0
mirror of https://github.com/CLIUtils/CLI11.git synced 2025-05-03 14:03:52 +00:00

Fix and add cov for subcom ini parser

This commit is contained in:
Henry Fredrick Schreiner 2017-03-17 12:04:22 -04:00
parent 17564cec05
commit a3522c1ddf
4 changed files with 50 additions and 5 deletions

View File

@ -6,6 +6,7 @@
* Added CodeCov code coverage reports * Added CodeCov code coverage reports
* Lots of small bugfixes related to adding tests to increase coverage * Lots of small bugfixes related to adding tests to increase coverage
* Error handling now uses scoped enum in errors * Error handling now uses scoped enum in errors
* Reparsing rules changed a little to accommodate Ini files. Callbacks are now called when parsing INI, and reset any time results are added.
## Version 0.6 ## Version 0.6

View File

@ -758,7 +758,7 @@ protected:
std::vector<detail::ini_ret_t> values = detail::parse_ini(config_name_); std::vector<detail::ini_ret_t> values = detail::parse_ini(config_name_);
while(values.size() > 0) { while(values.size() > 0) {
if(!_parse_ini(values)) { if(!_parse_ini(values)) {
throw ExtrasError(values.back().name()); throw ExtrasINIError(values.back().fullname);
} }
} }
} catch (const FileError &) { } catch (const FileError &) {
@ -780,7 +780,7 @@ protected:
// Process callbacks // Process callbacks
for(const Option_p& opt : options_) { for(const Option_p& opt : options_) {
if (opt->count() > 0) { if (opt->count() > 0 && !opt->get_callback_run()) {
opt->run_callback(); opt->run_callback();
} }
} }
@ -827,15 +827,17 @@ protected:
/// Returns true if it managed to find the option, if false you'll need to remove the arg manully. /// Returns true if it managed to find the option, if false you'll need to remove the arg manully.
bool _parse_ini(std::vector<detail::ini_ret_t> &args) { bool _parse_ini(std::vector<detail::ini_ret_t> &args) {
detail::ini_ret_t& current = args.back(); detail::ini_ret_t& current = args.back();
std::string parent = current.parent(); std::string parent = current.parent(); // respects curent.level
std::string name = current.name(); std::string name = current.name();
std::cout << current.fullname << " " << parent << " " << name << std::endl;
// If a parent is listed, go to a subcommand
if(parent != "") { if(parent != "") {
current.level++; current.level++;
for(const App_p &com : subcommands_) for(const App_p &com : subcommands_)
if(com->check_name(parent)) if(com->check_name(parent))
return com->_parse_ini(args); return com->_parse_ini(args);
return false; return false;
//throw CLI::ExtraINIError(current.fullname);
} }
auto op_ptr = std::find_if(std::begin(options_), std::end(options_), auto op_ptr = std::find_if(std::begin(options_), std::end(options_),
@ -868,8 +870,10 @@ protected:
} }
} else } else
throw ConversionError(current.fullname + ": too many inputs for a flag"); throw ConversionError(current.fullname + ": too many inputs for a flag");
} else } else {
op->results_ = current.inputs; op->results_ = current.inputs;
op->run_callback();
}
} }
args.pop_back(); args.pop_back();

View File

@ -106,6 +106,9 @@ protected:
/// Results of parsing /// Results of parsing
results_t results_; results_t results_;
/// Whether the callback has run (needed for INI parsing)
bool callback_run_ {false};
///@} ///@}
/// Making an option by hand is not defined, it must be made by the App class /// Making an option by hand is not defined, it must be made by the App class
@ -442,6 +445,7 @@ public:
/// Puts a result at position r /// Puts a result at position r
void add_result(std::string s) { void add_result(std::string s) {
results_.push_back(s); results_.push_back(s);
callback_run_ = false;
} }
@ -450,6 +454,11 @@ public:
return results_; return results_;
} }
/// See if the callback has been run already
bool get_callback_run() const {
return callback_run_;
}
///@} ///@}
protected: protected:

View File

@ -294,6 +294,37 @@ TEST_F(TApp, IniVector) {
} }
TEST_F(TApp, IniLayered) {
TempFile tmpini{"TestIniTmp.ini"};
app.add_config("--config", tmpini);
{
std::ofstream out{tmpini};
out << "[default]" << std::endl;
out << "val=1" << std::endl;
out << "[subcom]" << std::endl;
out << "val=2" << std::endl;
out << "subsubcom.val=3" << std::endl;
}
int one=0, two=0, three=0;
app.add_option("--val", one);
auto subcom = app.add_subcommand("subcom");
subcom->add_option("--val", two);
auto subsubcom = subcom->add_subcommand("subsubcom");
subsubcom->add_option("--val", three);
ASSERT_NO_THROW(run());
EXPECT_EQ(1, one);
EXPECT_EQ(2, two);
EXPECT_EQ(3, three);
}
TEST_F(TApp, IniFlags) { TEST_F(TApp, IniFlags) {
TempFile tmpini{"TestIniTmp.ini"}; TempFile tmpini{"TestIniTmp.ini"};
app.add_config("--config", tmpini); app.add_config("--config", tmpini);