| 814 | } |
| 815 | |
| 816 | bool common_params_to_map(int argc, char ** argv, llama_example ex, std::map<common_arg, std::string> & out_map) { |
| 817 | common_params dummy_params; |
| 818 | common_params_context ctx_arg = common_params_parser_init(dummy_params, ex, nullptr); |
| 819 | |
| 820 | std::unordered_map<std::string, common_arg *> arg_to_options; |
| 821 | for (auto & opt : ctx_arg.options) { |
| 822 | for (const auto & arg : opt.args) { |
| 823 | arg_to_options[arg] = &opt; |
| 824 | } |
| 825 | for (const auto & arg : opt.args_neg) { |
| 826 | arg_to_options[arg] = &opt; |
| 827 | } |
| 828 | } |
| 829 | |
| 830 | // TODO @ngxson : find a way to deduplicate this code |
| 831 | |
| 832 | // handle command line arguments |
| 833 | auto check_arg = [&](int i) { |
| 834 | if (i+1 >= argc) { |
| 835 | throw std::invalid_argument("expected value for argument"); |
| 836 | } |
| 837 | }; |
| 838 | |
| 839 | std::set<std::string> seen_args; |
| 840 | |
| 841 | for (int i = 1; i < argc; i++) { |
| 842 | const std::string arg_prefix = "--"; |
| 843 | |
| 844 | std::string arg = argv[i]; |
| 845 | if (arg.compare(0, arg_prefix.size(), arg_prefix) == 0) { |
| 846 | std::replace(arg.begin(), arg.end(), '_', '-'); |
| 847 | } |
| 848 | if (arg_to_options.find(arg) == arg_to_options.end()) { |
| 849 | throw std::invalid_argument(string_format("error: invalid argument: %s", arg.c_str())); |
| 850 | } |
| 851 | if (!seen_args.insert(arg).second) { |
| 852 | LOG_WRN("DEPRECATED: argument '%s' specified multiple times, use comma-separated values instead (only last value will be used)\n", arg.c_str()); |
| 853 | } |
| 854 | auto opt = *arg_to_options[arg]; |
| 855 | std::string val; |
| 856 | if (opt.value_hint == nullptr && opt.value_hint_2 == nullptr) { |
| 857 | // bool arg (need to reverse the meaning for negative args) |
| 858 | bool is_neg = std::find(opt.args_neg.begin(), opt.args_neg.end(), arg) != opt.args_neg.end(); |
| 859 | val = is_neg ? "0" : "1"; |
| 860 | } |
| 861 | if (opt.value_hint != nullptr) { |
| 862 | // arg with single value |
| 863 | check_arg(i); |
| 864 | val = argv[++i]; |
| 865 | } |
| 866 | if (opt.value_hint_2 != nullptr) { |
| 867 | // TODO: support arg with 2 values |
| 868 | throw std::invalid_argument("error: argument with 2 values is not yet supported\n"); |
| 869 | } |
| 870 | out_map[opt] = val; |
| 871 | } |
| 872 | |
| 873 | return true; |
no test coverage detected