Merge remote-tracking branch 'miloyip/master'
This commit is contained in:
commit
237d2f2ea3
0
bin/types/booleans.json
Executable file → Normal file
0
bin/types/booleans.json
Executable file → Normal file
0
bin/types/floats.json
Executable file → Normal file
0
bin/types/floats.json
Executable file → Normal file
0
bin/types/guids.json
Executable file → Normal file
0
bin/types/guids.json
Executable file → Normal file
0
bin/types/integers.json
Executable file → Normal file
0
bin/types/integers.json
Executable file → Normal file
0
bin/types/mixed.json
Executable file → Normal file
0
bin/types/mixed.json
Executable file → Normal file
0
bin/types/nulls.json
Executable file → Normal file
0
bin/types/nulls.json
Executable file → Normal file
0
bin/types/paragraphs.json
Executable file → Normal file
0
bin/types/paragraphs.json
Executable file → Normal file
51
doc/sax.md
51
doc/sax.md
@ -8,7 +8,7 @@ In RapidJSON, `Reader` (typedef of `GenericReader<...>`) is the SAX-style parser
|
||||
|
||||
# Reader {#Reader}
|
||||
|
||||
`Reader` parses a JSON from a stream. While it reads characters from the stream, it analyze the characters according to the syntax of JSON, and publish events to a handler.
|
||||
`Reader` parses a JSON from a stream. While it reads characters from the stream, it analyzes the characters according to the syntax of JSON, and publishes events to a handler.
|
||||
|
||||
For example, here is a JSON.
|
||||
|
||||
@ -24,7 +24,7 @@ For example, here is a JSON.
|
||||
}
|
||||
~~~~~~~~~~
|
||||
|
||||
While a `Reader` parses this JSON, it publishes the following events to the handler sequentially:
|
||||
When a `Reader` parses this JSON, it publishes the following events to the handler sequentially:
|
||||
|
||||
~~~~~~~~~~
|
||||
StartObject()
|
||||
@ -50,7 +50,7 @@ EndArray(4)
|
||||
EndObject(7)
|
||||
~~~~~~~~~~
|
||||
|
||||
These events can be easily matched with the JSON, except some event parameters need further explanation. Let's see the `simplereader` example which produces exactly the same output as above:
|
||||
These events can be easily matched with the JSON, but some event parameters need further explanation. Let's see the `simplereader` example which produces exactly the same output as above:
|
||||
|
||||
~~~~~~~~~~cpp
|
||||
#include "rapidjson/reader.h"
|
||||
@ -91,11 +91,11 @@ void main() {
|
||||
}
|
||||
~~~~~~~~~~
|
||||
|
||||
Note that, RapidJSON uses template to statically bind the `Reader` type and the handler type, instead of using class with virtual functions. This paradigm can improve the performance by inlining functions.
|
||||
Note that RapidJSON uses templates to statically bind the `Reader` type and the handler type, instead of using classes with virtual functions. This paradigm can improve performance by inlining functions.
|
||||
|
||||
## Handler {#Handler}
|
||||
|
||||
As the previous example showed, user needs to implement a handler, which consumes the events (function calls) from `Reader`. The handler must contain the following member functions.
|
||||
As shown in the previous example, the user needs to implement a handler which consumes the events (via function calls) from the `Reader`. The handler must contain the following member functions.
|
||||
|
||||
~~~~~~~~~~cpp
|
||||
class Handler {
|
||||
@ -122,15 +122,15 @@ class Handler {
|
||||
|
||||
When the `Reader` encounters a JSON number, it chooses a suitable C++ type mapping. And then it calls *one* function out of `Int(int)`, `Uint(unsigned)`, `Int64(int64_t)`, `Uint64(uint64_t)` and `Double(double)`. If `kParseNumbersAsStrings` is enabled, `Reader` will always calls `RawNumber()` instead.
|
||||
|
||||
`String(const char* str, SizeType length, bool copy)` is called when the `Reader` encounters a string. The first parameter is pointer to the string. The second parameter is the length of the string (excluding the null terminator). Note that RapidJSON supports null character `\0` inside a string. If such situation happens, `strlen(str) < length`. The last `copy` indicates whether the handler needs to make a copy of the string. For normal parsing, `copy = true`. Only when *insitu* parsing is used, `copy = false`. And beware that, the character type depends on the target encoding, which will be explained later.
|
||||
`String(const char* str, SizeType length, bool copy)` is called when the `Reader` encounters a string. The first parameter is pointer to the string. The second parameter is the length of the string (excluding the null terminator). Note that RapidJSON supports null character `\0` inside a string. If such situation happens, `strlen(str) < length`. The last `copy` indicates whether the handler needs to make a copy of the string. For normal parsing, `copy = true`. Only when *insitu* parsing is used, `copy = false`. And be aware that the character type depends on the target encoding, which will be explained later.
|
||||
|
||||
When the `Reader` encounters the beginning of an object, it calls `StartObject()`. An object in JSON is a set of name-value pairs. If the object contains members it first calls `Key()` for the name of member, and then calls functions depending on the type of the value. These calls of name-value pairs repeats until calling `EndObject(SizeType memberCount)`. Note that the `memberCount` parameter is just an aid for the handler, user may not need this parameter.
|
||||
When the `Reader` encounters the beginning of an object, it calls `StartObject()`. An object in JSON is a set of name-value pairs. If the object contains members it first calls `Key()` for the name of member, and then calls functions depending on the type of the value. These calls of name-value pairs repeat until calling `EndObject(SizeType memberCount)`. Note that the `memberCount` parameter is just an aid for the handler; users who do not need this parameter may ignore it.
|
||||
|
||||
Array is similar to object but simpler. At the beginning of an array, the `Reader` calls `BeginArary()`. If there is elements, it calls functions according to the types of element. Similarly, in the last call `EndArray(SizeType elementCount)`, the parameter `elementCount` is just an aid for the handler.
|
||||
Arrays are similar to objects, but simpler. At the beginning of an array, the `Reader` calls `BeginArary()`. If there is elements, it calls functions according to the types of element. Similarly, in the last call `EndArray(SizeType elementCount)`, the parameter `elementCount` is just an aid for the handler.
|
||||
|
||||
Every handler functions returns a `bool`. Normally it should returns `true`. If the handler encounters an error, it can return `false` to notify event publisher to stop further processing.
|
||||
Every handler function returns a `bool`. Normally it should return `true`. If the handler encounters an error, it can return `false` to notify the event publisher to stop further processing.
|
||||
|
||||
For example, when we parse a JSON with `Reader` and the handler detected that the JSON does not conform to the required schema, then the handler can return `false` and let the `Reader` stop further parsing. And the `Reader` will be in error state with error code `kParseErrorTermination`.
|
||||
For example, when we parse a JSON with `Reader` and the handler detects that the JSON does not conform to the required schema, the handler can return `false` and let the `Reader` stop further parsing. This will place the `Reader` in an error state, with error code `kParseErrorTermination`.
|
||||
|
||||
## GenericReader {#GenericReader}
|
||||
|
||||
@ -149,19 +149,19 @@ typedef GenericReader<UTF8<>, UTF8<> > Reader;
|
||||
} // namespace rapidjson
|
||||
~~~~~~~~~~
|
||||
|
||||
The `Reader` uses UTF-8 as both source and target encoding. The source encoding means the encoding in the JSON stream. The target encoding means the encoding of the `str` parameter in `String()` calls. For example, to parse a UTF-8 stream and outputs UTF-16 string events, you can define a reader by:
|
||||
The `Reader` uses UTF-8 as both source and target encoding. The source encoding means the encoding in the JSON stream. The target encoding means the encoding of the `str` parameter in `String()` calls. For example, to parse a UTF-8 stream and output UTF-16 string events, you can define a reader by:
|
||||
|
||||
~~~~~~~~~~cpp
|
||||
GenericReader<UTF8<>, UTF16<> > reader;
|
||||
~~~~~~~~~~
|
||||
|
||||
Note that, the default character type of `UTF16` is `wchar_t`. So this `reader`needs to call `String(const wchar_t*, SizeType, bool)` of the handler.
|
||||
Note that, the default character type of `UTF16` is `wchar_t`. So this `reader` needs to call `String(const wchar_t*, SizeType, bool)` of the handler.
|
||||
|
||||
The third template parameter `Allocator` is the allocator type for internal data structure (actually a stack).
|
||||
|
||||
## Parsing {#SaxParsing}
|
||||
|
||||
The one and only one function of `Reader` is to parse JSON.
|
||||
The main function of `Reader` is used to parse JSON.
|
||||
|
||||
~~~~~~~~~~cpp
|
||||
template <unsigned parseFlags, typename InputStream, typename Handler>
|
||||
@ -172,7 +172,30 @@ template <typename InputStream, typename Handler>
|
||||
bool Parse(InputStream& is, Handler& handler);
|
||||
~~~~~~~~~~
|
||||
|
||||
If an error occurs during parsing, it will return `false`. User can also calls `bool HasParseEror()`, `ParseErrorCode GetParseErrorCode()` and `size_t GetErrorOffset()` to obtain the error states. Actually `Document` uses these `Reader` functions to obtain parse errors. Please refer to [DOM](doc/dom.md) for details about parse error.
|
||||
If an error occurs during parsing, it will return `false`. User can also call `bool HasParseError()`, `ParseErrorCode GetParseErrorCode()` and `size_t GetErrorOffset()` to obtain the error states. In fact, `Document` uses these `Reader` functions to obtain parse errors. Please refer to [DOM](doc/dom.md) for details about parse errors.
|
||||
|
||||
## Token-by-Token Parsing {#TokenByTokenParsing}
|
||||
|
||||
Some users may wish to parse a JSON input stream a single token at a time, instead of immediately parsing an entire document without stopping. To parse JSON this way, instead of calling `Parse`, you can use the `IterativeParse` set of functions:
|
||||
|
||||
~~~~~~~~~~cpp
|
||||
void IterativeParseInit();
|
||||
|
||||
template <unsigned parseFlags, typename InputStream, typename Handler>
|
||||
bool IterativeParseNext(InputStream& is, Handler& handler);
|
||||
|
||||
bool IterativeParseComplete();
|
||||
~~~~~~~~~~
|
||||
|
||||
Here is an example of iteratively parsing JSON, token by token:
|
||||
|
||||
~~~~~~~~~~cpp
|
||||
reader.IterativeParseInit();
|
||||
while (!reader.IterativeParseComplete()) {
|
||||
reader.IterativeParseNext<kParseDefaultFlags>(is, handler);
|
||||
// Your handler has been called once.
|
||||
}
|
||||
~~~~~~~~~~
|
||||
|
||||
# Writer {#Writer}
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
#define RAPIDJSON_INTERNAL_STRFUNC_H_
|
||||
|
||||
#include "../stream.h"
|
||||
#include <cwchar>
|
||||
|
||||
RAPIDJSON_NAMESPACE_BEGIN
|
||||
namespace internal {
|
||||
@ -34,6 +35,16 @@ inline SizeType StrLen(const Ch* s) {
|
||||
return SizeType(p - s);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline SizeType StrLen(const char* s) {
|
||||
return SizeType(std::strlen(s));
|
||||
}
|
||||
|
||||
template <>
|
||||
inline SizeType StrLen(const wchar_t* s) {
|
||||
return SizeType(std::wcslen(s));
|
||||
}
|
||||
|
||||
//! Returns number of code points in a encoded string.
|
||||
template<typename Encoding>
|
||||
bool CountStringCodePoint(const typename Encoding::Ch* s, SizeType length, SizeType* outCount) {
|
||||
|
@ -107,7 +107,8 @@ public:
|
||||
return Base::WriteString(str, length);
|
||||
}
|
||||
|
||||
bool String(const Ch* str, SizeType length, bool copy = false) {
|
||||
template <typename T>
|
||||
RAPIDJSON_ENABLEIF_RETURN((internal::IsSame<Ch, T>), (bool)) String(const T* str, SizeType length, bool copy = false) {
|
||||
RAPIDJSON_ASSERT(str != 0);
|
||||
(void)copy;
|
||||
PrettyPrefix(kStringType);
|
||||
@ -126,7 +127,8 @@ public:
|
||||
return Base::WriteStartObject();
|
||||
}
|
||||
|
||||
bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); }
|
||||
template <typename T>
|
||||
RAPIDJSON_ENABLEIF_RETURN((internal::IsSame<Ch, T>), (bool)) Key(const T* str, SizeType length, bool copy = false) { return String(str, length, copy); }
|
||||
|
||||
#if RAPIDJSON_HAS_STDSTRING
|
||||
bool Key(const std::basic_string<Ch>& str) {
|
||||
@ -136,8 +138,10 @@ public:
|
||||
|
||||
bool EndObject(SizeType memberCount = 0) {
|
||||
(void)memberCount;
|
||||
RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level));
|
||||
RAPIDJSON_ASSERT(!Base::level_stack_.template Top<typename Base::Level>()->inArray);
|
||||
RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); // not inside an Object
|
||||
RAPIDJSON_ASSERT(!Base::level_stack_.template Top<typename Base::Level>()->inArray); // currently inside an Array, not Object
|
||||
RAPIDJSON_ASSERT(0 == Base::level_stack_.template Top<typename Base::Level>()->valueCount % 2); // Object has a Key without a Value
|
||||
|
||||
bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0;
|
||||
|
||||
if (!empty) {
|
||||
@ -182,8 +186,22 @@ public:
|
||||
//@{
|
||||
|
||||
//! Simpler but slower overload.
|
||||
bool String(const Ch* str) { return String(str, internal::StrLen(str)); }
|
||||
bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); }
|
||||
template <typename T>
|
||||
RAPIDJSON_ENABLEIF_RETURN((internal::IsSame<Ch, T>), (bool)) String(const T* const& str) { return String(str, internal::StrLen(str)); }
|
||||
template <typename T>
|
||||
RAPIDJSON_ENABLEIF_RETURN((internal::IsSame<Ch, T>), (bool)) Key(const T* const& str) { return Key(str, internal::StrLen(str)); }
|
||||
|
||||
//! The compiler can give us the length of quoted strings for free.
|
||||
template <typename T, size_t N>
|
||||
RAPIDJSON_ENABLEIF_RETURN((internal::IsSame<Ch, T>), (bool)) String(const T (&str)[N]) {
|
||||
RAPIDJSON_ASSERT(str[N-1] == '\0'); // you must pass in a null-terminated string (quoted constant strings are always null-terminated)
|
||||
return String(str, N-1);
|
||||
}
|
||||
template <typename T, size_t N>
|
||||
RAPIDJSON_ENABLEIF_RETURN((internal::IsSame<Ch, T>), (bool)) Key(const T (&str)[N]) {
|
||||
RAPIDJSON_ASSERT(str[N-1] == '\0'); // you must pass in a null-terminated string (quoted constant strings are always null-terminated)
|
||||
return Key(str, N-1);
|
||||
}
|
||||
|
||||
//@}
|
||||
|
||||
|
@ -1928,7 +1928,7 @@ private:
|
||||
const Context& CurrentContext() const { return *schemaStack_.template Top<Context>(); }
|
||||
|
||||
OutputHandler& CreateNullHandler() {
|
||||
return *(nullHandler_ = static_cast<OutputHandler*>(GetStateAllocator().Malloc(sizeof(OutputHandler))));
|
||||
return *(nullHandler_ = new (GetStateAllocator().Malloc(sizeof(OutputHandler))) OutputHandler);
|
||||
}
|
||||
|
||||
static const size_t kDefaultSchemaStackCapacity = 1024;
|
||||
|
@ -16,6 +16,7 @@
|
||||
#define RAPIDJSON_WRITER_H_
|
||||
|
||||
#include "stream.h"
|
||||
#include "internal/meta.h"
|
||||
#include "internal/stack.h"
|
||||
#include "internal/strfunc.h"
|
||||
#include "internal/dtoa.h"
|
||||
@ -198,7 +199,8 @@ public:
|
||||
return EndValue(WriteString(str, length));
|
||||
}
|
||||
|
||||
bool String(const Ch* str, SizeType length, bool copy = false) {
|
||||
template <typename T>
|
||||
RAPIDJSON_ENABLEIF_RETURN((internal::IsSame<Ch, T>), (bool)) String(const T* str, SizeType length, bool copy = false) {
|
||||
RAPIDJSON_ASSERT(str != 0);
|
||||
(void)copy;
|
||||
Prefix(kStringType);
|
||||
@ -217,12 +219,14 @@ public:
|
||||
return WriteStartObject();
|
||||
}
|
||||
|
||||
bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); }
|
||||
template <typename T>
|
||||
RAPIDJSON_ENABLEIF_RETURN((internal::IsSame<Ch, T>), (bool)) Key(const T* str, SizeType length, bool copy = false) { return String(str, length, copy); }
|
||||
|
||||
bool EndObject(SizeType memberCount = 0) {
|
||||
(void)memberCount;
|
||||
RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level));
|
||||
RAPIDJSON_ASSERT(!level_stack_.template Top<Level>()->inArray);
|
||||
RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); // not inside an Object
|
||||
RAPIDJSON_ASSERT(!level_stack_.template Top<Level>()->inArray); // currently inside an Array, not Object
|
||||
RAPIDJSON_ASSERT(0 == level_stack_.template Top<Level>()->valueCount % 2); // Object has a Key without a Value
|
||||
level_stack_.template Pop<Level>(1);
|
||||
return EndValue(WriteEndObject());
|
||||
}
|
||||
@ -246,8 +250,22 @@ public:
|
||||
//@{
|
||||
|
||||
//! Simpler but slower overload.
|
||||
bool String(const Ch* str) { return String(str, internal::StrLen(str)); }
|
||||
bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); }
|
||||
template <typename T>
|
||||
RAPIDJSON_ENABLEIF_RETURN((internal::IsSame<Ch, T>), (bool)) String(const T* const& str) { return String(str, internal::StrLen(str)); }
|
||||
template <typename T>
|
||||
RAPIDJSON_ENABLEIF_RETURN((internal::IsSame<Ch, T>), (bool)) Key(const T* const& str) { return Key(str, internal::StrLen(str)); }
|
||||
|
||||
//! The compiler can give us the length of quoted strings for free.
|
||||
template <typename T, size_t N>
|
||||
RAPIDJSON_ENABLEIF_RETURN((internal::IsSame<Ch, T>), (bool)) String(const T (&str)[N]) {
|
||||
RAPIDJSON_ASSERT(str[N-1] == '\0'); // you must pass in a null-terminated string (quoted constant strings are always null-terminated)
|
||||
return String(str, N-1);
|
||||
}
|
||||
template <typename T, size_t N>
|
||||
RAPIDJSON_ENABLEIF_RETURN((internal::IsSame<Ch, T>), (bool)) Key(const T (&str)[N]) {
|
||||
RAPIDJSON_ASSERT(str[N-1] == '\0'); // you must pass in a null-terminated string (quoted constant strings are always null-terminated)
|
||||
return Key(str, N-1);
|
||||
}
|
||||
|
||||
//@}
|
||||
|
||||
|
@ -79,7 +79,7 @@ add_test(NAME unittest
|
||||
if(NOT MSVC)
|
||||
# Not running SIMD.* unit test cases for Valgrind
|
||||
add_test(NAME valgrind_unittest
|
||||
COMMAND valgrind --leak-check=full --error-exitcode=1 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/unittest --gtest_filter=-SIMD.*
|
||||
COMMAND valgrind --suppressions=${CMAKE_SOURCE_DIR}/test/valgrind.supp --leak-check=full --error-exitcode=1 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/unittest --gtest_filter=-SIMD.*
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
|
@ -207,6 +207,57 @@ TEST(PrettyWriter, RawValue) {
|
||||
buffer.GetString());
|
||||
}
|
||||
|
||||
TEST(PrettyWriter, InvalidEventSequence) {
|
||||
// {]
|
||||
{
|
||||
StringBuffer buffer;
|
||||
PrettyWriter<StringBuffer> writer(buffer);
|
||||
writer.StartObject();
|
||||
EXPECT_THROW(writer.EndArray(), AssertException);
|
||||
EXPECT_FALSE(writer.IsComplete());
|
||||
}
|
||||
|
||||
// [}
|
||||
{
|
||||
StringBuffer buffer;
|
||||
PrettyWriter<StringBuffer> writer(buffer);
|
||||
writer.StartArray();
|
||||
EXPECT_THROW(writer.EndObject(), AssertException);
|
||||
EXPECT_FALSE(writer.IsComplete());
|
||||
}
|
||||
|
||||
// { 1:
|
||||
{
|
||||
StringBuffer buffer;
|
||||
PrettyWriter<StringBuffer> writer(buffer);
|
||||
writer.StartObject();
|
||||
EXPECT_THROW(writer.Int(1), AssertException);
|
||||
EXPECT_FALSE(writer.IsComplete());
|
||||
}
|
||||
|
||||
// { 'a' }
|
||||
{
|
||||
StringBuffer buffer;
|
||||
PrettyWriter<StringBuffer> writer(buffer);
|
||||
writer.StartObject();
|
||||
writer.Key("a");
|
||||
EXPECT_THROW(writer.EndObject(), AssertException);
|
||||
EXPECT_FALSE(writer.IsComplete());
|
||||
}
|
||||
|
||||
// { 'a':'b','c' }
|
||||
{
|
||||
StringBuffer buffer;
|
||||
PrettyWriter<StringBuffer> writer(buffer);
|
||||
writer.StartObject();
|
||||
writer.Key("a");
|
||||
writer.String("b");
|
||||
writer.Key("c");
|
||||
EXPECT_THROW(writer.EndObject(), AssertException);
|
||||
EXPECT_FALSE(writer.IsComplete());
|
||||
}
|
||||
}
|
||||
|
||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||
|
||||
static PrettyWriter<StringBuffer> WriterGen(StringBuffer &target) {
|
||||
|
@ -1281,6 +1281,12 @@ TEST(SchemaValidatingWriter, Simple) {
|
||||
EXPECT_TRUE(validator.GetInvalidDocumentPointer() == SchemaDocument::PointerType(""));
|
||||
}
|
||||
|
||||
TEST(Schema, Issue848) {
|
||||
rapidjson::Document d;
|
||||
rapidjson::SchemaDocument s(d);
|
||||
rapidjson::GenericSchemaValidator<rapidjson::SchemaDocument, rapidjson::Document> v(s);
|
||||
}
|
||||
|
||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||
|
||||
static SchemaDocument ReturnSchemaDocument() {
|
||||
|
@ -442,6 +442,28 @@ TEST(Writer, InvalidEventSequence) {
|
||||
EXPECT_THROW(writer.Int(1), AssertException);
|
||||
EXPECT_FALSE(writer.IsComplete());
|
||||
}
|
||||
|
||||
// { 'a' }
|
||||
{
|
||||
StringBuffer buffer;
|
||||
Writer<StringBuffer> writer(buffer);
|
||||
writer.StartObject();
|
||||
writer.Key("a");
|
||||
EXPECT_THROW(writer.EndObject(), AssertException);
|
||||
EXPECT_FALSE(writer.IsComplete());
|
||||
}
|
||||
|
||||
// { 'a':'b','c' }
|
||||
{
|
||||
StringBuffer buffer;
|
||||
Writer<StringBuffer> writer(buffer);
|
||||
writer.StartObject();
|
||||
writer.Key("a");
|
||||
writer.String("b");
|
||||
writer.Key("c");
|
||||
EXPECT_THROW(writer.EndObject(), AssertException);
|
||||
EXPECT_FALSE(writer.IsComplete());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Writer, NaN) {
|
||||
|
17
test/valgrind.supp
Normal file
17
test/valgrind.supp
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
Suppress wcslen valgrind report 1
|
||||
Memcheck:Cond
|
||||
fun:__wcslen_sse2
|
||||
}
|
||||
|
||||
{
|
||||
Suppress wcslen valgrind report 2
|
||||
Memcheck:Addr8
|
||||
fun:__wcslen_sse2
|
||||
}
|
||||
|
||||
{
|
||||
Suppress wcslen valgrind report 3
|
||||
Memcheck:Value8
|
||||
fun:__wcslen_sse2
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user