| 291 | } |
| 292 | |
| 293 | const char *param_subcommand(struct command *cmd, const char *buffer, |
| 294 | const jsmntok_t tokens[], |
| 295 | const char *name, ...) |
| 296 | { |
| 297 | va_list ap; |
| 298 | struct param *params = tal_arr(cmd, struct param, 0); |
| 299 | const char *arg, **names = tal_arr(tmpctx, const char *, 1); |
| 300 | const char *subcmd; |
| 301 | |
| 302 | param_add(¶ms, "subcommand", PARAM_REQUIRED, NULL, NULL, |
| 303 | (void *)param_string, &subcmd); |
| 304 | names[0] = name; |
| 305 | va_start(ap, name); |
| 306 | while ((arg = va_arg(ap, const char *)) != NULL) |
| 307 | tal_arr_expand(&names, arg); |
| 308 | va_end(ap); |
| 309 | |
| 310 | if (command_usage_only(cmd)) { |
| 311 | char *usage = tal_strdup(cmd, "subcommand"); |
| 312 | for (size_t i = 0; i < tal_count(names); i++) |
| 313 | tal_append_fmt(&usage, "%c%s", |
| 314 | i == 0 ? '=' : '|', names[i]); |
| 315 | check_params(params); |
| 316 | command_set_usage(cmd, usage); |
| 317 | return NULL; |
| 318 | } |
| 319 | |
| 320 | /* Check it's valid */ |
| 321 | if (param_arr(cmd, buffer, tokens, params, true) != NULL) { |
| 322 | return NULL; |
| 323 | } |
| 324 | |
| 325 | /* Check it's one of the known ones. */ |
| 326 | for (size_t i = 0; i < tal_count(names); i++) |
| 327 | if (streq(subcmd, names[i])) |
| 328 | return subcmd; |
| 329 | |
| 330 | /* We really do ignore this. */ |
| 331 | struct command_result *ignore; |
| 332 | ignore = command_fail(cmd, JSONRPC2_INVALID_PARAMS, |
| 333 | "Unknown subcommand '%s'", subcmd); |
| 334 | assert(ignore); |
| 335 | return NULL; |
| 336 | } |
| 337 | |
| 338 | static bool param_core(struct command *cmd, |
| 339 | const char *buffer, |
no test coverage detected