mirror of
https://github.com/johnkerl/miller.git
synced 2026-07-28 18:21:52 +00:00
JSON-parser neaten
This commit is contained in:
parent
68044e4ae0
commit
8fade1bbea
1 changed files with 76 additions and 78 deletions
|
|
@ -193,23 +193,23 @@ static int new_value(
|
|||
state.cur_line, state.cur_col
|
||||
|
||||
static const long
|
||||
flag_next = 1 << 0,
|
||||
flag_reproc = 1 << 1,
|
||||
flag_need_comma = 1 << 2,
|
||||
flag_seek_value = 1 << 3,
|
||||
flag_escaped = 1 << 4,
|
||||
FLAG_NEXT = 1 << 0,
|
||||
FLAG_REPROC = 1 << 1,
|
||||
FLAG_NEED_COMMA = 1 << 2,
|
||||
FLAG_SEEK_VALUE = 1 << 3,
|
||||
FLAG_ESCAPED = 1 << 4,
|
||||
// xxx rename to flag_in_string
|
||||
// xxx upcase all these ...
|
||||
flag_string = 1 << 5,
|
||||
flag_need_colon = 1 << 6,
|
||||
flag_done = 1 << 7,
|
||||
flag_num_negative = 1 << 8,
|
||||
flag_num_zero = 1 << 9,
|
||||
flag_num_e = 1 << 10,
|
||||
flag_num_e_got_sign = 1 << 11,
|
||||
flag_num_e_negative = 1 << 12,
|
||||
flag_line_comment = 1 << 13,
|
||||
flag_block_comment = 1 << 14;
|
||||
FLAG_STRING = 1 << 5,
|
||||
FLAG_NEED_COLON = 1 << 6,
|
||||
FLAG_DONE = 1 << 7,
|
||||
FLAG_NUM_NEGATIVE = 1 << 8,
|
||||
FLAG_NUM_ZERO = 1 << 9,
|
||||
FLAG_NUM_E = 1 << 10,
|
||||
FLAG_NUM_E_got_sign = 1 << 11,
|
||||
FLAG_NUM_E_negative = 1 << 12,
|
||||
FLAG_LINE_COMMENT = 1 << 13,
|
||||
FLAG_BLOCK_COMMENT = 1 << 14;
|
||||
|
||||
// ================================================================
|
||||
json_value_t * json_parse(const json_char * json, size_t length, char* error_buf) {
|
||||
|
|
@ -268,7 +268,7 @@ json_value_t * json_parse_ex(
|
|||
unsigned int string_length = 0;
|
||||
|
||||
top = root = 0;
|
||||
flags = flag_seek_value;
|
||||
flags = FLAG_SEEK_VALUE;
|
||||
|
||||
state.cur_line = 1;
|
||||
|
||||
|
|
@ -276,7 +276,7 @@ json_value_t * json_parse_ex(
|
|||
json_char* pb = (json_char*)((state.ptr == end) ? NULL : state.ptr);
|
||||
json_char b = (state.ptr == end) ? 0 : *state.ptr;
|
||||
|
||||
if (flags & flag_string) {
|
||||
if (flags & FLAG_STRING) {
|
||||
if (!b) {
|
||||
sprintf(error, "Unexpected EOF in string (at %d:%d)", LINE_AND_COL);
|
||||
goto e_failed;
|
||||
|
|
@ -285,8 +285,8 @@ json_value_t * json_parse_ex(
|
|||
if (string_length > state.uint_max)
|
||||
goto e_overflow;
|
||||
|
||||
if (flags & flag_escaped) {
|
||||
flags &= ~ flag_escaped;
|
||||
if (flags & FLAG_ESCAPED) {
|
||||
flags &= ~ FLAG_ESCAPED;
|
||||
|
||||
switch (b) {
|
||||
case 'b': STRING_ADD('\b'); break;
|
||||
|
|
@ -369,14 +369,14 @@ json_value_t * json_parse_ex(
|
|||
break;
|
||||
|
||||
default:
|
||||
STRING_ADD (b);
|
||||
STRING_ADD(b);
|
||||
};
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (b == '\\') {
|
||||
flags |= flag_escaped;
|
||||
flags |= FLAG_ESCAPED;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -384,13 +384,13 @@ json_value_t * json_parse_ex(
|
|||
if (!state.first_pass)
|
||||
string [string_length] = 0;
|
||||
|
||||
flags &= ~ flag_string;
|
||||
flags &= ~ FLAG_STRING;
|
||||
string = 0;
|
||||
|
||||
switch (top->type) {
|
||||
case JSON_STRING:
|
||||
top->u.string.length = string_length;
|
||||
flags |= flag_next;
|
||||
flags |= FLAG_NEXT;
|
||||
break;
|
||||
|
||||
case JSON_OBJECT:
|
||||
|
|
@ -406,7 +406,7 @@ json_value_t * json_parse_ex(
|
|||
(*(json_char **) &top->_reserved.p.pobject_mem) += string_length + 1;
|
||||
}
|
||||
|
||||
flags |= flag_seek_value | flag_need_colon;
|
||||
flags |= FLAG_SEEK_VALUE | FLAG_NEED_COLON;
|
||||
continue;
|
||||
|
||||
default:
|
||||
|
|
@ -419,31 +419,31 @@ json_value_t * json_parse_ex(
|
|||
}
|
||||
|
||||
if (state.settings.setting_flags & JSON_ENABLE_COMMENTS) {
|
||||
if (flags & (flag_line_comment | flag_block_comment)) {
|
||||
if (flags & flag_line_comment) {
|
||||
if (flags & (FLAG_LINE_COMMENT | FLAG_BLOCK_COMMENT)) {
|
||||
if (flags & FLAG_LINE_COMMENT) {
|
||||
if (b == '\r' || b == '\n' || !b) {
|
||||
flags &= ~ flag_line_comment;
|
||||
flags &= ~ FLAG_LINE_COMMENT;
|
||||
--state.ptr; /* so null can be reproc'd */
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (flags & flag_block_comment) {
|
||||
if (flags & FLAG_BLOCK_COMMENT) {
|
||||
if (!b) {
|
||||
sprintf(error, "%d:%d: Unexpected EOF in block comment", LINE_AND_COL);
|
||||
goto e_failed;
|
||||
}
|
||||
|
||||
if (b == '*' && state.ptr < (end - 1) && state.ptr [1] == '/') {
|
||||
flags &= ~ flag_block_comment;
|
||||
flags &= ~ FLAG_BLOCK_COMMENT;
|
||||
++state.ptr; /* skip closing sequence */
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
} else if (b == '/') {
|
||||
if (! (flags & (flag_seek_value | flag_done)) && top->type != JSON_OBJECT) {
|
||||
if (! (flags & (FLAG_SEEK_VALUE | FLAG_DONE)) && top->type != JSON_OBJECT) {
|
||||
sprintf(error, "%d:%d: Comment not allowed here", LINE_AND_COL);
|
||||
goto e_failed;
|
||||
}
|
||||
|
|
@ -455,11 +455,11 @@ json_value_t * json_parse_ex(
|
|||
|
||||
switch (b = *state.ptr) {
|
||||
case '/':
|
||||
flags |= flag_line_comment;
|
||||
flags |= FLAG_LINE_COMMENT;
|
||||
continue;
|
||||
|
||||
case '*':
|
||||
flags |= flag_block_comment;
|
||||
flags |= FLAG_BLOCK_COMMENT;
|
||||
continue;
|
||||
|
||||
default:
|
||||
|
|
@ -469,7 +469,7 @@ json_value_t * json_parse_ex(
|
|||
}
|
||||
}
|
||||
|
||||
if (flags & flag_done) {
|
||||
if (flags & FLAG_DONE) {
|
||||
if (!b)
|
||||
break;
|
||||
if (state.settings.setting_flags & JSON_ENABLE_SEQUENTIAL_OBJECTS) {
|
||||
|
|
@ -487,14 +487,14 @@ json_value_t * json_parse_ex(
|
|||
};
|
||||
}
|
||||
|
||||
if (flags & flag_seek_value) {
|
||||
if (flags & FLAG_SEEK_VALUE) {
|
||||
switch (b) {
|
||||
WHITESPACE:
|
||||
continue;
|
||||
|
||||
case ']':
|
||||
if (top && top->type == JSON_ARRAY) {
|
||||
flags = (flags & ~ (flag_need_comma | flag_seek_value)) | flag_next;
|
||||
flags = (flags & ~ (FLAG_NEED_COMMA | FLAG_SEEK_VALUE)) | FLAG_NEXT;
|
||||
} else {
|
||||
sprintf (error, "%d:%d: Unexpected ]", LINE_AND_COL);
|
||||
goto e_failed;
|
||||
|
|
@ -503,9 +503,9 @@ json_value_t * json_parse_ex(
|
|||
break;
|
||||
|
||||
default:
|
||||
if (flags & flag_need_comma) {
|
||||
if (flags & FLAG_NEED_COMMA) {
|
||||
if (b == ',') {
|
||||
flags &= ~ flag_need_comma;
|
||||
flags &= ~ FLAG_NEED_COMMA;
|
||||
continue;
|
||||
} else {
|
||||
sprintf(error, "%d:%d: Expected , before %c", state.cur_line, state.cur_col, b);
|
||||
|
|
@ -513,9 +513,9 @@ json_value_t * json_parse_ex(
|
|||
}
|
||||
}
|
||||
|
||||
if (flags & flag_need_colon) {
|
||||
if (flags & FLAG_NEED_COLON) {
|
||||
if (b == ':') {
|
||||
flags &= ~ flag_need_colon;
|
||||
flags &= ~ FLAG_NEED_COLON;
|
||||
continue;
|
||||
} else {
|
||||
sprintf(error, "%d:%d: Expected : before %c", state.cur_line, state.cur_col, b);
|
||||
|
|
@ -523,7 +523,7 @@ json_value_t * json_parse_ex(
|
|||
}
|
||||
}
|
||||
|
||||
flags &= ~ flag_seek_value;
|
||||
flags &= ~ FLAG_SEEK_VALUE;
|
||||
|
||||
switch (b) {
|
||||
case '{':
|
||||
|
|
@ -534,13 +534,13 @@ json_value_t * json_parse_ex(
|
|||
case '[':
|
||||
if (!new_value(&state, &top, &root, &alloc, JSON_ARRAY))
|
||||
goto e_alloc_failure;
|
||||
flags |= flag_seek_value;
|
||||
flags |= FLAG_SEEK_VALUE;
|
||||
continue;
|
||||
|
||||
case '"':
|
||||
if (!new_value(&state, &top, &root, &alloc, JSON_STRING))
|
||||
goto e_alloc_failure;
|
||||
flags |= flag_string;
|
||||
flags |= FLAG_STRING;
|
||||
string = top->u.string.ptr;
|
||||
string_length = 0;
|
||||
continue;
|
||||
|
|
@ -558,7 +558,7 @@ json_value_t * json_parse_ex(
|
|||
// xxx
|
||||
top->u.boolean.nval = 1;
|
||||
|
||||
flags |= flag_next;
|
||||
flags |= FLAG_NEXT;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
|
|
@ -573,7 +573,7 @@ json_value_t * json_parse_ex(
|
|||
if (!new_value(&state, &top, &root, &alloc, JSON_BOOLEAN))
|
||||
goto e_alloc_failure;
|
||||
|
||||
flags |= flag_next;
|
||||
flags |= FLAG_NEXT;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
|
|
@ -586,12 +586,12 @@ json_value_t * json_parse_ex(
|
|||
if (!new_value(&state, &top, &root, &alloc, JSON_NULL))
|
||||
goto e_alloc_failure;
|
||||
|
||||
flags |= flag_next;
|
||||
flags |= FLAG_NEXT;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (isdigit (b) || b == '-') {
|
||||
// xxx end
|
||||
// xxx start
|
||||
if (!new_value(&state, &top, &root, &alloc, JSON_INTEGER))
|
||||
goto e_alloc_failure;
|
||||
|
||||
|
|
@ -605,23 +605,23 @@ json_value_t * json_parse_ex(
|
|||
b = *state.ptr;
|
||||
}
|
||||
|
||||
flags |= flag_next | flag_reproc;
|
||||
flags |= FLAG_NEXT | FLAG_REPROC;
|
||||
break;
|
||||
}
|
||||
|
||||
flags &= ~ (flag_num_negative | flag_num_e |
|
||||
flag_num_e_got_sign | flag_num_e_negative | flag_num_zero);
|
||||
flags &= ~ (FLAG_NUM_NEGATIVE | FLAG_NUM_E |
|
||||
FLAG_NUM_E_got_sign | FLAG_NUM_E_negative | FLAG_NUM_ZERO);
|
||||
|
||||
num_digits = 0;
|
||||
num_fraction = 0;
|
||||
num_e = 0;
|
||||
|
||||
if (b != '-') {
|
||||
flags |= flag_reproc;
|
||||
flags |= FLAG_REPROC;
|
||||
break;
|
||||
}
|
||||
|
||||
flags |= flag_num_negative;
|
||||
flags |= FLAG_NUM_NEGATIVE;
|
||||
continue;
|
||||
} else {
|
||||
sprintf(error, "%d:%d: Unexpected `%c` when seeking value", LINE_AND_COL, b);
|
||||
|
|
@ -638,12 +638,12 @@ json_value_t * json_parse_ex(
|
|||
continue;
|
||||
|
||||
case '"':
|
||||
if (flags & flag_need_comma) {
|
||||
if (flags & FLAG_NEED_COMMA) {
|
||||
sprintf(error, "%d:%d: Expected , before \"", LINE_AND_COL);
|
||||
goto e_failed;
|
||||
}
|
||||
|
||||
flags |= flag_string;
|
||||
flags |= FLAG_STRING;
|
||||
|
||||
string = (json_char *) top->_reserved.p.pobject_mem;
|
||||
string_length = 0;
|
||||
|
|
@ -651,12 +651,12 @@ json_value_t * json_parse_ex(
|
|||
break;
|
||||
|
||||
case '}':
|
||||
flags = (flags & ~ flag_need_comma) | flag_next;
|
||||
flags = (flags & ~ FLAG_NEED_COMMA) | FLAG_NEXT;
|
||||
break;
|
||||
|
||||
case ',':
|
||||
if (flags & flag_need_comma) {
|
||||
flags &= ~ flag_need_comma;
|
||||
if (flags & FLAG_NEED_COMMA) {
|
||||
flags &= ~ FLAG_NEED_COMMA;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -672,17 +672,17 @@ json_value_t * json_parse_ex(
|
|||
if (isdigit(b)) {
|
||||
++num_digits;
|
||||
|
||||
if (top->type == JSON_INTEGER || flags & flag_num_e) {
|
||||
if (! (flags & flag_num_e)) {
|
||||
if (flags & flag_num_zero) {
|
||||
if (top->type == JSON_INTEGER || flags & FLAG_NUM_E) {
|
||||
if (! (flags & FLAG_NUM_E)) {
|
||||
if (flags & FLAG_NUM_ZERO) {
|
||||
sprintf(error, "%d:%d: Unexpected `0` before `%c`", LINE_AND_COL, b);
|
||||
goto e_failed;
|
||||
}
|
||||
|
||||
if (num_digits == 1 && b == '0')
|
||||
flags |= flag_num_zero;
|
||||
flags |= FLAG_NUM_ZERO;
|
||||
} else {
|
||||
flags |= flag_num_e_got_sign;
|
||||
flags |= FLAG_NUM_E_got_sign;
|
||||
num_e = (num_e * 10) + (b - '0');
|
||||
continue;
|
||||
}
|
||||
|
|
@ -697,11 +697,11 @@ json_value_t * json_parse_ex(
|
|||
}
|
||||
|
||||
if (b == '+' || b == '-') {
|
||||
if ( (flags & flag_num_e) && !(flags & flag_num_e_got_sign)) {
|
||||
flags |= flag_num_e_got_sign;
|
||||
if ( (flags & FLAG_NUM_E) && !(flags & FLAG_NUM_E_got_sign)) {
|
||||
flags |= FLAG_NUM_E_got_sign;
|
||||
|
||||
if (b == '-')
|
||||
flags |= flag_num_e_negative;
|
||||
flags |= FLAG_NUM_E_negative;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
|
@ -715,12 +715,11 @@ json_value_t * json_parse_ex(
|
|||
// xxx
|
||||
top->u.dbl.nval = (double) top->u.integer.nval;
|
||||
|
||||
// xxx start??
|
||||
num_digits = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! (flags & flag_num_e)) {
|
||||
if (! (flags & FLAG_NUM_E)) {
|
||||
if (top->type == JSON_DOUBLE) {
|
||||
if (!num_digits) {
|
||||
sprintf(error, "%d:%d: Expected digit after `.`", LINE_AND_COL);
|
||||
|
|
@ -731,16 +730,15 @@ json_value_t * json_parse_ex(
|
|||
}
|
||||
|
||||
if (b == 'e' || b == 'E') {
|
||||
flags |= flag_num_e;
|
||||
flags |= FLAG_NUM_E;
|
||||
|
||||
if (top->type == JSON_INTEGER) {
|
||||
top->type = JSON_DOUBLE;
|
||||
top->u.dbl.nval = (double) top->u.integer.nval;
|
||||
}
|
||||
|
||||
// xxx start??
|
||||
num_digits = 0;
|
||||
flags &= ~ flag_num_zero;
|
||||
flags &= ~ FLAG_NUM_ZERO;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
|
@ -750,10 +748,10 @@ json_value_t * json_parse_ex(
|
|||
goto e_failed;
|
||||
}
|
||||
|
||||
top->u.dbl.nval *= pow(10.0, (double) (flags & flag_num_e_negative ? - num_e : num_e));
|
||||
top->u.dbl.nval *= pow(10.0, (double) (flags & FLAG_NUM_E_negative ? - num_e : num_e));
|
||||
}
|
||||
|
||||
if (flags & flag_num_negative) {
|
||||
if (flags & FLAG_NUM_NEGATIVE) {
|
||||
// xxx
|
||||
if (top->type == JSON_INTEGER)
|
||||
top->u.integer.nval = - top->u.integer.nval;
|
||||
|
|
@ -761,7 +759,7 @@ json_value_t * json_parse_ex(
|
|||
top->u.dbl.nval = - top->u.dbl.nval;
|
||||
}
|
||||
|
||||
flags |= flag_next | flag_reproc;
|
||||
flags |= FLAG_NEXT | FLAG_REPROC;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -769,23 +767,23 @@ json_value_t * json_parse_ex(
|
|||
};
|
||||
}
|
||||
|
||||
if (flags & flag_reproc) {
|
||||
flags &= ~ flag_reproc;
|
||||
if (flags & FLAG_REPROC) {
|
||||
flags &= ~ FLAG_REPROC;
|
||||
--state.ptr;
|
||||
}
|
||||
|
||||
if (flags & flag_next) {
|
||||
flags = (flags & ~ flag_next) | flag_need_comma;
|
||||
if (flags & FLAG_NEXT) {
|
||||
flags = (flags & ~ FLAG_NEXT) | FLAG_NEED_COMMA;
|
||||
|
||||
if (!top->parent) {
|
||||
/* root value done */
|
||||
|
||||
flags |= flag_done;
|
||||
flags |= FLAG_DONE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (top->parent->type == JSON_ARRAY)
|
||||
flags |= flag_seek_value;
|
||||
flags |= FLAG_SEEK_VALUE;
|
||||
|
||||
if (!state.first_pass) {
|
||||
json_value_t * parent = top->parent;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue