2018-12-08 01:39:28 +01:00
|
|
|
#ifndef LIGHTNING_COMMON_PARAM_H
|
|
|
|
#define LIGHTNING_COMMON_PARAM_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, ¬e),
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.
2018-06-16 17:29:32 +02:00
|
|
|
#include "config.h"
|
2018-12-08 01:39:28 +01:00
|
|
|
#include <common/json.h>
|
|
|
|
#include <common/json_tok.h>
|
|
|
|
#include <stdbool.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, ¬e),
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.
2018-06-16 17:29:32 +02:00
|
|
|
|
2018-08-30 21:11:27 +02:00
|
|
|
/*~ Greetings adventurer!
|
|
|
|
*
|
2018-12-10 20:19:12 +01:00
|
|
|
* Do you want to automatically validate json input and unmarshal it into
|
2018-08-30 21:11:27 +02:00
|
|
|
* local variables, all using typesafe callbacks? And on error,
|
|
|
|
* call command_fail with a proper error message? Then you've come to the
|
|
|
|
* right place!
|
|
|
|
*
|
|
|
|
* Here is a simple example of using the system:
|
|
|
|
*
|
|
|
|
* unsigned *cltv;
|
|
|
|
* u64 *msatoshi;
|
|
|
|
* const jsmntok_t *note;
|
|
|
|
* u64 *expiry;
|
|
|
|
*
|
|
|
|
* if (!param(cmd, buffer, params,
|
|
|
|
* p_req("cltv", json_tok_number, &cltv),
|
|
|
|
* p_opt("msatoshi", json_tok_u64, &msatoshi),
|
|
|
|
* p_opt("note", json_tok_tok, ¬e),
|
|
|
|
* p_opt_def("expiry", json_tok_u64, &expiry, 3600),
|
|
|
|
* NULL))
|
|
|
|
* return;
|
|
|
|
*
|
|
|
|
* If param() returns true then you're good to go.
|
|
|
|
*
|
|
|
|
* All the command handlers throughout the code use this system.
|
|
|
|
* json_invoice() is a great example. The common callbacks can be found in
|
2018-12-08 01:39:28 +01:00
|
|
|
* common/json_tok.c. Use them directly or feel free to write your own.
|
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, ¬e),
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.
2018-06-16 17:29:32 +02:00
|
|
|
*/
|
2018-12-08 01:39:28 +01:00
|
|
|
struct command;
|
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, ¬e),
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.
2018-06-16 17:29:32 +02:00
|
|
|
|
2018-12-16 05:50:06 +01:00
|
|
|
/* A dummy type returned by command_ functions, to ensure you return them
|
|
|
|
* immediately */
|
|
|
|
struct command_result;
|
|
|
|
|
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, ¬e),
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.
2018-06-16 17:29:32 +02:00
|
|
|
/*
|
2018-08-15 17:16:02 +02:00
|
|
|
* Parse the json tokens. @params can be an array of values or an object
|
2018-07-12 20:04:45 +02:00
|
|
|
* of named values.
|
|
|
|
*/
|
|
|
|
bool param(struct command *cmd, const char *buffer,
|
2018-12-10 20:20:25 +01:00
|
|
|
const jsmntok_t params[], ...) LAST_ARG_NULL;
|
2018-07-12 20:04:45 +02:00
|
|
|
|
|
|
|
/*
|
2018-12-16 05:50:06 +01:00
|
|
|
* The callback signature.
|
|
|
|
*
|
|
|
|
* Callbacks must return NULL on success. On failure they
|
|
|
|
* must return command_fail(...).
|
2018-08-10 04:15:30 +02:00
|
|
|
*/
|
2018-12-16 05:50:06 +01:00
|
|
|
typedef struct command_result *(*param_cbx)(struct command *cmd,
|
|
|
|
const char *name,
|
|
|
|
const char *buffer,
|
|
|
|
const jsmntok_t *tok,
|
|
|
|
void **arg);
|
2018-08-10 04:15:30 +02:00
|
|
|
|
2019-07-16 03:41:51 +02:00
|
|
|
/**
|
|
|
|
* Parse the first json value.
|
|
|
|
*
|
|
|
|
* name...: NULL-terminated array of valid values.
|
|
|
|
*
|
|
|
|
* Returns subcommand: if it returns NULL if you should return
|
|
|
|
* command_param_failed() immediately.
|
|
|
|
*/
|
|
|
|
const char *param_subcommand(struct command *cmd, const char *buffer,
|
|
|
|
const jsmntok_t tokens[],
|
|
|
|
const char *name, ...) LAST_ARG_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, ¬e),
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.
2018-06-16 17:29:32 +02:00
|
|
|
/*
|
2018-08-15 17:16:02 +02:00
|
|
|
* Add a required parameter.
|
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, ¬e),
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.
2018-06-16 17:29:32 +02:00
|
|
|
*/
|
2020-02-04 01:03:22 +01:00
|
|
|
#define p_req(name, cbx, arg) \
|
2018-08-15 17:16:02 +02:00
|
|
|
name"", \
|
|
|
|
true, \
|
2019-07-16 03:41:51 +02:00
|
|
|
(param_cbx)(cbx), \
|
2018-08-15 17:16:02 +02:00
|
|
|
(arg) + 0*sizeof((cbx)((struct command *)NULL, \
|
|
|
|
(const char *)NULL, \
|
|
|
|
(const char *)NULL, \
|
|
|
|
(const jsmntok_t *)NULL, \
|
2018-12-16 05:50:06 +01:00
|
|
|
(arg)) == (struct command_result *)NULL)
|
2018-08-10 04:15:30 +02:00
|
|
|
|
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, ¬e),
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.
2018-06-16 17:29:32 +02:00
|
|
|
/*
|
2018-08-15 17:16:02 +02:00
|
|
|
* Add an optional parameter. *arg is set to NULL if it isn't found.
|
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, ¬e),
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.
2018-06-16 17:29:32 +02:00
|
|
|
*/
|
2018-08-15 17:16:02 +02:00
|
|
|
#define p_opt(name, cbx, arg) \
|
|
|
|
name"", \
|
|
|
|
false, \
|
2019-07-16 03:41:51 +02:00
|
|
|
(param_cbx)(cbx), \
|
2018-08-15 17:16:02 +02:00
|
|
|
({ *arg = NULL; \
|
|
|
|
(arg) + 0*sizeof((cbx)((struct command *)NULL, \
|
|
|
|
(const char *)NULL, \
|
|
|
|
(const char *)NULL, \
|
|
|
|
(const jsmntok_t *)NULL, \
|
2018-12-16 05:50:06 +01:00
|
|
|
(arg)) == (struct command_result *)NULL); })
|
2018-08-10 04:15:30 +02:00
|
|
|
|
2018-07-11 04:29:53 +02:00
|
|
|
/*
|
2018-08-15 17:16:02 +02:00
|
|
|
* Add an optional parameter. *arg is set to @def if it isn't found.
|
2018-07-11 04:29:53 +02:00
|
|
|
*/
|
2018-08-15 17:16:02 +02:00
|
|
|
#define p_opt_def(name, cbx, arg, def) \
|
|
|
|
name"", \
|
|
|
|
false, \
|
2019-07-16 03:41:51 +02:00
|
|
|
(param_cbx)(cbx), \
|
2018-08-15 17:16:02 +02:00
|
|
|
({ (*arg) = tal((cmd), typeof(**arg)); \
|
|
|
|
(**arg) = (def); \
|
|
|
|
(arg) + 0*sizeof((cbx)((struct command *)NULL, \
|
|
|
|
(const char *)NULL, \
|
|
|
|
(const char *)NULL, \
|
|
|
|
(const jsmntok_t *)NULL, \
|
2018-12-16 05:50:06 +01:00
|
|
|
(arg)) == (struct command_result *)NULL); })
|
2018-08-10 04:15:30 +02:00
|
|
|
|
2018-12-08 01:39:25 +01:00
|
|
|
/* Special flag for 'check' which allows any parameters. */
|
|
|
|
#define p_opt_any() "", false, NULL, NULL
|
2018-12-08 01:39:28 +01:00
|
|
|
#endif /* LIGHTNING_COMMON_PARAM_H */
|