diff --git a/include/weaseljson.h b/include/weaseljson.h index aedbd7d..4e01ec7 100644 --- a/include/weaseljson.h +++ b/include/weaseljson.h @@ -1,6 +1,10 @@ #ifndef WEASELJSON_H #define WEASELJSON_H +#ifdef __cplusplus +extern "C" { +#endif + struct WeaselJsonCallbacks { void (*on_begin_object)(void *data); void (*on_end_object)(void *data); @@ -17,4 +21,37 @@ struct WeaselJsonCallbacks { void (*on_null_literal)(void *data); }; +enum WeaselJsonStatus { + /** Accept input */ + WeaselJson_OK, + /** Consumed all available input. Call WeaselJsonParser_parse with more data + to provide more input, or call with length 0 to indicate end of data*/ + WeaselJson_AGAIN, + /** Invalid json */ + WeaselJson_REJECT, + /** json is too deeply nested */ + WeaselJson_OVERFLOW, +}; + +typedef struct WeaselJsonParser WeaselJsonParser; + +/** Increasing stack size increases memory usage but also increases the depth of + * nested json accepted. */ +WeaselJsonParser *WeaselJsonParser_create(int stackSize); + +/** Restore the parser to its newly-created state */ +void WeaselJsonParser_reset(WeaselJsonParser *parser); + +/** Destroy the parser */ +void WeaselJsonParser_destroy(WeaselJsonParser *parser); + +/** Incrementally parse `len` more bytes starting at `buf`. `buf` may be + * modified. Call with `len` 0 to indicate end of data */ +WeaselJsonStatus WeaselJsonParser_parse(WeaselJsonParser *parser, char *buf, + int len); + +#ifdef __cplusplus +} +#endif + #endif diff --git a/src/fuzz.cpp b/src/fuzz.cpp index f6fbbc8..78b045c 100644 --- a/src/fuzz.cpp +++ b/src/fuzz.cpp @@ -1,48 +1,49 @@ #include "callbacks.h" #include "json_value.h" #include "parser3.h" +#include "weaseljson.h" #include -std::pair runStreaming(std::string copy, - int stride) { +std::pair runStreaming(std::string copy, + int stride) { SerializeState state; auto c = serializeCallbacks(); parser3::Parser3 parser(&c, &state); if (stride == 0) { auto s = parser.parse(copy.data(), copy.size()); - if (s != parser3::S_AGAIN) { + if (s != WeaselJson_AGAIN) { return {state.result, s}; } } else { for (int i = 0; i < copy.size(); i += stride) { auto s = parser.parse(copy.data() + i, std::min(stride, copy.size() - i)); - if (s != parser3::S_AGAIN) { + if (s != WeaselJson_AGAIN) { return {state.result, s}; } } } auto s = parser.parse(nullptr, 0); - if (s != parser3::S_OK) { + if (s != WeaselJson_OK) { return {state.result, s}; } - return {state.result, parser3::S_OK}; + return {state.result, WeaselJson_OK}; } -std::pair runBatch(std::string copy) { +std::pair runBatch(std::string copy) { SerializeState state; auto c = serializeCallbacks(); parser3::Parser3 parser(&c, &state); auto s = parser.parse(copy.data(), copy.size()); - if (s != parser3::S_AGAIN) { + if (s != WeaselJson_AGAIN) { return {state.result, s}; } s = parser.parse(nullptr, 0); - if (s != parser3::S_OK) { + if (s != WeaselJson_OK) { return {state.result, s}; } - return {state.result, parser3::S_OK}; + return {state.result, WeaselJson_OK}; } void testStreaming(std::string const &json) { @@ -51,15 +52,15 @@ void testStreaming(std::string const &json) { auto streaming = runStreaming(json, stride); if (streaming != batch) { if (streaming.second == batch.second && - streaming.second != parser3::S_OK) { + streaming.second != WeaselJson_OK) { // It's ok if the processed data doesn't match if parsing failed return; } printf("streaming: %s, %s\n", - streaming.second == parser3::S_OK ? "accept" : "reject", + streaming.second == WeaselJson_OK ? "accept" : "reject", streaming.first.c_str()); printf("batch: %s, %s\n", - streaming.second == parser3::S_OK ? "accept" : "reject", + streaming.second == WeaselJson_OK ? "accept" : "reject", batch.first.c_str()); abort(); } @@ -67,13 +68,13 @@ void testStreaming(std::string const &json) { } void compareWithSimdjson(std::string const &json) { - parser3::Status ours; + WeaselJsonStatus ours; { auto copy = json; auto c = noopCallbacks(); parser3::Parser3 parser3(&c, nullptr); ours = parser3.parse(copy.data(), copy.size()); - if (ours == parser3::S_AGAIN) { + if (ours == WeaselJson_AGAIN) { ours = parser3.parse(nullptr, 0); } } @@ -83,10 +84,10 @@ void compareWithSimdjson(std::string const &json) { simdjson::dom::parser parser; auto doc = parser.parse(my_padded_data); auto theirs = doc.error(); - if (ours == parser3::S_OVERFLOW || theirs == simdjson::DEPTH_ERROR) { + if (ours == WeaselJson_OVERFLOW || theirs == simdjson::DEPTH_ERROR) { return; } - if ((ours == parser3::S_OK) != (theirs == simdjson::SUCCESS)) { + if ((ours == WeaselJson_OK) != (theirs == simdjson::SUCCESS)) { if (json.starts_with("\xef\xbb\xbf")) { // What to do with byte order mark? return; diff --git a/src/json_value.h b/src/json_value.h index 237dfdd..b8dfc54 100644 --- a/src/json_value.h +++ b/src/json_value.h @@ -197,19 +197,19 @@ inline std::optional toValue(std::string copy, int stride) { auto c = readValueCallbacks(); parser3::Parser3 parser(&c, &state); if (stride == 0) { - if (parser.parse(copy.data(), copy.size()) != parser3::S_AGAIN) { + if (parser.parse(copy.data(), copy.size()) != WeaselJson_AGAIN) { return std::nullopt; } } else { for (int i = 0; i < copy.size(); i += stride) { if (parser.parse(copy.data() + i, std::min(stride, copy.size() - i)) != - parser3::S_AGAIN) { + WeaselJson_AGAIN) { return std::nullopt; } } } - if (parser.parse(nullptr, 0) != parser3::S_OK) { + if (parser.parse(nullptr, 0) != WeaselJson_OK) { return std::nullopt; } return std::move(state.result); diff --git a/src/parser3.h b/src/parser3.h index b53b4e7..7859d1b 100644 --- a/src/parser3.h +++ b/src/parser3.h @@ -16,18 +16,7 @@ namespace parser3 { -enum Status { - // Accept input - S_OK, - // Consumed all available input. - S_AGAIN, - // Invalid json - S_REJECT, - // json is too deeply nested - S_OVERFLOW, -}; - -typedef Status (*Continuation)(struct Parser3 *); +typedef WeaselJsonStatus (*Continuation)(struct Parser3 *); // These appear in the stack of the pushdown // automata @@ -79,7 +68,7 @@ struct Parser3 { std::ignore = push({N_WHITESPACE, N_VALUE, N_WHITESPACE, T_EOF}); } - [[nodiscard]] Status parse(char *buf, int len) { + [[nodiscard]] WeaselJsonStatus parse(char *buf, int len) { complete = len == 0; this->buf = this->dataBegin = this->writeBuf = buf; this->bufEnd = buf + len; @@ -106,14 +95,14 @@ struct Parser3 { assert(!empty()); --stackPtr; } - [[nodiscard]] Status push(std::initializer_list symbols) { + [[nodiscard]] WeaselJsonStatus push(std::initializer_list symbols) { if (stackPtr >= std::end(stack) - symbols.size()) [[unlikely]] { - return S_OVERFLOW; + return WeaselJson_OVERFLOW; } for (int i = symbols.size() - 1; i >= 0; --i) { *stackPtr++ = *(symbols.begin() + i); } - return S_OK; + return WeaselJson_OK; } [[nodiscard]] int len() const { auto result = bufEnd - buf; @@ -125,7 +114,7 @@ struct Parser3 { return *(stackPtr - 1); } - static Status keepGoing(Parser3 *self); + static WeaselJsonStatus keepGoing(Parser3 *self); constexpr static int kMaxStackSize = 1024; @@ -148,7 +137,7 @@ struct Parser3 { uint32_t minCodepoint; }; -inline Status n_value(Parser3 *self) { +inline WeaselJsonStatus n_value(Parser3 *self) { switch (*self->buf) { case '{': self->pop(); @@ -207,14 +196,14 @@ inline Status n_value(Parser3 *self) { } break; default: - return S_REJECT; + return WeaselJson_REJECT; } MUSTTAIL return Parser3::keepGoing(self); } -inline Status n_object(Parser3 *self) { +inline WeaselJsonStatus n_object(Parser3 *self) { if (*self->buf != '{') { - return S_REJECT; + return WeaselJson_REJECT; } self->callbacks->on_begin_object(self->data); ++self->buf; @@ -225,7 +214,7 @@ inline Status n_object(Parser3 *self) { MUSTTAIL return Parser3::keepGoing(self); } -inline Status n_object2(Parser3 *self) { +inline WeaselJsonStatus n_object2(Parser3 *self) { switch (*self->buf) { case '}': ++self->buf; @@ -240,11 +229,11 @@ inline Status n_object2(Parser3 *self) { } MUSTTAIL return Parser3::keepGoing(self); default: - return S_REJECT; + return WeaselJson_REJECT; } } -inline Status n_object3(Parser3 *self) { +inline WeaselJsonStatus n_object3(Parser3 *self) { switch (*self->buf) { case '}': ++self->buf; @@ -260,13 +249,13 @@ inline Status n_object3(Parser3 *self) { } MUSTTAIL return Parser3::keepGoing(self); default: - return S_REJECT; + return WeaselJson_REJECT; } } -inline Status n_array(Parser3 *self) { +inline WeaselJsonStatus n_array(Parser3 *self) { if (*self->buf != '[') { - return S_REJECT; + return WeaselJson_REJECT; } self->callbacks->on_begin_array(self->data); ++self->buf; @@ -277,7 +266,7 @@ inline Status n_array(Parser3 *self) { MUSTTAIL return Parser3::keepGoing(self); } -inline Status n_array2(Parser3 *self) { +inline WeaselJsonStatus n_array2(Parser3 *self) { switch (*self->buf) { case ']': ++self->buf; @@ -293,7 +282,7 @@ inline Status n_array2(Parser3 *self) { } } -inline Status n_array3(Parser3 *self) { +inline WeaselJsonStatus n_array3(Parser3 *self) { switch (*self->buf) { case ']': ++self->buf; @@ -308,13 +297,13 @@ inline Status n_array3(Parser3 *self) { } MUSTTAIL return Parser3::keepGoing(self); default: - return S_REJECT; + return WeaselJson_REJECT; } } -inline Status n_string(Parser3 *self) { +inline WeaselJsonStatus n_string(Parser3 *self) { if (*self->buf != '"') { - return S_REJECT; + return WeaselJson_REJECT; } self->callbacks->on_begin_string(self->data); ++self->buf; @@ -326,7 +315,7 @@ inline Status n_string(Parser3 *self) { MUSTTAIL return Parser3::keepGoing(self); } -inline Status n_string2(Parser3 *self) { +inline WeaselJsonStatus n_string2(Parser3 *self) { auto commit = [self, before = self->buf]() { int len = self->buf - before; if (self->writeBuf != before) { @@ -395,11 +384,11 @@ begin: MUSTTAIL return Parser3::keepGoing(self); case Tables::CONTINUATION_BYTE: case Tables::INVALID: - return S_REJECT; + return WeaselJson_REJECT; } } -inline Status n_string_following_escape(Parser3 *self) { +inline WeaselJsonStatus n_string_following_escape(Parser3 *self) { switch (*self->buf) { case '"': case '\\': @@ -424,14 +413,14 @@ inline Status n_string_following_escape(Parser3 *self) { } MUSTTAIL return Parser3::keepGoing(self); default: - return S_REJECT; + return WeaselJson_REJECT; } } -inline Status t_utf8_continuation_byte(Parser3 *self) { +inline WeaselJsonStatus t_utf8_continuation_byte(Parser3 *self) { if (tables.stringByteMeaning[uint8_t(*self->buf)] != Tables::CONTINUATION_BYTE) { - return S_REJECT; + return WeaselJson_REJECT; } self->utf8Codepoint <<= 6; self->utf8Codepoint |= *self->buf & 0b00111111; @@ -440,17 +429,17 @@ inline Status t_utf8_continuation_byte(Parser3 *self) { MUSTTAIL return Parser3::keepGoing(self); } -inline Status t_utf8_last_continuation_byte(Parser3 *self) { +inline WeaselJsonStatus t_utf8_last_continuation_byte(Parser3 *self) { if (tables.stringByteMeaning[uint8_t(*self->buf)] != Tables::CONTINUATION_BYTE) { - return S_REJECT; + return WeaselJson_REJECT; } self->utf8Codepoint <<= 6; self->utf8Codepoint |= *self->buf & 0b00111111; if (self->utf8Codepoint < self->minCodepoint || self->utf8Codepoint > 0x10ffff || (0xd800 <= self->utf8Codepoint && self->utf8Codepoint <= 0xdfff)) { - return S_REJECT; + return WeaselJson_REJECT; } // TODO tell valgrind utf8Codepoint and minCodepoint are uninitialized *self->writeBuf++ = *self->buf++; @@ -458,25 +447,25 @@ inline Status t_utf8_last_continuation_byte(Parser3 *self) { MUSTTAIL return Parser3::keepGoing(self); } -inline Status t_digit(Parser3 *self) { +inline WeaselJsonStatus t_digit(Parser3 *self) { if ('0' <= *self->buf && *self->buf <= '9') { ++self->buf; self->pop(); MUSTTAIL return Parser3::keepGoing(self); } - return S_REJECT; + return WeaselJson_REJECT; } -inline Status t_onenine(Parser3 *self) { +inline WeaselJsonStatus t_onenine(Parser3 *self) { if ('1' <= *self->buf && *self->buf <= '9') { ++self->buf; self->pop(); MUSTTAIL return Parser3::keepGoing(self); } - return S_REJECT; + return WeaselJson_REJECT; } -inline Status t_hex(Parser3 *self) { +inline WeaselJsonStatus t_hex(Parser3 *self) { self->utf8Codepoint <<= 4; if (('0' <= *self->buf && *self->buf <= '9')) { self->utf8Codepoint |= *self->buf - '0'; @@ -485,14 +474,14 @@ inline Status t_hex(Parser3 *self) { } else if ('A' <= *self->buf && *self->buf <= 'F') { self->utf8Codepoint |= 10 + *self->buf - 'A'; } else { - return S_REJECT; + return WeaselJson_REJECT; } ++self->buf; self->pop(); MUSTTAIL return Parser3::keepGoing(self); } -inline Status t_hex2(Parser3 *self) { +inline WeaselJsonStatus t_hex2(Parser3 *self) { self->utf8Codepoint <<= 4; if (('0' <= *self->buf && *self->buf <= '9')) { self->utf8Codepoint |= *self->buf - '0'; @@ -501,7 +490,7 @@ inline Status t_hex2(Parser3 *self) { } else if ('A' <= *self->buf && *self->buf <= 'F') { self->utf8Codepoint |= 10 + *self->buf - 'A'; } else { - return S_REJECT; + return WeaselJson_REJECT; } ++self->buf; @@ -559,7 +548,7 @@ inline Status t_hex2(Parser3 *self) { MUSTTAIL return Parser3::keepGoing(self); } -inline Status t_hex3(Parser3 *self) { +inline WeaselJsonStatus t_hex3(Parser3 *self) { self->utf8Codepoint <<= 4; if (('0' <= *self->buf && *self->buf <= '9')) { self->utf8Codepoint |= *self->buf - '0'; @@ -568,12 +557,12 @@ inline Status t_hex3(Parser3 *self) { } else if ('A' <= *self->buf && *self->buf <= 'F') { self->utf8Codepoint |= 10 + *self->buf - 'A'; } else { - return S_REJECT; + return WeaselJson_REJECT; } ++self->buf; if (!(0xdc00 <= self->utf8Codepoint && self->utf8Codepoint <= 0xdfff)) { - return S_REJECT; + return WeaselJson_REJECT; } // Decode utf16 surrogate pair @@ -585,7 +574,7 @@ inline Status t_hex3(Parser3 *self) { char tmp[4]; assert(self->utf8Codepoint >= 0x10000); if (self->utf8Codepoint > 0x10FFFF) { - return S_REJECT; + return WeaselJson_REJECT; } bool useTmp = self->buf - self->writeBuf < 4; char *p = tmp; @@ -609,7 +598,7 @@ inline Status t_hex3(Parser3 *self) { MUSTTAIL return Parser3::keepGoing(self); } -inline Status n_integer(Parser3 *self) { +inline WeaselJsonStatus n_integer(Parser3 *self) { self->callbacks->on_begin_number(self->data); self->dataBegin = self->buf; switch (*self->buf) { @@ -640,11 +629,11 @@ inline Status n_integer(Parser3 *self) { } MUSTTAIL return Parser3::keepGoing(self); default: - return S_REJECT; + return WeaselJson_REJECT; } } -inline Status n_integer2(Parser3 *self) { +inline WeaselJsonStatus n_integer2(Parser3 *self) { switch (*self->buf) { case '0': ++self->buf; @@ -666,11 +655,11 @@ inline Status n_integer2(Parser3 *self) { } MUSTTAIL return Parser3::keepGoing(self); default: - return S_REJECT; + return WeaselJson_REJECT; } } -inline Status n_digits(Parser3 *self) { +inline WeaselJsonStatus n_digits(Parser3 *self) { switch (*self->buf) { case '0': case '1': @@ -689,11 +678,11 @@ inline Status n_digits(Parser3 *self) { } MUSTTAIL return Parser3::keepGoing(self); default: - return S_REJECT; + return WeaselJson_REJECT; } } -inline Status n_digits2(Parser3 *self) { +inline WeaselJsonStatus n_digits2(Parser3 *self) { if (self->len() == 0) { self->pop(); MUSTTAIL return Parser3::keepGoing(self); @@ -717,7 +706,7 @@ inline Status n_digits2(Parser3 *self) { } } -inline Status n_fraction(Parser3 *self) { +inline WeaselJsonStatus n_fraction(Parser3 *self) { if (self->len() == 0) { self->pop(); MUSTTAIL return Parser3::keepGoing(self); @@ -736,7 +725,7 @@ inline Status n_fraction(Parser3 *self) { } } -inline Status n_exponent(Parser3 *self) { +inline WeaselJsonStatus n_exponent(Parser3 *self) { if (self->len() == 0) { self->pop(); MUSTTAIL return Parser3::keepGoing(self); @@ -756,7 +745,7 @@ inline Status n_exponent(Parser3 *self) { } } -inline Status n_sign(Parser3 *self) { +inline WeaselJsonStatus n_sign(Parser3 *self) { if (self->len() == 0) { self->pop(); MUSTTAIL return Parser3::keepGoing(self); @@ -773,7 +762,7 @@ inline Status n_sign(Parser3 *self) { } } -inline Status n_whitespace(Parser3 *self) { +inline WeaselJsonStatus n_whitespace(Parser3 *self) { if (self->len() == 0) { self->pop(); MUSTTAIL return Parser3::keepGoing(self); @@ -781,60 +770,60 @@ inline Status n_whitespace(Parser3 *self) { while (tables.whitespace[uint8_t(*self->buf)]) { ++self->buf; if (self->buf == self->bufEnd) { - return S_AGAIN; + return WeaselJson_AGAIN; } } self->pop(); MUSTTAIL return Parser3::keepGoing(self); } -inline Status n_true(Parser3 *self) { +inline WeaselJsonStatus n_true(Parser3 *self) { if (*self->buf == 'e') { ++self->buf; self->pop(); self->callbacks->on_true_literal(self->data); MUSTTAIL return Parser3::keepGoing(self); } - return S_REJECT; + return WeaselJson_REJECT; } -inline Status n_false(Parser3 *self) { +inline WeaselJsonStatus n_false(Parser3 *self) { if (*self->buf == 'e') { ++self->buf; self->pop(); self->callbacks->on_false_literal(self->data); MUSTTAIL return Parser3::keepGoing(self); } - return S_REJECT; + return WeaselJson_REJECT; } -inline Status n_null(Parser3 *self) { +inline WeaselJsonStatus n_null(Parser3 *self) { if (*self->buf == 'l') { ++self->buf; self->pop(); self->callbacks->on_null_literal(self->data); MUSTTAIL return Parser3::keepGoing(self); } - return S_REJECT; + return WeaselJson_REJECT; } -template inline Status singleChar(Parser3 *self) { +template inline WeaselJsonStatus singleChar(Parser3 *self) { if (*self->buf == kChar) { ++self->buf; self->pop(); MUSTTAIL return Parser3::keepGoing(self); } - return S_REJECT; + return WeaselJson_REJECT; } -inline Status t_eof(Parser3 *self) { +inline WeaselJsonStatus t_eof(Parser3 *self) { if (self->len() > 0) { - return S_REJECT; + return WeaselJson_REJECT; } - return self->complete ? S_OK : S_AGAIN; + return self->complete ? WeaselJson_OK : WeaselJson_AGAIN; } -inline Status t_end_number(Parser3 *self) { +inline WeaselJsonStatus t_end_number(Parser3 *self) { self->pop(); self->flushNumber(); self->callbacks->on_end_number(self->data); @@ -847,7 +836,7 @@ constexpr inline struct ContinuationTable { for (int i = 0; i < N_SYMBOL_COUNT; ++i) { continuations[i] = +[](struct Parser3 *) { printf("unimplemented\n"); - return S_REJECT; + return WeaselJson_REJECT; }; } continuations[N_VALUE] = n_value; @@ -942,7 +931,7 @@ constexpr inline struct ContinuationTable { bool acceptsEmptyString[N_SYMBOL_COUNT]{}; } symbolTables; -inline Status Parser3::keepGoing(Parser3 *self) { +inline WeaselJsonStatus Parser3::keepGoing(Parser3 *self) { // self->debugPrint(); if (self->len() == 0) { if (!self->complete) { @@ -992,10 +981,10 @@ inline Status Parser3::keepGoing(Parser3 *self) { case N_SYMBOL_COUNT: break; } - return S_AGAIN; + return WeaselJson_AGAIN; } if (!symbolTables.acceptsEmptyString[self->top()]) { - return S_REJECT; + return WeaselJson_REJECT; } } MUSTTAIL return symbolTables.continuations[self->top()](self); diff --git a/src/test.cpp b/src/test.cpp index b30b3f9..9a5b389 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -12,6 +12,7 @@ #include "callbacks.h" #include "parser3.h" +#include "weaseljson.h" // This is the JSON grammar in McKeeman Form. @@ -154,15 +155,15 @@ void testStreaming(std::string const &json) { auto copy = json; parser3::Parser3 parser(&c, &streaming); for (int i = 0; i < copy.size(); ++i) { - REQUIRE(parser.parse(copy.data() + i, 1) == parser3::S_AGAIN); + REQUIRE(parser.parse(copy.data() + i, 1) == WeaselJson_AGAIN); } - CHECK(parser.parse(nullptr, 0) == parser3::S_OK); + CHECK(parser.parse(nullptr, 0) == WeaselJson_OK); } { auto copy = json; parser3::Parser3 parser(&c, &batch); - REQUIRE(parser.parse(copy.data(), copy.size()) == parser3::S_AGAIN); - CHECK(parser.parse(nullptr, 0) == parser3::S_OK); + REQUIRE(parser.parse(copy.data(), copy.size()) == WeaselJson_AGAIN); + CHECK(parser.parse(nullptr, 0) == WeaselJson_OK); } CHECK(streaming.result == batch.result); } @@ -177,32 +178,32 @@ TEST_CASE("parser3") { parser3::Parser3 parser(&c, &state); int i = 0; for (; i < copy.length() - 1; ++i) { - REQUIRE(parser.parse(copy.data() + i, 1) == parser3::S_AGAIN); + REQUIRE(parser.parse(copy.data() + i, 1) == WeaselJson_AGAIN); } - CHECK(parser.parse(copy.data() + i, 1) == parser3::S_AGAIN); - CHECK(parser.parse(nullptr, 0) == parser3::S_OK); + CHECK(parser.parse(copy.data() + i, 1) == WeaselJson_AGAIN); + CHECK(parser.parse(nullptr, 0) == WeaselJson_OK); puts(""); } { std::string copy = "{\"x\": [], \"y\": {}}"; parser3::Parser3 parser(&c, &state); - CHECK(parser.parse(copy.data(), copy.length()) == parser3::S_AGAIN); - CHECK(parser.parse(nullptr, 0) == parser3::S_OK); + CHECK(parser.parse(copy.data(), copy.length()) == WeaselJson_AGAIN); + CHECK(parser.parse(nullptr, 0) == WeaselJson_OK); puts(""); } { auto c = noopCallbacks(); std::string copy = "{\"a\":\"a"; parser3::Parser3 parser(&c, &state); - CHECK(parser.parse(copy.data(), copy.length()) == parser3::S_AGAIN); - CHECK(parser.parse(nullptr, 0) == parser3::S_REJECT); + CHECK(parser.parse(copy.data(), copy.length()) == WeaselJson_AGAIN); + CHECK(parser.parse(nullptr, 0) == WeaselJson_REJECT); } { auto c = noopCallbacks(); std::string copy = "["; parser3::Parser3 parser(&c, &state); - CHECK(parser.parse(copy.data(), copy.length()) == parser3::S_AGAIN); - CHECK(parser.parse(nullptr, 0) == parser3::S_REJECT); + CHECK(parser.parse(copy.data(), copy.length()) == WeaselJson_AGAIN); + CHECK(parser.parse(nullptr, 0) == WeaselJson_REJECT); } } @@ -225,9 +226,9 @@ void doTestUnescapingUtf8(std::string const &escaped, CAPTURE(i); CHECK( parser.parse(copy.data() + i, std::min(stride, copy.size() - i)) == - parser3::S_AGAIN); + WeaselJson_AGAIN); } - CHECK(parser.parse(nullptr, 0) == parser3::S_OK); + CHECK(parser.parse(nullptr, 0) == WeaselJson_OK); CHECK(result.size() == expected.size()); CHECK(result == expected); } @@ -269,7 +270,7 @@ TEST_CASE("bench3") { auto copy = json; parser3::Parser3 parser(&c, nullptr); bench.doNotOptimizeAway(parser.parse(copy.data(), copy.length())); - bench.doNotOptimizeAway(parser.parse(nullptr, 0) == parser3::S_OK); + bench.doNotOptimizeAway(parser.parse(nullptr, 0) == WeaselJson_OK); }); } diff --git a/src/validate.cpp b/src/validate.cpp index 58d5fc7..1429ffb 100644 --- a/src/validate.cpp +++ b/src/validate.cpp @@ -3,6 +3,7 @@ #include "callbacks.h" #include "parser3.h" +#include "weaseljson.h" int main(int argc, char **argv) { if (argc < 2) { @@ -24,12 +25,12 @@ int main(int argc, char **argv) { return 1; } switch (parser.parse(buf, l)) { - case parser3::S_OK: + case WeaselJson_OK: return 0; - case parser3::S_AGAIN: + case WeaselJson_AGAIN: continue; - case parser3::S_REJECT: - case parser3::S_OVERFLOW: + case WeaselJson_REJECT: + case WeaselJson_OVERFLOW: return 1; } if (l == 0) {