* Convert command line arguments to params object when -named is enabled. * * The -named syntax accepts named arguments in NAME=VALUE format, as well as * positional arguments without names. The syntax is inherently ambiguous if * names are omitted and values contain '=', so a heuristic is used to * disambiguate: * * - Arguments that do not contain '=' are treated as positional parameters.
| 479 | * wallet with that literal name. |
| 480 | */ |
| 481 | UniValue RPCConvertNamedValues(const std::string &strMethod, const std::vector<std::string> &strParams) |
| 482 | { |
| 483 | UniValue params(UniValue::VOBJ); |
| 484 | UniValue positional_args{UniValue::VARR}; |
| 485 | |
| 486 | for (std::string_view s: strParams) { |
| 487 | size_t pos = s.find('='); |
| 488 | if (pos == std::string_view::npos) { |
| 489 | positional_args.push_back(ParseParam(rpc_convert::FromPosition(strMethod, positional_args.size()), s)); |
| 490 | continue; |
| 491 | } |
| 492 | |
| 493 | std::string name{s.substr(0, pos)}; |
| 494 | std::string_view value{s.substr(pos+1)}; |
| 495 | |
| 496 | const CRPCConvertParam* named_param{rpc_convert::FromName(strMethod, name)}; |
| 497 | if (!named_param) { |
| 498 | const CRPCConvertParam* positional_param = rpc_convert::FromPosition(strMethod, positional_args.size()); |
| 499 | UniValue parsed_value; |
| 500 | if (positional_param && positional_param->format == ParamFormat::JSON && parsed_value.read(s)) { |
| 501 | positional_args.push_back(std::move(parsed_value)); |
| 502 | continue; |
| 503 | } else if (positional_param && positional_param->format == ParamFormat::STRING) { |
| 504 | positional_args.push_back(s); |
| 505 | continue; |
| 506 | } |
| 507 | } |
| 508 | |
| 509 | // Intentionally overwrite earlier named values with later ones as a |
| 510 | // convenience for scripts and command line users that want to merge |
| 511 | // options. |
| 512 | params.pushKV(name, ParseParam(named_param, value)); |
| 513 | } |
| 514 | |
| 515 | if (!positional_args.empty()) { |
| 516 | // Use pushKVEnd instead of pushKV to avoid overwriting an explicit |
| 517 | // "args" value with an implicit one. Let the RPC server handle the |
| 518 | // request as given. |
| 519 | params.pushKVEnd("args", std::move(positional_args)); |
| 520 | } |
| 521 | |
| 522 | return params; |
| 523 | } |