Skip to content

Commit

Permalink
get rid of a bunch of dynamic tests and replace them with control flow
Browse files Browse the repository at this point in the history
  • Loading branch information
chadaustin committed Apr 22, 2017
1 parent 193b183 commit 3828769
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 32 deletions.
51 changes: 25 additions & 26 deletions include/sajson.h
Expand Up @@ -617,47 +617,43 @@ namespace sajson {
if (p == 0) {
return error(p, "no root element");
}
char c = *p;

type current_structure_type;
if (c == '[') {
if (*p == '[') {
current_structure_type = TYPE_ARRAY;
} else if (c == '{') {
} else if (*p == '{') {
current_structure_type = TYPE_OBJECT;
} else {
return error(p, "document root must be object or array");
}
++p;

size_t* current_base = temp;
*temp++ = make_element(current_structure_type, ROOT_MARKER);

type value_type_result;

bool had_comma = false;
goto after_comma;

for (;;) {
const char closing_bracket = (current_structure_type == TYPE_OBJECT ? '}' : ']');
const bool is_first_element = temp == current_base + 1;
bool had_comma = false;

p = skip_whitespace(p);
char c = p ? *p : 0;
if (is_first_element) {
if (c == ',') {
return error(p, "unexpected comma");
}
} else {
if (c == ',') {
p = skip_whitespace(p + 1);
c = p ? *p : 0;
had_comma = true;
} else if (c != closing_bracket) {
return error(p, "expected ,");
}
if (SAJSON_UNLIKELY(!p)) {
return error(p, "unexpected end of input");
}

if (*p == (current_structure_type == TYPE_OBJECT ? '}' : ']')) {
goto next_element;
}
if (SAJSON_UNLIKELY(*p != ',')) {
return error(p, "expected ,");
}
had_comma = true;

if (current_structure_type == TYPE_OBJECT && c != '}') {
if (c != '"') {
return error(p, "object key must be quoted");
after_comma:
p = skip_whitespace(p + 1);
if (current_structure_type == TYPE_OBJECT && *p != '}') {
if (*p != '"') {
return error(p, "invalid object key");
}
p = parse_string(p, temp);
if (!p) {
Expand All @@ -672,6 +668,8 @@ namespace sajson {
}

p = skip_whitespace(p);

next_element:
switch (p ? *p : 0) {
type next_type;
size_t element;
Expand Down Expand Up @@ -734,12 +732,12 @@ namespace sajson {
next_type = TYPE_OBJECT;
goto push;
push: {
++p;
size_t* previous_base = current_base;
current_base = temp;
*temp++ = make_element(current_structure_type, previous_base - structure);
current_structure_type = next_type;
continue;
had_comma = false;
goto after_comma;
}

case ']':
Expand Down Expand Up @@ -783,6 +781,7 @@ namespace sajson {
}

*temp++ = make_element(value_type_result, out - current_base - 1);
had_comma = false;
}

done:
Expand Down
12 changes: 6 additions & 6 deletions tests/test.cpp
Expand Up @@ -306,7 +306,7 @@ SUITE(commas) {
CHECK_EQUAL(false, document.is_valid());
CHECK_EQUAL(1u, document.get_error_line());
CHECK_EQUAL(2u, document.get_error_column());
CHECK_EQUAL("unexpected comma", document.get_error_message());
CHECK_EQUAL("invalid object key", document.get_error_message());
}

TEST(trailing_comma_array) {
Expand Down Expand Up @@ -598,15 +598,15 @@ SUITE(errors) {
const sajson::document& document = parse(literal("{0:0}"));
CHECK_EQUAL(false, document.is_valid());
CHECK_EQUAL(1u, document.get_error_line());
//CHECK_EQUAL(3, document.get_error_column());
CHECK_EQUAL("object key must be quoted", document.get_error_message());
CHECK_EQUAL(2u, document.get_error_column());
CHECK_EQUAL("invalid object key", document.get_error_message());
}

TEST(objects_must_have_keys) {
const sajson::document& document = parse(literal("{\"0\"}"));
CHECK_EQUAL(false, document.is_valid());
CHECK_EQUAL(1u, document.get_error_line());
//CHECK_EQUAL(3, document.get_error_column());
CHECK_EQUAL(5u, document.get_error_column());
CHECK_EQUAL("expected :", document.get_error_message());
}

Expand Down Expand Up @@ -638,8 +638,8 @@ SUITE(errors) {
const sajson::document& document = parse(literal("{]"));
CHECK_EQUAL(false, document.is_valid());
CHECK_EQUAL(1u, document.get_error_line());
//CHECK_EQUAL(3, document.get_error_column());
CHECK_EQUAL("object key must be quoted", document.get_error_message());
CHECK_EQUAL(2u, document.get_error_column());
CHECK_EQUAL("invalid object key", document.get_error_message());
}

#define CHECK_PARSE_ERROR(text, error_message) \
Expand Down

0 comments on commit 3828769

Please sign in to comment.