|
|
|
#include <ccan/asort/asort.h>
|
Typesafe callback system for parsing json
This is part of #1464 and incorporates Rusty's suggested updates from #1569.
See comment in param.h for description, here's the basics:
unsigned cltv;
const jsmntok_t *note;
u64 msatoshi;
struct param * mp;
if (!param_parse(cmd, buffer, tokens,
param_req("cltv", json_tok_number, &cltv),
param_opt("note", json_tok_tok, &note),
mp = param_opt("msatoshi", json_tok_u64, &msatoshi),
NULL))
return;
if (param_is_set(mp))
do_something()
There is a lot of developer mode code to make sure we don't make mistakes,
like trying to unmarshal into the same variable twice or adding a required param
after optional.
During testing, I found a bug (of sorts) in the current system. It allows you
to provide two named parameters with the same name without error; e.g.:
# cli/lightning-cli -k newaddr addresstype=p2sh-segwit addresstype=bech32
{
"address": "2N3r6fT65PhfhE1mcMS6TtcdaEurud6M7pA"
}
It just takes the first and ignores the second. The new system reports this as an
error for now. We can always change this later.
7 years ago
|
|
|
#include <ccan/tal/str/str.h>
|
|
|
|
#include <common/utils.h>
|
|
|
|
#include <lightningd/json.h>
|
|
|
|
#include <lightningd/jsonrpc.h>
|
|
|
|
#include <lightningd/jsonrpc_errors.h>
|
|
|
|
#include <lightningd/lightningd.h>
|
|
|
|
#include <lightningd/params.h>
|
|
|
|
|
|
|
|
struct param {
|
|
|
|
const tal_t *ctx;
|
Typesafe callback system for parsing json
This is part of #1464 and incorporates Rusty's suggested updates from #1569.
See comment in param.h for description, here's the basics:
unsigned cltv;
const jsmntok_t *note;
u64 msatoshi;
struct param * mp;
if (!param_parse(cmd, buffer, tokens,
param_req("cltv", json_tok_number, &cltv),
param_opt("note", json_tok_tok, &note),
mp = param_opt("msatoshi", json_tok_u64, &msatoshi),
NULL))
return;
if (param_is_set(mp))
do_something()
There is a lot of developer mode code to make sure we don't make mistakes,
like trying to unmarshal into the same variable twice or adding a required param
after optional.
During testing, I found a bug (of sorts) in the current system. It allows you
to provide two named parameters with the same name without error; e.g.:
# cli/lightning-cli -k newaddr addresstype=p2sh-segwit addresstype=bech32
{
"address": "2N3r6fT65PhfhE1mcMS6TtcdaEurud6M7pA"
}
It just takes the first and ignores the second. The new system reports this as an
error for now. We can always change this later.
7 years ago
|
|
|
char *name;
|
|
|
|
bool is_set;
|
|
|
|
param_cb cb;
|
|
|
|
void *arg;
|
|
|
|
size_t argsize;
|
Typesafe callback system for parsing json
This is part of #1464 and incorporates Rusty's suggested updates from #1569.
See comment in param.h for description, here's the basics:
unsigned cltv;
const jsmntok_t *note;
u64 msatoshi;
struct param * mp;
if (!param_parse(cmd, buffer, tokens,
param_req("cltv", json_tok_number, &cltv),
param_opt("note", json_tok_tok, &note),
mp = param_opt("msatoshi", json_tok_u64, &msatoshi),
NULL))
return;
if (param_is_set(mp))
do_something()
There is a lot of developer mode code to make sure we don't make mistakes,
like trying to unmarshal into the same variable twice or adding a required param
after optional.
During testing, I found a bug (of sorts) in the current system. It allows you
to provide two named parameters with the same name without error; e.g.:
# cli/lightning-cli -k newaddr addresstype=p2sh-segwit addresstype=bech32
{
"address": "2N3r6fT65PhfhE1mcMS6TtcdaEurud6M7pA"
}
It just takes the first and ignores the second. The new system reports this as an
error for now. We can always change this later.
7 years ago
|
|
|
};
|
|
|
|
|
|
|
|
struct param *param_add_(const tal_t *ctx,
|
|
|
|
char *name, param_cb cb, void *arg, size_t argsize)
|
Typesafe callback system for parsing json
This is part of #1464 and incorporates Rusty's suggested updates from #1569.
See comment in param.h for description, here's the basics:
unsigned cltv;
const jsmntok_t *note;
u64 msatoshi;
struct param * mp;
if (!param_parse(cmd, buffer, tokens,
param_req("cltv", json_tok_number, &cltv),
param_opt("note", json_tok_tok, &note),
mp = param_opt("msatoshi", json_tok_u64, &msatoshi),
NULL))
return;
if (param_is_set(mp))
do_something()
There is a lot of developer mode code to make sure we don't make mistakes,
like trying to unmarshal into the same variable twice or adding a required param
after optional.
During testing, I found a bug (of sorts) in the current system. It allows you
to provide two named parameters with the same name without error; e.g.:
# cli/lightning-cli -k newaddr addresstype=p2sh-segwit addresstype=bech32
{
"address": "2N3r6fT65PhfhE1mcMS6TtcdaEurud6M7pA"
}
It just takes the first and ignores the second. The new system reports this as an
error for now. We can always change this later.
7 years ago
|
|
|
{
|
|
|
|
#if DEVELOPER
|
|
|
|
assert(name);
|
|
|
|
assert(cb);
|
|
|
|
assert(arg);
|
|
|
|
#endif
|
|
|
|
struct param *last = tal(tmpctx, struct param);
|
|
|
|
last->ctx = ctx;
|
Typesafe callback system for parsing json
This is part of #1464 and incorporates Rusty's suggested updates from #1569.
See comment in param.h for description, here's the basics:
unsigned cltv;
const jsmntok_t *note;
u64 msatoshi;
struct param * mp;
if (!param_parse(cmd, buffer, tokens,
param_req("cltv", json_tok_number, &cltv),
param_opt("note", json_tok_tok, &note),
mp = param_opt("msatoshi", json_tok_u64, &msatoshi),
NULL))
return;
if (param_is_set(mp))
do_something()
There is a lot of developer mode code to make sure we don't make mistakes,
like trying to unmarshal into the same variable twice or adding a required param
after optional.
During testing, I found a bug (of sorts) in the current system. It allows you
to provide two named parameters with the same name without error; e.g.:
# cli/lightning-cli -k newaddr addresstype=p2sh-segwit addresstype=bech32
{
"address": "2N3r6fT65PhfhE1mcMS6TtcdaEurud6M7pA"
}
It just takes the first and ignores the second. The new system reports this as an
error for now. We can always change this later.
7 years ago
|
|
|
last->is_set = false;
|
|
|
|
last->name = tal_strdup(last, name);
|
|
|
|
last->cb = cb;
|
|
|
|
last->arg = arg;
|
|
|
|
last->argsize = argsize;
|
|
|
|
/* Non-NULL means we are supposed to allocate iff found */
|
|
|
|
if (last->ctx)
|
|
|
|
*(void **)last->arg = NULL;
|
|
|
|
return last;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct param *param_opt_add_(const tal_t *ctx, char *name, const jsmntok_t **tok)
|
|
|
|
{
|
|
|
|
struct param *last = tal(tmpctx, struct param);
|
|
|
|
assert(ctx);
|
|
|
|
last->ctx = ctx;
|
|
|
|
last->is_set = false;
|
|
|
|
last->name = tal_strdup(last, name);
|
|
|
|
last->cb = (param_cb)json_tok_tok;
|
|
|
|
last->arg = tok;
|
|
|
|
last->argsize = sizeof(*tok);
|
|
|
|
*tok = NULL;
|
Typesafe callback system for parsing json
This is part of #1464 and incorporates Rusty's suggested updates from #1569.
See comment in param.h for description, here's the basics:
unsigned cltv;
const jsmntok_t *note;
u64 msatoshi;
struct param * mp;
if (!param_parse(cmd, buffer, tokens,
param_req("cltv", json_tok_number, &cltv),
param_opt("note", json_tok_tok, &note),
mp = param_opt("msatoshi", json_tok_u64, &msatoshi),
NULL))
return;
if (param_is_set(mp))
do_something()
There is a lot of developer mode code to make sure we don't make mistakes,
like trying to unmarshal into the same variable twice or adding a required param
after optional.
During testing, I found a bug (of sorts) in the current system. It allows you
to provide two named parameters with the same name without error; e.g.:
# cli/lightning-cli -k newaddr addresstype=p2sh-segwit addresstype=bech32
{
"address": "2N3r6fT65PhfhE1mcMS6TtcdaEurud6M7pA"
}
It just takes the first and ignores the second. The new system reports this as an
error for now. We can always change this later.
7 years ago
|
|
|
return last;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct fail_format {
|
|
|
|
void *cb;
|
|
|
|
const char *format;
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct fail_format fail_formats[] = {
|
|
|
|
{json_tok_bool, "'%s' should be 'true' or 'false', not '%.*s'"},
|
|
|
|
{json_tok_double, "'%s' should be a double, not '%.*s'"},
|
|
|
|
{json_tok_u64, "'%s' should be an unsigned 64 bit integer, not '%.*s'"},
|
|
|
|
{json_tok_number, "'%s' should be an integer, not '%.*s'"},
|
|
|
|
{json_tok_wtx,
|
|
|
|
"'%s' should be 'all' or a positive integer greater than "
|
|
|
|
"545, not '%.*s'"},
|
|
|
|
{NULL, "'%s' of '%.*s' is invalid'"}
|
|
|
|
};
|
|
|
|
|
|
|
|
static const char *find_fail_format(param_cb cb)
|
|
|
|
{
|
|
|
|
struct fail_format *fmt = fail_formats;
|
|
|
|
while (fmt->cb != NULL) {
|
|
|
|
if (fmt->cb == cb)
|
|
|
|
break;
|
|
|
|
fmt++;
|
|
|
|
}
|
|
|
|
return fmt->format;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool make_callback(struct command *cmd,
|
|
|
|
struct param *def,
|
|
|
|
const char *buffer, const jsmntok_t * tok)
|
|
|
|
{
|
|
|
|
void *arg;
|
Typesafe callback system for parsing json
This is part of #1464 and incorporates Rusty's suggested updates from #1569.
See comment in param.h for description, here's the basics:
unsigned cltv;
const jsmntok_t *note;
u64 msatoshi;
struct param * mp;
if (!param_parse(cmd, buffer, tokens,
param_req("cltv", json_tok_number, &cltv),
param_opt("note", json_tok_tok, &note),
mp = param_opt("msatoshi", json_tok_u64, &msatoshi),
NULL))
return;
if (param_is_set(mp))
do_something()
There is a lot of developer mode code to make sure we don't make mistakes,
like trying to unmarshal into the same variable twice or adding a required param
after optional.
During testing, I found a bug (of sorts) in the current system. It allows you
to provide two named parameters with the same name without error; e.g.:
# cli/lightning-cli -k newaddr addresstype=p2sh-segwit addresstype=bech32
{
"address": "2N3r6fT65PhfhE1mcMS6TtcdaEurud6M7pA"
}
It just takes the first and ignores the second. The new system reports this as an
error for now. We can always change this later.
7 years ago
|
|
|
def->is_set = true;
|
|
|
|
if (def->argsize && def->cb != (param_cb)json_tok_tok) {
|
|
|
|
*(void **)def->arg
|
|
|
|
= arg
|
|
|
|
= tal_alloc_(def->ctx, def->argsize, false, false,
|
|
|
|
"param");
|
|
|
|
} else
|
|
|
|
arg = def->arg;
|
|
|
|
if (!def->cb(buffer, tok, arg)) {
|
Typesafe callback system for parsing json
This is part of #1464 and incorporates Rusty's suggested updates from #1569.
See comment in param.h for description, here's the basics:
unsigned cltv;
const jsmntok_t *note;
u64 msatoshi;
struct param * mp;
if (!param_parse(cmd, buffer, tokens,
param_req("cltv", json_tok_number, &cltv),
param_opt("note", json_tok_tok, &note),
mp = param_opt("msatoshi", json_tok_u64, &msatoshi),
NULL))
return;
if (param_is_set(mp))
do_something()
There is a lot of developer mode code to make sure we don't make mistakes,
like trying to unmarshal into the same variable twice or adding a required param
after optional.
During testing, I found a bug (of sorts) in the current system. It allows you
to provide two named parameters with the same name without error; e.g.:
# cli/lightning-cli -k newaddr addresstype=p2sh-segwit addresstype=bech32
{
"address": "2N3r6fT65PhfhE1mcMS6TtcdaEurud6M7pA"
}
It just takes the first and ignores the second. The new system reports this as an
error for now. We can always change this later.
7 years ago
|
|
|
struct json_result *data = new_json_result(cmd);
|
|
|
|
const char *val = tal_fmt(cmd, "%.*s", tok->end - tok->start,
|
|
|
|
buffer + tok->start);
|
|
|
|
json_object_start(data, NULL);
|
|
|
|
json_add_string(data, def->name, val);
|
|
|
|
json_object_end(data);
|
|
|
|
command_fail_detailed(cmd, JSONRPC2_INVALID_PARAMS, data,
|
|
|
|
find_fail_format(def->cb), def->name,
|
|
|
|
tok->end - tok->start,
|
|
|
|
buffer + tok->start);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct param **post_check(struct command *cmd, struct param **params)
|
|
|
|
{
|
|
|
|
struct param **first = params;
|
|
|
|
struct param **last = first + tal_count(params);
|
|
|
|
|
|
|
|
/* Make sure required params were provided. */
|
|
|
|
while (first != last && (*first)->argsize == 0) {
|
Typesafe callback system for parsing json
This is part of #1464 and incorporates Rusty's suggested updates from #1569.
See comment in param.h for description, here's the basics:
unsigned cltv;
const jsmntok_t *note;
u64 msatoshi;
struct param * mp;
if (!param_parse(cmd, buffer, tokens,
param_req("cltv", json_tok_number, &cltv),
param_opt("note", json_tok_tok, &note),
mp = param_opt("msatoshi", json_tok_u64, &msatoshi),
NULL))
return;
if (param_is_set(mp))
do_something()
There is a lot of developer mode code to make sure we don't make mistakes,
like trying to unmarshal into the same variable twice or adding a required param
after optional.
During testing, I found a bug (of sorts) in the current system. It allows you
to provide two named parameters with the same name without error; e.g.:
# cli/lightning-cli -k newaddr addresstype=p2sh-segwit addresstype=bech32
{
"address": "2N3r6fT65PhfhE1mcMS6TtcdaEurud6M7pA"
}
It just takes the first and ignores the second. The new system reports this as an
error for now. We can always change this later.
7 years ago
|
|
|
if (!(*first)->is_set) {
|
|
|
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
|
|
|
"missing required parameter: '%s'",
|
|
|
|
(*first)->name);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
first++;
|
|
|
|
}
|
|
|
|
return params;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct param **parse_by_position(struct command *cmd,
|
|
|
|
struct param **params,
|
|
|
|
const char *buffer,
|
|
|
|
const jsmntok_t tokens[])
|
|
|
|
{
|
|
|
|
const jsmntok_t *tok = tokens + 1;
|
|
|
|
const jsmntok_t *end = json_next(tokens);
|
|
|
|
struct param **first = params;
|
|
|
|
struct param **last = first + tal_count(params);
|
|
|
|
|
|
|
|
while (first != last && tok != end) {
|
|
|
|
if (!json_tok_is_null(buffer, tok))
|
|
|
|
if (!make_callback(cmd, *first, buffer, tok))
|
|
|
|
return NULL;
|
|
|
|
tok = json_next(tok);
|
|
|
|
first++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* check for unexpected trailing params */
|
|
|
|
if (tok != end) {
|
|
|
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
|
|
|
"too many parameters:"
|
|
|
|
" got %u, expected %zu",
|
|
|
|
tokens->size, tal_count(params));
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return post_check(cmd, params);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct param *find_param(struct param **params, const char *start,
|
|
|
|
size_t n)
|
|
|
|
{
|
|
|
|
struct param **first = params;
|
|
|
|
struct param **last = first + tal_count(params);
|
|
|
|
|
|
|
|
while (first != last) {
|
|
|
|
if (strncmp((*first)->name, start, n) == 0)
|
|
|
|
if (strlen((*first)->name) == n)
|
|
|
|
return *first;
|
|
|
|
first++;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct param **parse_by_name(struct command *cmd,
|
|
|
|
struct param **params,
|
|
|
|
const char *buffer,
|
|
|
|
const jsmntok_t tokens[])
|
|
|
|
{
|
|
|
|
const jsmntok_t *first = tokens + 1;
|
|
|
|
const jsmntok_t *last = json_next(tokens);
|
|
|
|
|
|
|
|
while (first != last) {
|
|
|
|
struct param *p = find_param(params, buffer + first->start,
|
|
|
|
first->end - first->start);
|
|
|
|
if (!p) {
|
|
|
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
|
|
|
"unknown parameter: '%.*s'",
|
|
|
|
first->end - first->start,
|
|
|
|
buffer + first->start);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (p->is_set) {
|
|
|
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
|
|
|
"duplicate json names: '%s'", p->name);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!make_callback(cmd, p, buffer, first + 1))
|
|
|
|
return NULL;
|
|
|
|
first = json_next(first + 1);
|
|
|
|
}
|
|
|
|
return post_check(cmd, params);
|
|
|
|
}
|
|
|
|
|
|
|
|
#if DEVELOPER
|
|
|
|
static int comp_by_name(struct param *const *a, struct param *const *b,
|
|
|
|
void *unused)
|
Typesafe callback system for parsing json
This is part of #1464 and incorporates Rusty's suggested updates from #1569.
See comment in param.h for description, here's the basics:
unsigned cltv;
const jsmntok_t *note;
u64 msatoshi;
struct param * mp;
if (!param_parse(cmd, buffer, tokens,
param_req("cltv", json_tok_number, &cltv),
param_opt("note", json_tok_tok, &note),
mp = param_opt("msatoshi", json_tok_u64, &msatoshi),
NULL))
return;
if (param_is_set(mp))
do_something()
There is a lot of developer mode code to make sure we don't make mistakes,
like trying to unmarshal into the same variable twice or adding a required param
after optional.
During testing, I found a bug (of sorts) in the current system. It allows you
to provide two named parameters with the same name without error; e.g.:
# cli/lightning-cli -k newaddr addresstype=p2sh-segwit addresstype=bech32
{
"address": "2N3r6fT65PhfhE1mcMS6TtcdaEurud6M7pA"
}
It just takes the first and ignores the second. The new system reports this as an
error for now. We can always change this later.
7 years ago
|
|
|
{
|
|
|
|
return strcmp((*a)->name, (*b)->name);
|
Typesafe callback system for parsing json
This is part of #1464 and incorporates Rusty's suggested updates from #1569.
See comment in param.h for description, here's the basics:
unsigned cltv;
const jsmntok_t *note;
u64 msatoshi;
struct param * mp;
if (!param_parse(cmd, buffer, tokens,
param_req("cltv", json_tok_number, &cltv),
param_opt("note", json_tok_tok, &note),
mp = param_opt("msatoshi", json_tok_u64, &msatoshi),
NULL))
return;
if (param_is_set(mp))
do_something()
There is a lot of developer mode code to make sure we don't make mistakes,
like trying to unmarshal into the same variable twice or adding a required param
after optional.
During testing, I found a bug (of sorts) in the current system. It allows you
to provide two named parameters with the same name without error; e.g.:
# cli/lightning-cli -k newaddr addresstype=p2sh-segwit addresstype=bech32
{
"address": "2N3r6fT65PhfhE1mcMS6TtcdaEurud6M7pA"
}
It just takes the first and ignores the second. The new system reports this as an
error for now. We can always change this later.
7 years ago
|
|
|
}
|
|
|
|
|
|
|
|
static int comp_by_arg(struct param *const *a, struct param *const *b,
|
|
|
|
void *unused)
|
Typesafe callback system for parsing json
This is part of #1464 and incorporates Rusty's suggested updates from #1569.
See comment in param.h for description, here's the basics:
unsigned cltv;
const jsmntok_t *note;
u64 msatoshi;
struct param * mp;
if (!param_parse(cmd, buffer, tokens,
param_req("cltv", json_tok_number, &cltv),
param_opt("note", json_tok_tok, &note),
mp = param_opt("msatoshi", json_tok_u64, &msatoshi),
NULL))
return;
if (param_is_set(mp))
do_something()
There is a lot of developer mode code to make sure we don't make mistakes,
like trying to unmarshal into the same variable twice or adding a required param
after optional.
During testing, I found a bug (of sorts) in the current system. It allows you
to provide two named parameters with the same name without error; e.g.:
# cli/lightning-cli -k newaddr addresstype=p2sh-segwit addresstype=bech32
{
"address": "2N3r6fT65PhfhE1mcMS6TtcdaEurud6M7pA"
}
It just takes the first and ignores the second. The new system reports this as an
error for now. We can always change this later.
7 years ago
|
|
|
{
|
|
|
|
/* size_t could be larger than int: don't turn a 4bn difference into 0 */
|
|
|
|
if ((*a)->arg > (*b)->arg)
|
|
|
|
return 1;
|
|
|
|
else if ((*a)->arg < (*b)->arg)
|
|
|
|
return -1;
|
|
|
|
return 0;
|
Typesafe callback system for parsing json
This is part of #1464 and incorporates Rusty's suggested updates from #1569.
See comment in param.h for description, here's the basics:
unsigned cltv;
const jsmntok_t *note;
u64 msatoshi;
struct param * mp;
if (!param_parse(cmd, buffer, tokens,
param_req("cltv", json_tok_number, &cltv),
param_opt("note", json_tok_tok, &note),
mp = param_opt("msatoshi", json_tok_u64, &msatoshi),
NULL))
return;
if (param_is_set(mp))
do_something()
There is a lot of developer mode code to make sure we don't make mistakes,
like trying to unmarshal into the same variable twice or adding a required param
after optional.
During testing, I found a bug (of sorts) in the current system. It allows you
to provide two named parameters with the same name without error; e.g.:
# cli/lightning-cli -k newaddr addresstype=p2sh-segwit addresstype=bech32
{
"address": "2N3r6fT65PhfhE1mcMS6TtcdaEurud6M7pA"
}
It just takes the first and ignores the second. The new system reports this as an
error for now. We can always change this later.
7 years ago
|
|
|
}
|
|
|
|
|
|
|
|
/* This comparator is a bit different, but works well.
|
|
|
|
* Return 0 if @a is optional and @b is required. Otherwise return 1.
|
|
|
|
*/
|
|
|
|
static int comp_req_order(struct param *const *a, struct param *const *b,
|
|
|
|
void *unused)
|
Typesafe callback system for parsing json
This is part of #1464 and incorporates Rusty's suggested updates from #1569.
See comment in param.h for description, here's the basics:
unsigned cltv;
const jsmntok_t *note;
u64 msatoshi;
struct param * mp;
if (!param_parse(cmd, buffer, tokens,
param_req("cltv", json_tok_number, &cltv),
param_opt("note", json_tok_tok, &note),
mp = param_opt("msatoshi", json_tok_u64, &msatoshi),
NULL))
return;
if (param_is_set(mp))
do_something()
There is a lot of developer mode code to make sure we don't make mistakes,
like trying to unmarshal into the same variable twice or adding a required param
after optional.
During testing, I found a bug (of sorts) in the current system. It allows you
to provide two named parameters with the same name without error; e.g.:
# cli/lightning-cli -k newaddr addresstype=p2sh-segwit addresstype=bech32
{
"address": "2N3r6fT65PhfhE1mcMS6TtcdaEurud6M7pA"
}
It just takes the first and ignores the second. The new system reports this as an
error for now. We can always change this later.
7 years ago
|
|
|
{
|
|
|
|
if ((*a)->argsize != 0 && (*b)->argsize == 0)
|
Typesafe callback system for parsing json
This is part of #1464 and incorporates Rusty's suggested updates from #1569.
See comment in param.h for description, here's the basics:
unsigned cltv;
const jsmntok_t *note;
u64 msatoshi;
struct param * mp;
if (!param_parse(cmd, buffer, tokens,
param_req("cltv", json_tok_number, &cltv),
param_opt("note", json_tok_tok, &note),
mp = param_opt("msatoshi", json_tok_u64, &msatoshi),
NULL))
return;
if (param_is_set(mp))
do_something()
There is a lot of developer mode code to make sure we don't make mistakes,
like trying to unmarshal into the same variable twice or adding a required param
after optional.
During testing, I found a bug (of sorts) in the current system. It allows you
to provide two named parameters with the same name without error; e.g.:
# cli/lightning-cli -k newaddr addresstype=p2sh-segwit addresstype=bech32
{
"address": "2N3r6fT65PhfhE1mcMS6TtcdaEurud6M7pA"
}
It just takes the first and ignores the second. The new system reports this as an
error for now. We can always change this later.
7 years ago
|
|
|
return 0;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Make sure 2 sequential items in @params are not equal (based on
|
|
|
|
* provided comparator).
|
|
|
|
*/
|
|
|
|
static void check_distinct(struct param **params,
|
|
|
|
int (*compar) (struct param *const *a,
|
|
|
|
struct param *const *b, void *unused))
|
Typesafe callback system for parsing json
This is part of #1464 and incorporates Rusty's suggested updates from #1569.
See comment in param.h for description, here's the basics:
unsigned cltv;
const jsmntok_t *note;
u64 msatoshi;
struct param * mp;
if (!param_parse(cmd, buffer, tokens,
param_req("cltv", json_tok_number, &cltv),
param_opt("note", json_tok_tok, &note),
mp = param_opt("msatoshi", json_tok_u64, &msatoshi),
NULL))
return;
if (param_is_set(mp))
do_something()
There is a lot of developer mode code to make sure we don't make mistakes,
like trying to unmarshal into the same variable twice or adding a required param
after optional.
During testing, I found a bug (of sorts) in the current system. It allows you
to provide two named parameters with the same name without error; e.g.:
# cli/lightning-cli -k newaddr addresstype=p2sh-segwit addresstype=bech32
{
"address": "2N3r6fT65PhfhE1mcMS6TtcdaEurud6M7pA"
}
It just takes the first and ignores the second. The new system reports this as an
error for now. We can always change this later.
7 years ago
|
|
|
{
|
|
|
|
struct param **first = params;
|
|
|
|
struct param **last = first + tal_count(params);
|
|
|
|
first++;
|
|
|
|
while (first != last) {
|
|
|
|
assert(compar(first - 1, first, NULL) != 0);
|
Typesafe callback system for parsing json
This is part of #1464 and incorporates Rusty's suggested updates from #1569.
See comment in param.h for description, here's the basics:
unsigned cltv;
const jsmntok_t *note;
u64 msatoshi;
struct param * mp;
if (!param_parse(cmd, buffer, tokens,
param_req("cltv", json_tok_number, &cltv),
param_opt("note", json_tok_tok, &note),
mp = param_opt("msatoshi", json_tok_u64, &msatoshi),
NULL))
return;
if (param_is_set(mp))
do_something()
There is a lot of developer mode code to make sure we don't make mistakes,
like trying to unmarshal into the same variable twice or adding a required param
after optional.
During testing, I found a bug (of sorts) in the current system. It allows you
to provide two named parameters with the same name without error; e.g.:
# cli/lightning-cli -k newaddr addresstype=p2sh-segwit addresstype=bech32
{
"address": "2N3r6fT65PhfhE1mcMS6TtcdaEurud6M7pA"
}
It just takes the first and ignores the second. The new system reports this as an
error for now. We can always change this later.
7 years ago
|
|
|
first++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void check_unique(struct param **copy,
|
|
|
|
int (*compar) (struct param *const *a,
|
|
|
|
struct param *const *b, void *unused))
|
Typesafe callback system for parsing json
This is part of #1464 and incorporates Rusty's suggested updates from #1569.
See comment in param.h for description, here's the basics:
unsigned cltv;
const jsmntok_t *note;
u64 msatoshi;
struct param * mp;
if (!param_parse(cmd, buffer, tokens,
param_req("cltv", json_tok_number, &cltv),
param_opt("note", json_tok_tok, &note),
mp = param_opt("msatoshi", json_tok_u64, &msatoshi),
NULL))
return;
if (param_is_set(mp))
do_something()
There is a lot of developer mode code to make sure we don't make mistakes,
like trying to unmarshal into the same variable twice or adding a required param
after optional.
During testing, I found a bug (of sorts) in the current system. It allows you
to provide two named parameters with the same name without error; e.g.:
# cli/lightning-cli -k newaddr addresstype=p2sh-segwit addresstype=bech32
{
"address": "2N3r6fT65PhfhE1mcMS6TtcdaEurud6M7pA"
}
It just takes the first and ignores the second. The new system reports this as an
error for now. We can always change this later.
7 years ago
|
|
|
{
|
|
|
|
asort(copy, tal_count(copy), compar, NULL);
|
Typesafe callback system for parsing json
This is part of #1464 and incorporates Rusty's suggested updates from #1569.
See comment in param.h for description, here's the basics:
unsigned cltv;
const jsmntok_t *note;
u64 msatoshi;
struct param * mp;
if (!param_parse(cmd, buffer, tokens,
param_req("cltv", json_tok_number, &cltv),
param_opt("note", json_tok_tok, &note),
mp = param_opt("msatoshi", json_tok_u64, &msatoshi),
NULL))
return;
if (param_is_set(mp))
do_something()
There is a lot of developer mode code to make sure we don't make mistakes,
like trying to unmarshal into the same variable twice or adding a required param
after optional.
During testing, I found a bug (of sorts) in the current system. It allows you
to provide two named parameters with the same name without error; e.g.:
# cli/lightning-cli -k newaddr addresstype=p2sh-segwit addresstype=bech32
{
"address": "2N3r6fT65PhfhE1mcMS6TtcdaEurud6M7pA"
}
It just takes the first and ignores the second. The new system reports this as an
error for now. We can always change this later.
7 years ago
|
|
|
check_distinct(copy, compar);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Verify consistent internal state.
|
|
|
|
*/
|
|
|
|
static void check_params(struct param **params)
|
|
|
|
{
|
|
|
|
if (tal_count(params) < 2)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* make sure there are no required params following optional */
|
|
|
|
check_distinct(params, comp_req_order);
|
|
|
|
|
|
|
|
/* duplicate so we can sort */
|
|
|
|
struct param **copy = tal_dup_arr(params, struct param *,
|
|
|
|
params, tal_count(params), 0);
|
|
|
|
|
|
|
|
/* check for repeated names and args */
|
|
|
|
check_unique(copy, comp_by_name);
|
|
|
|
check_unique(copy, comp_by_arg);
|
|
|
|
|
|
|
|
tal_free(copy);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static struct param **param_parse_arr(struct command *cmd,
|
|
|
|
const char *buffer,
|
|
|
|
const jsmntok_t tokens[],
|
|
|
|
struct param **params)
|
|
|
|
{
|
|
|
|
#if DEVELOPER
|
|
|
|
check_params(params);
|
|
|
|
#endif
|
|
|
|
if (tokens->type == JSMN_ARRAY)
|
|
|
|
return parse_by_position(cmd, params, buffer, tokens);
|
|
|
|
else if (tokens->type == JSMN_OBJECT)
|
|
|
|
return parse_by_name(cmd, params, buffer, tokens);
|
|
|
|
|
|
|
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
|
|
|
"Expected array or object for params");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct param **param_parse(struct command *cmd, const char *buffer,
|
|
|
|
const jsmntok_t tokens[], ...)
|
|
|
|
{
|
|
|
|
struct param *def;
|
|
|
|
struct param **params = tal_arr(cmd, struct param *, 0);
|
|
|
|
va_list ap;
|
|
|
|
va_start(ap, tokens);
|
|
|
|
while ((def = va_arg(ap, struct param *)) != NULL) {
|
|
|
|
tal_steal(params, def);
|
|
|
|
tal_resize(¶ms, tal_count(params) + 1);
|
|
|
|
params[tal_count(params) - 1] = def;
|
|
|
|
}
|
|
|
|
va_end(ap);
|
|
|
|
|
|
|
|
return param_parse_arr(cmd, buffer, tokens, params);
|
|
|
|
}
|