Commit 8f4112be authored by Dominik Charousset's avatar Dominik Charousset Committed by Hauke Goldhammer

Add convenience function for C-style arg remainder

parent 065ad856
......@@ -185,9 +185,20 @@ public:
/// and instead return from `main` immediately.
bool cli_helptext_printed;
/// Stores the content of `argv[0]` from the arguments passed to `parse`.
std::string program_name;
/// Stores CLI arguments that were not consumed by CAF.
string_list remainder;
/// Returns the remainder including the program name (`argv[0]`) suitable for
/// passing the returned pair of arguments to C-style functions that usually
/// accept `(argc, argv)` input as passed to `main`. This function creates the
/// necessary buffers lazily on first call.
/// @note The returned pointer remains valid only as long as the
/// `actor_system_config` object exists.
std::pair<int, char**> c_args_remainder();
// -- caf-run parameters -----------------------------------------------------
/// Stores whether this node was started in slave mode.
......@@ -317,6 +328,9 @@ protected:
config_option_set custom_options_;
private:
std::vector<char*> c_args_remainder_;
std::vector<char> c_args_remainder_buf_;
actor_system_config& set_impl(string_view name, config_value value);
error extract_config_file_path(string_list& args);
......
......@@ -53,6 +53,7 @@ actor_system_config::~actor_system_config() {
actor_system_config::actor_system_config()
: cli_helptext_printed(false),
program_name("unknown-caf-app"),
slave_mode(false),
config_file_path(default_config_file),
slave_mode_fun(nullptr) {
......@@ -187,18 +188,45 @@ settings actor_system_config::dump_content() const {
error actor_system_config::parse(int argc, char** argv,
const char* config_file_cstr) {
string_list args;
if (argc > 1)
args.assign(argv + 1, argv + argc);
if (argc > 0) {
program_name = argv[0];
if (argc > 1)
args.assign(argv + 1, argv + argc);
}
return parse(std::move(args), config_file_cstr);
}
error actor_system_config::parse(int argc, char** argv, std::istream& conf) {
string_list args;
if (argc > 1)
args.assign(argv + 1, argv + argc);
if (argc > 0) {
program_name = argv[0];
if (argc > 1)
args.assign(argv + 1, argv + argc);
}
return parse(std::move(args), conf);
}
std::pair<int, char**> actor_system_config::c_args_remainder() {
if (c_args_remainder_.empty()) {
c_args_remainder_buf_.assign(program_name.begin(), program_name.end());
c_args_remainder_buf_.emplace_back('\0');
for (const auto& arg : remainder) {
c_args_remainder_buf_.insert(c_args_remainder_buf_.end(), //
arg.begin(), arg.end());
c_args_remainder_buf_.emplace_back('\0');
}
auto ptr = c_args_remainder_buf_.data();
auto end = ptr + c_args_remainder_buf_.size();
auto advance_ptr = [&ptr] {
while (*ptr++ != '\0')
; // nop
};
for (; ptr != end; advance_ptr())
c_args_remainder_.emplace_back(ptr);
}
return {static_cast<int>(c_args_remainder_.size()), c_args_remainder_.data()};
}
namespace {
struct config_iter {
......
......@@ -85,6 +85,9 @@ CAF_TEST(parsing - without CLI arguments) {
parse(text);
CAF_CHECK(cfg.remainder.empty());
CAF_CHECK_EQUAL(get_or(cfg, "foo.bar", ""), "hello");
auto [argc, argv] = cfg.c_args_remainder();
CAF_REQUIRE_EQUAL(argc, 1);
CAF_CHECK_EQUAL(argv[0], cfg.program_name);
}
CAF_TEST(parsing - without CLI cfg.remainder) {
......@@ -111,11 +114,15 @@ CAF_TEST(parsing - without CLI cfg.remainder) {
CAF_TEST(parsing - with CLI cfg.remainder) {
auto text = "foo{\nbar=\"hello\"}";
options("?foo").add<std::string>("bar,b", "some string parameter");
CAF_MESSAGE("valid cfg.remainder");
parse(text, {"-b", "test", "hello", "world"});
CAF_REQUIRE_EQUAL(cfg.remainder.size(), 2u);
CAF_CHECK_EQUAL(get_or(cfg, "foo.bar", ""), "test");
CAF_CHECK_EQUAL(cfg.remainder, string_list({"hello", "world"}));
CAF_MESSAGE("invalid cfg.remainder");
auto [argc, argv] = cfg.c_args_remainder();
CAF_REQUIRE_EQUAL(argc, 3);
CAF_CHECK_EQUAL(argv[0], cfg.program_name);
CAF_CHECK_EQUAL(argv[1], cfg.remainder[0]);
CAF_CHECK_EQUAL(argv[2], cfg.remainder[1]);
}
CAF_TEST(file input overrides defaults but CLI args always win) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment