| 432 | // |
| 433 | |
| 434 | static bool common_params_parse_ex(int argc, char ** argv, common_params_context & ctx_arg) { |
| 435 | common_params & params = ctx_arg.params; |
| 436 | |
| 437 | std::unordered_map<std::string, std::pair<common_arg *, bool>> arg_to_options; |
| 438 | for (auto & opt : ctx_arg.options) { |
| 439 | for (const auto & arg : opt.args) { |
| 440 | arg_to_options[arg] = {&opt, /* is_positive */ true}; |
| 441 | } |
| 442 | for (const auto & arg : opt.args_neg) { |
| 443 | arg_to_options[arg] = {&opt, /* is_positive */ false}; |
| 444 | } |
| 445 | } |
| 446 | |
| 447 | // handle environment variables |
| 448 | for (auto & opt : ctx_arg.options) { |
| 449 | std::string value; |
| 450 | if (opt.get_value_from_env(value)) { |
| 451 | try { |
| 452 | if (opt.handler_void && is_truthy(value)) { |
| 453 | opt.handler_void(params); |
| 454 | } |
| 455 | if (opt.handler_int) { |
| 456 | opt.handler_int(params, std::stoi(value)); |
| 457 | } |
| 458 | if (opt.handler_bool) { |
| 459 | opt.handler_bool(params, parse_bool_value(value)); |
| 460 | } |
| 461 | if (opt.handler_string) { |
| 462 | opt.handler_string(params, value); |
| 463 | continue; |
| 464 | } |
| 465 | } catch (std::exception & e) { |
| 466 | throw std::invalid_argument(string_format( |
| 467 | "error while handling environment variable \"%s\": %s\n\n", opt.env, e.what())); |
| 468 | } |
| 469 | } |
| 470 | } |
| 471 | |
| 472 | // handle command line arguments |
| 473 | auto check_arg = [&](int i) { |
| 474 | if (i+1 >= argc) { |
| 475 | throw std::invalid_argument("expected value for argument"); |
| 476 | } |
| 477 | }; |
| 478 | |
| 479 | auto parse_cli_args = [&]() { |
| 480 | std::set<std::string> seen_args; |
| 481 | |
| 482 | for (int i = 1; i < argc; i++) { |
| 483 | const std::string arg_prefix = "--"; |
| 484 | |
| 485 | std::string arg = argv[i]; |
| 486 | if (arg.compare(0, arg_prefix.size(), arg_prefix) == 0) { |
| 487 | std::replace(arg.begin(), arg.end(), '_', '-'); |
| 488 | } |
| 489 | if (arg_to_options.find(arg) == arg_to_options.end()) { |
| 490 | throw std::invalid_argument(string_format("error: invalid argument: %s", arg.c_str())); |
| 491 | } |
no test coverage detected