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.
This commit is contained in:
Wim Taymans 2020-12-31 10:04:18 +01:00
parent c39ba8570e
commit 49b17bca22

View file

@ -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) static inline int spa_json_next(struct spa_json * iter, const char **value)
{ {
int utf8_remain = 0; 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++) { for (; iter->cur < iter->end; iter->cur++) {
unsigned char cur = (unsigned char)*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; goto again;
case __STRUCT: case __STRUCT:
switch (cur) { 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; continue;
case '"': case '"':
*value = iter->cur; *value = iter->cur;
@ -96,25 +99,21 @@ static inline int spa_json_next(struct spa_json * iter, const char **value)
} }
--iter->depth; --iter->depth;
continue; continue;
case '-': case '+': case 'a' ... 'z': case 'A' ... 'Z': case '0' ... '9': default:
*value = iter->cur; *value = iter->cur;
iter->state = __BARE; iter->state = __BARE;
continue;
} }
return -1; continue;
case __BARE: case __BARE:
switch (cur) { switch (cur) {
case '\t': case ' ': case '\r': case '\n': case '\t': case ' ': case '\r': case '\n':
case ':': case ',': case ']': case '}': case ':': case ',': case '=': case ']': case '}':
iter->state = __STRUCT; iter->state = __STRUCT;
if (iter->depth > 0) if (iter->depth > 0)
goto again; goto again;
return iter->cur - *value; return iter->cur - *value;
default:
if (cur >= 32 && cur <= 126)
continue;
} }
return -1; continue;
case __STRING: case __STRING:
switch (cur) { switch (cur) {
case '\\': case '\\':
@ -157,9 +156,19 @@ static inline int spa_json_next(struct spa_json * iter, const char **value)
continue; continue;
} }
return -1; 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) static inline int spa_json_enter_container(struct spa_json *iter, struct spa_json *sub, char type)