Skip to content

Commit ceb98f7

Browse files
Tmp push: Flexibler commandline handling
1 parent 3c36149 commit ceb98f7

File tree

8 files changed

+108
-37
lines changed

8 files changed

+108
-37
lines changed

src/net/config/ConfigInstance.cpp

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343

4444
#ifndef DOXYGEN_SHOULD_SKIP_THIS
4545

46+
#include "log/Logger.h"
4647
#include "utils/Config.h"
4748

4849
#include <cstddef>
@@ -163,13 +164,30 @@ namespace net::config {
163164
return requiredCount > 0;
164165
}
165166

167+
CLI::App* ConfigInstance::get() const {
168+
return instanceSc;
169+
}
170+
166171
CLI::App* ConfigInstance::getSection(const std::string& name, bool onlyGot, bool recursive) const {
167-
CLI::App* resultSc = (instanceSc->got_subcommand(name) || !onlyGot) ? instanceSc->get_subcommand_no_throw(name) : nullptr;
172+
CLI::App* resultSc = nullptr;
173+
174+
CLI::App* sectionSc = instanceSc->get_subcommand_no_throw(name);
175+
CLI::App* parentSectionSc = instanceSc->get_parent()->get_subcommand_no_throw(name);
176+
177+
if (sectionSc != nullptr) {
178+
VLOG(0) << "----------- Origin: " << sectionSc->get_name() << " " << sectionSc << ", C: " << sectionSc->count()
179+
<< " CA: " << sectionSc->count_all() << ", OnlyGot: " << onlyGot;
180+
}
181+
182+
if (parentSectionSc != nullptr) {
183+
VLOG(0) << "----------- Parent: " << parentSectionSc->get_name() << " " << parentSectionSc
184+
<< ", C: " << parentSectionSc->count() << " CA: " << parentSectionSc->count_all() << ", OnlyGot: " << onlyGot;
185+
}
168186

169-
if (resultSc == nullptr && recursive) {
170-
CLI::App* parentSc = instanceSc->get_parent();
171-
resultSc =
172-
(parentSc != nullptr && (parentSc->got_subcommand(name) || !onlyGot)) ? parentSc->get_subcommand_no_throw(name) : nullptr;
187+
if (sectionSc != nullptr && (sectionSc->count_all() > 0 || !onlyGot)) {
188+
resultSc = sectionSc;
189+
} else if (recursive && parentSectionSc != nullptr && (parentSectionSc->count_all() > 0 || !onlyGot)) {
190+
resultSc = parentSectionSc;
173191
}
174192

175193
return resultSc;

src/net/config/ConfigInstance.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ namespace net::config {
9393
void required(CLI::App* section, bool req = true);
9494
bool getRequired() const;
9595

96+
CLI::App* get() const;
97+
9698
private:
9799
uint8_t requiredCount = 0;
98100

src/utils/Config.cpp

Lines changed: 53 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -257,12 +257,7 @@ namespace utils {
257257
->type_name("configfile")
258258
->check(!CLI::ExistingDirectory);
259259

260-
app->add_option_function<std::string>(
261-
"-w,--write-config",
262-
[]([[maybe_unused]] const std::string& configFile) {
263-
throw CLI::CallForWriteConfig(configFile);
264-
},
265-
"Write config file and exit")
260+
app->add_option("-w,--write-config", "Write config file and exit")
266261
->configurable(false)
267262
->default_val(configDirectory + "/" + applicationName + ".conf")
268263
->type_name("[configfile]")
@@ -368,8 +363,8 @@ namespace utils {
368363
aliases.clear();
369364

370365
app->final_callback([]() {
371-
if (daemonizeOpt->as<bool>() && (*app)["--show-config"]->count() == 0 && (*app)["--write-config"]->count() == 0 &&
372-
(*app)["--command-line"]->count() == 0) {
366+
if (daemonizeOpt->as<bool>() && helpTriggerApp == nullptr && showConfigTriggerApp == nullptr &&
367+
(*app)["--write-config"]->count() == 0 && (*app)["--command-line"]->count() == 0) {
373368
std::cout << "Running as daemon (double fork)" << std::endl;
374369

375370
utils::Daemon::startDaemon(
@@ -415,9 +410,7 @@ namespace utils {
415410

416411
proceed = false;
417412
} else {
418-
if ((*app)["--show-config"]->count() == 0 && (*app)["--write-config"]->count() == 0 && (*app)["--command-line"]->count() == 0) {
419-
app->allow_extras(false);
420-
}
413+
app->allow_extras((*app)["--show-config"]->count() != 0);
421414

422415
if (!quietOpt->as<bool>()) {
423416
logger::Logger::setLogLevel(logLevelOpt->as<int>());
@@ -440,9 +433,9 @@ namespace utils {
440433
};
441434

442435
std::string out;
443-
out.reserve(s.size() * 2);
436+
out.reserve(s.size() * 3);
444437

445-
for (char c : s) {
438+
for (const char c : s) {
446439
if (special.contains(c)) {
447440
out.push_back('\\');
448441
}
@@ -522,7 +515,7 @@ namespace utils {
522515
createCommandLineOptions(out, app, mode);
523516

524517
std::string optionString = out.str();
525-
if (optionString.back() == ' ') {
518+
if (!optionString.empty() && optionString.back() == ' ') {
526519
optionString.pop_back();
527520
}
528521

@@ -586,22 +579,47 @@ namespace utils {
586579

587580
try {
588581
try {
589-
app->parse(argc, argv);
590-
success = true;
582+
try {
583+
app->parse(argc, argv);
584+
success = true;
585+
} catch (const CLI::ParseError&) {
586+
if (helpTriggerApp == nullptr) {
587+
if (showConfigTriggerApp != nullptr) {
588+
success = false;
589+
throw CLI::CallForShowConfig(showConfigTriggerApp);
590+
}
591+
if ((*app)["--write-config"]->count() > 0) {
592+
success = false;
593+
throw CLI::CallForWriteConfig((*app)["--write-config"]->as<std::string>());
594+
}
595+
}
596+
597+
throw;
598+
}
599+
if (helpTriggerApp == nullptr) {
600+
if (showConfigTriggerApp != nullptr) {
601+
success = false;
602+
throw CLI::CallForShowConfig(showConfigTriggerApp);
603+
}
604+
if ((*app)["--write-config"]->count() > 0) {
605+
success = false;
606+
throw CLI::CallForWriteConfig((*app)["--write-config"]->as<std::string>());
607+
}
608+
}
591609
} catch (const DaemonError& e) {
592610
std::cout << "Daemon error: " << e.what() << " ... exiting" << std::endl;
593611
} catch (const DaemonFailure& e) {
594612
std::cout << "Daemon failure: " << e.what() << " ... exiting" << std::endl;
595613
} catch (const DaemonSignaled& e) {
596614
std::cout << "Pid: " << getpid() << ", child pid: " << e.getPid() << ": " << e.what() << std::endl;
597615
} catch (const CLI::CallForHelp&) {
598-
const std::string helpMode = helpApp->get_option("--help")->as<std::string>();
616+
const std::string helpMode = helpTriggerApp->get_option("--help")->as<std::string>();
599617
const CLI::App* helpApp = nullptr;
600618
CLI::AppFormatMode mode = CLI::AppFormatMode::Normal;
601619
if (helpMode == "exact") {
602-
helpApp = utils::Config::helpApp;
620+
helpApp = utils::Config::helpTriggerApp;
603621
} else if (helpMode == "expanded") {
604-
helpApp = utils::Config::helpApp;
622+
helpApp = utils::Config::helpTriggerApp;
605623
mode = CLI::AppFormatMode::All;
606624
}
607625
std::cout << app->help(helpApp, "", mode) << std::endl;
@@ -657,10 +675,11 @@ namespace utils {
657675
throw;
658676
}
659677
} catch ([[maybe_unused]] const CLI::ParseError& e) {
660-
std::cout << std::endl << "Append -h or --help to your command line for more information." << std::endl;
678+
std::cout << std::endl << "Append -h or --help to your command line for more information." << std::endl;
661679
} catch (const CLI::Error& e) {
662-
std::cout << "[" << Color::Code::FG_RED << e.get_name() << Color::Code::FG_DEFAULT << "] " << e.what() << std::endl;
663-
std::cout << "Append -h or --help to your command line for more information." << std::endl;
680+
std::cout << "[" << Color::Code::FG_RED << e.get_name() << Color::Code::FG_DEFAULT << " ] " << e.what() << std::endl;
681+
682+
std::cout << std::endl << "Append -h or --help to your command line for more information." << std::endl;
664683
}
665684

666685
return success;
@@ -736,10 +755,10 @@ namespace utils {
736755

737756
CLI::App* Config::addStandardFlags(CLI::App* app) {
738757
app //
739-
->add_flag_callback(
758+
->add_flag_function(
740759
"-s,--show-config",
741-
[app]() {
742-
throw CLI::CallForShowConfig(app);
760+
[app](std::size_t) {
761+
showConfigTriggerApp = app;
743762
},
744763
"Show current configuration and exit") //
745764
->configurable(false)
@@ -800,9 +819,9 @@ namespace utils {
800819

801820
CLI::App* Config::addHelp(CLI::App* app) {
802821
app->set_help_flag(
803-
"-h{standard},--help{standard}",
822+
"-h{exact},--help{exact}",
804823
[app](std::size_t) {
805-
helpApp = app;
824+
helpTriggerApp = app;
806825
},
807826
"Print help message and exit")
808827
->group(app->get_formatter()->get_label("Nonpersistent Options"))
@@ -813,13 +832,13 @@ namespace utils {
813832

814833
CLI::App* Config::addSimpleHelp(CLI::App* app) {
815834
app->set_help_flag(
816-
"--help,-h",
835+
"--help{exact},-h{exact}",
817836
[app](std::size_t) {
818-
helpApp = app;
837+
helpTriggerApp = app;
819838
},
820839
"Print help message and exit")
821840
->group(app->get_formatter()->get_label("Nonpersistent Options"))
822-
->disable_flag_override();
841+
->check(CLI::IsMember({"standard", "exact"}));
823842

824843
return app;
825844
}
@@ -832,6 +851,7 @@ namespace utils {
832851
return sc->get_required();
833852
})) {
834853
instance->needs(sub);
854+
instance->configurable();
835855
}
836856
} else {
837857
app->remove_needs(instance);
@@ -840,6 +860,7 @@ namespace utils {
840860
return sc->get_required();
841861
})) {
842862
instance->remove_needs(sub);
863+
instance->configurable(false);
843864
}
844865
}
845866

@@ -988,7 +1009,8 @@ namespace utils {
9881009
CLI::Option* Config::verboseLevelOpt = nullptr;
9891010
CLI::Option* Config::quietOpt = nullptr;
9901011

991-
CLI::App* Config::helpApp = nullptr;
1012+
CLI::App* Config::helpTriggerApp = nullptr;
1013+
CLI::App* Config::showConfigTriggerApp = nullptr;
9921014

9931015
std::map<std::string, std::string> Config::aliases;
9941016
std::map<std::string, CLI::Option*> Config::applicationOptions;

src/utils/Config.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,11 @@ namespace utils {
149149
static CLI::Option* verboseLevelOpt;
150150
static CLI::Option* quietOpt;
151151

152-
static CLI::App* helpApp;
152+
public:
153+
static CLI::App* helpTriggerApp;
154+
static CLI::App* showConfigTriggerApp;
153155

156+
private:
154157
static std::map<std::string, std::string> aliases; // from -> to
155158
static std::map<std::string, CLI::Option*> applicationOptions; // keep all user options in memory
156159
};

src/utils/Exceptions.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,4 +90,12 @@ namespace CLI {
9090
return configFile;
9191
}
9292

93+
BootstrapError::BootstrapError(const std::string& error)
94+
: CLI::Error("BootstrapError", error, CLI::ExitCodes::RequiredError)
95+
, error(error) {
96+
}
97+
98+
BootstrapError::~BootstrapError() {
99+
}
100+
93101
} // namespace CLI

src/utils/Exceptions.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,15 @@ namespace CLI {
104104
std::string configFile;
105105
};
106106

107+
class BootstrapError : public CLI::Error {
108+
public:
109+
explicit BootstrapError(const std::string& error);
110+
~BootstrapError() override;
111+
112+
private:
113+
std::string error;
114+
};
115+
107116
} // namespace CLI
108117

109118
#endif // CLI_EXCEPTIONS_H

src/utils/Formatter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ namespace CLI {
175175
return outString + out.str();
176176
}
177177

178+
#ifndef CLI11_ORIGINAL_FORMATTER
178179
HelpFormatter::~HelpFormatter() {
179180
}
180181

@@ -446,4 +447,6 @@ namespace CLI {
446447
return out.str();
447448
}
448449

450+
#endif // CLI11_ORIGINAL_FORMATTER
451+
449452
} // namespace CLI

src/utils/Formatter.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@
6565

6666
#endif // DOXYGEN_SHOULD_SKIP_THIS
6767

68+
// #define CLI11_ORIGINAL_FORMATTER
69+
6870
namespace CLI {
6971

7072
class ConfigFormatter : public ConfigBase {
@@ -76,6 +78,8 @@ namespace CLI {
7678
};
7779

7880
class HelpFormatter : public CLI::Formatter {
81+
#ifndef CLI11_ORIGINAL_FORMATTER
82+
7983
public:
8084
~HelpFormatter() override;
8185

@@ -87,6 +91,8 @@ namespace CLI {
8791
std::string make_subcommand(const App* sub) const override;
8892
std::string make_expanded(const App* sub, AppFormatMode mode) const override;
8993
std::string make_option_opts(const Option* opt) const override;
94+
95+
#endif // CLI11_ORIGINAL_FORMATTER
9096
};
9197

9298
} // namespace CLI

0 commit comments

Comments
 (0)