From 49b17bca22f07bc58b556509c2df76b8f1fa1c6c Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 31 Dec 2020 10:04:18 +0100 Subject: [PATCH] json: relax the parser some more Allow bare strings with all non-special other chars. Add # to comment a line till \n Allow = as separator for keys Fix end of string handling. Now: { "#": "this is a comment" "key": "value", "foo": 24 } and { # this is a comment key = value foo = 24 } Parse to the same thing with less clutter. --- spa/include/spa/utils/json.h | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/spa/include/spa/utils/json.h b/spa/include/spa/utils/json.h index 304da63a8..457ce88b3 100644 --- a/spa/include/spa/utils/json.h +++ b/spa/include/spa/utils/json.h @@ -64,7 +64,7 @@ static inline void spa_json_enter(struct spa_json * iter, struct spa_json * sub) static inline int spa_json_next(struct spa_json * iter, const char **value) { int utf8_remain = 0; - enum { __NONE, __STRUCT, __BARE, __STRING, __UTF8, __ESC }; + enum { __NONE, __STRUCT, __BARE, __STRING, __UTF8, __ESC, __COMMENT }; for (; iter->cur < iter->end; iter->cur++) { unsigned char cur = (unsigned char)*iter->cur; @@ -76,7 +76,10 @@ static inline int spa_json_next(struct spa_json * iter, const char **value) goto again; case __STRUCT: switch (cur) { - case '\t': case ' ': case '\r': case '\n': case ':': case ',': + case '\t': case ' ': case '\r': case '\n': case ':': case '=': case ',': + continue; + case '#': + iter->state = __COMMENT; continue; case '"': *value = iter->cur; @@ -96,25 +99,21 @@ static inline int spa_json_next(struct spa_json * iter, const char **value) } --iter->depth; continue; - case '-': case '+': case 'a' ... 'z': case 'A' ... 'Z': case '0' ... '9': + default: *value = iter->cur; iter->state = __BARE; - continue; } - return -1; + continue; case __BARE: switch (cur) { case '\t': case ' ': case '\r': case '\n': - case ':': case ',': case ']': case '}': + case ':': case ',': case '=': case ']': case '}': iter->state = __STRUCT; if (iter->depth > 0) goto again; return iter->cur - *value; - default: - if (cur >= 32 && cur <= 126) - continue; } - return -1; + continue; case __STRING: switch (cur) { case '\\': @@ -157,9 +156,19 @@ static inline int spa_json_next(struct spa_json * iter, const char **value) continue; } return -1; + case __COMMENT: + switch (cur) { + case '\n': case '\r': + iter->state = __STRUCT; + } } + } - return (iter->depth == 0 ? (iter->state == __BARE ? iter->cur - *value : 0) : -1); + return (iter->depth == 0 ? + (iter->state == __BARE && iter->cur < iter->end ? + iter->cur - *value : + 0) : + -1); } static inline int spa_json_enter_container(struct spa_json *iter, struct spa_json *sub, char type)