Commit 813eaf4e authored by Milo Yip's avatar Milo Yip

Merge pull request #25 from miloyip/issue22setjmp

Removal of setjmp()/longjmp()
parents 32b93052 a1a8abd0
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
#include "encodings.h" #include "encodings.h"
#include "internal/pow10.h" #include "internal/pow10.h"
#include "internal/stack.h" #include "internal/stack.h"
#include <csetjmp>
#ifdef RAPIDJSON_SSE42 #ifdef RAPIDJSON_SSE42
#include <nmmintrin.h> #include <nmmintrin.h>
...@@ -21,12 +20,21 @@ ...@@ -21,12 +20,21 @@
#pragma warning(disable : 4127) // conditional expression is constant #pragma warning(disable : 4127) // conditional expression is constant
#endif #endif
#ifndef RAPIDJSON_PARSE_ERROR_NORETURN
#define RAPIDJSON_PARSE_ERROR_NORETURN(msg, offset) \
RAPIDJSON_MULTILINEMACRO_BEGIN \
if (!HasParseError()) {\
parseError_ = msg; \
errorOffset_ = offset; \
}\
RAPIDJSON_MULTILINEMACRO_END
#endif
#ifndef RAPIDJSON_PARSE_ERROR #ifndef RAPIDJSON_PARSE_ERROR
#define RAPIDJSON_PARSE_ERROR(msg, offset) \ #define RAPIDJSON_PARSE_ERROR(msg, offset) \
RAPIDJSON_MULTILINEMACRO_BEGIN \ RAPIDJSON_MULTILINEMACRO_BEGIN \
parseError_ = msg; \ RAPIDJSON_PARSE_ERROR_NORETURN(msg, offset); \
errorOffset_ = offset; \ return; \
longjmp(jmpbuf_, 1); \
RAPIDJSON_MULTILINEMACRO_END RAPIDJSON_MULTILINEMACRO_END
#endif #endif
...@@ -225,35 +233,24 @@ public: ...@@ -225,35 +233,24 @@ public:
parseError_ = 0; parseError_ = 0;
errorOffset_ = 0; errorOffset_ = 0;
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4611) // interaction between '_setjmp' and C++ object destruction is non-portable
#endif
if (setjmp(jmpbuf_)) {
#ifdef _MSC_VER
#pragma warning(pop)
#endif
stack_.Clear();
return false;
}
SkipWhitespace(is); SkipWhitespace(is);
if (is.Peek() == '\0') if (is.Peek() == '\0')
RAPIDJSON_PARSE_ERROR("Text only contains white space(s)", is.Tell()); RAPIDJSON_PARSE_ERROR_NORETURN("Text only contains white space(s)", is.Tell());
else { else {
switch (is.Peek()) { switch (is.Peek()) {
case '{': ParseObject<parseFlags>(is, handler); break; case '{': ParseObject<parseFlags>(is, handler); break;
case '[': ParseArray<parseFlags>(is, handler); break; case '[': ParseArray<parseFlags>(is, handler); break;
default: RAPIDJSON_PARSE_ERROR("Expect either an object or array at root", is.Tell()); default: RAPIDJSON_PARSE_ERROR_NORETURN("Expect either an object or array at root", is.Tell());
} }
SkipWhitespace(is); SkipWhitespace(is);
if (is.Peek() != '\0') if (is.Peek() != '\0')
RAPIDJSON_PARSE_ERROR("Nothing should follow the root object or array.", is.Tell()); RAPIDJSON_PARSE_ERROR_NORETURN("Nothing should follow the root object or array.", is.Tell());
} }
return true; stack_.Clear();
return !HasParseError();
} }
bool HasParseError() const { return parseError_ != 0; } bool HasParseError() const { return parseError_ != 0; }
...@@ -280,6 +277,9 @@ private: ...@@ -280,6 +277,9 @@ private:
RAPIDJSON_PARSE_ERROR("Name of an object member must be a string", is.Tell()); RAPIDJSON_PARSE_ERROR("Name of an object member must be a string", is.Tell());
ParseString<parseFlags>(is, handler); ParseString<parseFlags>(is, handler);
if (HasParseError())
return;
SkipWhitespace(is); SkipWhitespace(is);
if (is.Take() != ':') if (is.Take() != ':')
...@@ -288,6 +288,9 @@ private: ...@@ -288,6 +288,9 @@ private:
SkipWhitespace(is); SkipWhitespace(is);
ParseValue<parseFlags>(is, handler); ParseValue<parseFlags>(is, handler);
if (HasParseError())
return;
SkipWhitespace(is); SkipWhitespace(is);
++memberCount; ++memberCount;
...@@ -316,6 +319,9 @@ private: ...@@ -316,6 +319,9 @@ private:
for (SizeType elementCount = 0;;) { for (SizeType elementCount = 0;;) {
ParseValue<parseFlags>(is, handler); ParseValue<parseFlags>(is, handler);
if (HasParseError())
return;
++elementCount; ++elementCount;
SkipWhitespace(is); SkipWhitespace(is);
...@@ -375,8 +381,10 @@ private: ...@@ -375,8 +381,10 @@ private:
codepoint -= 'A' - 10; codepoint -= 'A' - 10;
else if (c >= 'a' && c <= 'f') else if (c >= 'a' && c <= 'f')
codepoint -= 'a' - 10; codepoint -= 'a' - 10;
else else {
RAPIDJSON_PARSE_ERROR("Incorrect hex digit after \\u escape", s.Tell() - 1); RAPIDJSON_PARSE_ERROR_NORETURN("Incorrect hex digit after \\u escape", s.Tell() - 1);
return 0;
}
} }
is = s; // Restore is is = s; // Restore is
return codepoint; return codepoint;
...@@ -652,7 +660,6 @@ private: ...@@ -652,7 +660,6 @@ private:
static const size_t kDefaultStackCapacity = 256; //!< Default stack capacity in bytes for storing a single decoded string. static const size_t kDefaultStackCapacity = 256; //!< Default stack capacity in bytes for storing a single decoded string.
internal::Stack<Allocator> stack_; //!< A stack for storing decoded string temporarily during non-destructive parsing. internal::Stack<Allocator> stack_; //!< A stack for storing decoded string temporarily during non-destructive parsing.
jmp_buf jmpbuf_; //!< setjmp buffer for fast exit from nested parsing function calls.
const char* parseError_; const char* parseError_;
size_t errorOffset_; size_t errorOffset_;
}; // class GenericReader }; // class GenericReader
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment