mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-09 07:10:16 +01:00
4d1d0438e1
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.
94 lines
3.0 KiB
C
94 lines
3.0 KiB
C
#ifndef LIGHTNING_LIGHTNINGD_PARAMS_H
|
|
#define LIGHTNING_LIGHTNINGD_PARAMS_H
|
|
#include "config.h"
|
|
#include <ccan/ccan/typesafe_cb/typesafe_cb.h>
|
|
|
|
struct param;
|
|
|
|
/*
|
|
Typesafe callback system for unmarshalling and validating json parameters.
|
|
|
|
Typical usage:
|
|
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;
|
|
|
|
At this point in the code you can be assured the json tokens were successfully
|
|
parsed. If not, param_parse() returned NULL, having already called
|
|
command_fail() with a descriptive error message. The data section of the json
|
|
result contains the offending parameter and its value.
|
|
|
|
cltv is a required parameter, and is set correctly.
|
|
|
|
note and msatoshi are optional parameters. You can see if they have been set
|
|
by calling param_is_set(); e.g.:
|
|
|
|
if (param_is_set(mp))
|
|
do_something()
|
|
|
|
The note parameter uses a special callback, json_tok_tok(). It
|
|
simply sets seedtok to the appropriate value and lets the handler do the
|
|
validating. It has the added feature of setting seedtok to NULL if it is null
|
|
or not specified.
|
|
|
|
There are canned failure messages for common callbacks. An example:
|
|
|
|
'msatoshi' should be an unsigned 64 bit integer, not '123z'
|
|
|
|
Otherwise a generic message is provided.
|
|
*/
|
|
struct param **param_parse(struct command *cmd, const char *buffer,
|
|
const jsmntok_t params[], ...);
|
|
|
|
/*
|
|
* This callback provided must follow this signature; e.g.,
|
|
* bool json_tok_double(const char *buffer, const jsmntok_t *tok, double *arg)
|
|
*/
|
|
typedef bool(*param_cb)(const char *buffer, const jsmntok_t *tok, void *arg);
|
|
|
|
/*
|
|
* Add a handler to unmarshal a required json token into @arg. The handler must
|
|
* return true on success and false on failure. Upon failure, command_fail will be
|
|
* called with a descriptive error message.
|
|
*
|
|
* This operation is typesafe; i.e., a compilation error will occur if the types
|
|
* of @arg and the last parameter of @cb do not match.
|
|
*
|
|
* Returns an opaque pointer that can be later used in param_is_set().
|
|
*/
|
|
#define param_req(name, cb, arg) \
|
|
param_add_(true, name, \
|
|
typesafe_cb_preargs(bool, void *, \
|
|
(cb), (arg), \
|
|
const char *, \
|
|
const jsmntok_t *), \
|
|
(arg))
|
|
/*
|
|
* Same as above but for optional parameters.
|
|
*/
|
|
#define param_opt(name, cb, arg) \
|
|
param_add_(false, name, \
|
|
typesafe_cb_preargs(bool, void *, \
|
|
(cb), (arg), \
|
|
const char *, \
|
|
const jsmntok_t *), \
|
|
(arg))
|
|
struct param * param_add_(bool required, char *name, param_cb cb, void *arg);
|
|
|
|
/*
|
|
* Check to see if an optional parameter was set during parsing (although it
|
|
* works for all parameters).
|
|
* Returns the @arg if set, otherwise NULL.
|
|
*/
|
|
void * param_is_set(struct param *p);
|
|
|
|
#endif /* LIGHTNING_LIGHTNINGD_PARAMS_H */
|