From 3415abe56dc02a639a7474d4e08a8cc5959c8c65 Mon Sep 17 00:00:00 2001 From: William Lallemand Date: Tue, 14 Apr 2026 10:25:30 +0200 Subject: [PATCH] MINOR: mjson: reintroduce mjson_next() The lack of mjson_next() prevents to iterate easily and need to hack by iterating on a loop of snprintf + $.field[XXX] combined with mjson_find(). This reintroduce mjson_next() so we could iterate without having to build the string. The patch does not reintroduce MJSON_ENABLE_NEXT so it could be used without having to define it. --- include/import/mjson.h | 3 ++ src/mjson.c | 70 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/include/import/mjson.h b/include/import/mjson.h index 043ca2b69..4bfdc81d5 100644 --- a/include/import/mjson.h +++ b/include/import/mjson.h @@ -54,4 +54,7 @@ int mjson_get_bool(const char *s, int len, const char *path, int *v); int mjson_get_string(const char *s, int len, const char *path, char *to, int n); int mjson_get_hex(const char *s, int len, const char *path, char *to, int n); +int mjson_next(const char *s, int n, int off, int *koff, int *klen, int *voff, + int *vlen, int *vtype); + #endif // MJSON_H diff --git a/src/mjson.c b/src/mjson.c index 19c204e73..0012f0c50 100644 --- a/src/mjson.c +++ b/src/mjson.c @@ -338,6 +338,76 @@ int mjson_get_hex(const char *s, int len, const char *x, char *to, int n) { return j; } +struct nextdata { + int off, len, depth, t, vo, arrayindex; + int *koff, *klen, *voff, *vlen, *vtype; +}; + +static int next_cb(int tok, const char *s, int off, int len, void *ud) { + struct nextdata *d = (struct nextdata *) ud; + // int i; + switch (tok) { + case '{': + case '[': + if (d->depth == 0 && tok == '[') d->arrayindex = 0; + if (d->depth == 1 && off > d->off) { + d->vo = off; + d->t = tok == '{' ? MJSON_TOK_OBJECT : MJSON_TOK_ARRAY; + if (d->voff) *d->voff = off; + if (d->vtype) *d->vtype = d->t; + } + d->depth++; + break; + case '}': + case ']': + d->depth--; + if (d->depth == 1 && d->vo) { + d->len = off + len; + if (d->vlen) *d->vlen = d->len - d->vo; + if (d->arrayindex >= 0) { + if (d->koff) *d->koff = d->arrayindex; // koff holds array index + if (d->klen) *d->klen = 0; // klen holds 0 + } + return 1; + } + if (d->depth == 1 && d->arrayindex >= 0) d->arrayindex++; + break; + case ',': + case ':': + break; + case MJSON_TOK_KEY: + if (d->depth == 1 && d->off < off) { + if (d->koff) *d->koff = off; // And report back to the user + if (d->klen) *d->klen = len; // If we have to + } + break; + default: + if (d->depth != 1) break; + // If we're iterating over the array + if (off > d->off) { + d->len = off + len; + if (d->vlen) *d->vlen = len; // value length + if (d->voff) *d->voff = off; // value offset + if (d->vtype) *d->vtype = tok; // value type + if (d->arrayindex >= 0) { + if (d->koff) *d->koff = d->arrayindex; // koff holds array index + if (d->klen) *d->klen = 0; // klen holds 0 + } + return 1; + } + if (d->arrayindex >= 0) d->arrayindex++; + break; + } + (void) s; + return 0; +} + +int mjson_next(const char *s, int n, int off, int *koff, int *klen, int *voff, + int *vlen, int *vtype) { + struct nextdata d = {off, 0, 0, 0, 0, -1, koff, klen, voff, vlen, vtype}; + mjson(s, n, next_cb, &d); + return d.len; +} static int is_digit(int c) { return c >= '0' && c <= '9'; }