talfmt take a ctx pointer and return NULL or a valid pointer. * fmt takes the argument, and returns a bool. * * This function returns NULL on success, or errmsg on failure. */
| 156 | * This function returns NULL on success, or errmsg on failure. |
| 157 | */ |
| 158 | static const char *handle_percent(const char *buffer, |
| 159 | const jsmntok_t *tok, |
| 160 | va_list *ap) |
| 161 | { |
| 162 | void *ctx; |
| 163 | const char *fmtname; |
| 164 | |
| 165 | /* This is set to (dummy) json_scan if it's a non-tal fmt */ |
| 166 | ctx = va_arg(*ap, void *); |
| 167 | fmtname = va_arg(*ap, const char *); |
| 168 | if (ctx != json_scan) { |
| 169 | void *(*talfmt)(void *, const char *, const jsmntok_t *); |
| 170 | void **p; |
| 171 | p = va_arg(*ap, void **); |
| 172 | talfmt = va_arg(*ap, void *(*)(void *, const char *, const jsmntok_t *)); |
| 173 | /* If we're skipping this, don't call fmt! */ |
| 174 | if (!tok) |
| 175 | return NULL; |
| 176 | *p = talfmt(ctx, buffer, tok); |
| 177 | if (*p != NULL) |
| 178 | return NULL; |
| 179 | } else { |
| 180 | bool (*fmt)(const char *, const jsmntok_t *, void *); |
| 181 | void *p; |
| 182 | |
| 183 | p = va_arg(*ap, void *); |
| 184 | fmt = va_arg(*ap, bool (*)(const char *, const jsmntok_t *, void *)); |
| 185 | /* If we're skipping this, don't call fmt! */ |
| 186 | if (!tok) |
| 187 | return NULL; |
| 188 | if (fmt(buffer, tok, p)) |
| 189 | return NULL; |
| 190 | } |
| 191 | |
| 192 | return tal_fmt(tmpctx, "%s could not parse %.*s", |
| 193 | fmtname, |
| 194 | json_tok_full_len(tok), |
| 195 | json_tok_full(buffer, tok)); |
| 196 | } |
| 197 | |
| 198 | /* GUIDE := OBJ | ARRAY | '%' |
| 199 | * OBJ := '{' FIELDLIST '}' |
no test coverage detected