Compare commits
4 Commits
master
...
clang-form
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c237489a6c | ||
|
|
3c75d4d612 | ||
|
|
e61dbc5e88 | ||
|
|
7d6901bff2 |
12
.clang-format
Normal file
12
.clang-format
Normal file
@ -0,0 +1,12 @@
|
||||
Standard: Cpp03
|
||||
UseTab: ForIndentation
|
||||
TabWidth: 4
|
||||
IndentWidth: 4
|
||||
AccessModifierOffset: -4
|
||||
BreakBeforeBraces: Allman
|
||||
IndentCaseLabels: false
|
||||
ColumnLimit: 0
|
||||
PointerAlignment: Left
|
||||
BreakConstructorInitializersBeforeComma: true
|
||||
NamespaceIndentation: None
|
||||
AlignEscapedNewlines: DontAlign
|
||||
3
Makefile
3
Makefile
@ -74,6 +74,9 @@ release: build/pugixml-$(VERSION).tar.gz build/pugixml-$(VERSION).zip
|
||||
|
||||
docs: docs/quickstart.html docs/manual.html
|
||||
|
||||
format:
|
||||
clang-format -i src/*.cpp src/*.hpp tests/*.cpp tests/*.hpp
|
||||
|
||||
build/pugixml-%: .FORCE | $(RELEASE)
|
||||
@mkdir -p $(BUILD)
|
||||
TIMESTAMP=`git show v$(VERSION) -s --format=%ct` && python scripts/archive.py $@ pugixml-$(VERSION) $$TIMESTAMP $|
|
||||
|
||||
6197
src/pugixml.cpp
6197
src/pugixml.cpp
File diff suppressed because it is too large
Load Diff
748
src/pugixml.hpp
748
src/pugixml.hpp
File diff suppressed because it is too large
Load Diff
@ -1,49 +1,49 @@
|
||||
#include "allocator.hpp"
|
||||
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// Address sanitizer
|
||||
#if defined(__has_feature)
|
||||
# define ADDRESS_SANITIZER __has_feature(address_sanitizer)
|
||||
#define ADDRESS_SANITIZER __has_feature(address_sanitizer)
|
||||
#else
|
||||
# if defined(__SANITIZE_ADDRESS__)
|
||||
# define ADDRESS_SANITIZER 1
|
||||
# else
|
||||
# define ADDRESS_SANITIZER 0
|
||||
# endif
|
||||
#if defined(__SANITIZE_ADDRESS__)
|
||||
#define ADDRESS_SANITIZER 1
|
||||
#else
|
||||
#define ADDRESS_SANITIZER 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Low-level allocation functions
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
# ifdef __MWERKS__
|
||||
# pragma ANSI_strict off // disable ANSI strictness to include windows.h
|
||||
# pragma cpp_extensions on // enable some extensions to include windows.h
|
||||
# endif
|
||||
#ifdef __MWERKS__
|
||||
#pragma ANSI_strict off // disable ANSI strictness to include windows.h
|
||||
#pragma cpp_extensions on // enable some extensions to include windows.h
|
||||
#endif
|
||||
|
||||
# if defined(_MSC_VER)
|
||||
# pragma warning(disable: 4201) // nonstandard extension used: nameless struct/union
|
||||
# endif
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(disable : 4201) // nonstandard extension used: nameless struct/union
|
||||
#endif
|
||||
|
||||
# ifdef _XBOX_VER
|
||||
# define NOD3D
|
||||
# include <xtl.h>
|
||||
# else
|
||||
# include <windows.h>
|
||||
# endif
|
||||
#ifdef _XBOX_VER
|
||||
#define NOD3D
|
||||
#include <xtl.h>
|
||||
#else
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
const size_t page_size = 4096;
|
||||
const size_t page_size = 4096;
|
||||
|
||||
size_t align_to_page(size_t value)
|
||||
{
|
||||
size_t align_to_page(size_t value)
|
||||
{
|
||||
return (value + page_size - 1) & ~(page_size - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void* allocate_page_aligned(size_t size)
|
||||
{
|
||||
void* allocate_page_aligned(size_t size)
|
||||
{
|
||||
// We can't use VirtualAlloc because it has 64Kb granularity so we run out of address space quickly
|
||||
// We can't use malloc because of occasional problems with CW on CRT termination
|
||||
static HANDLE heap = HeapCreate(0, 0, 0);
|
||||
@ -51,14 +51,15 @@ namespace
|
||||
void* result = HeapAlloc(heap, 0, size + page_size);
|
||||
|
||||
return reinterpret_cast<void*>(align_to_page(reinterpret_cast<size_t>(result)));
|
||||
}
|
||||
}
|
||||
|
||||
void* allocate(size_t size)
|
||||
{
|
||||
void* allocate(size_t size)
|
||||
{
|
||||
size_t aligned_size = align_to_page(size);
|
||||
|
||||
void* ptr = allocate_page_aligned(aligned_size + page_size);
|
||||
if (!ptr) return 0;
|
||||
if (!ptr)
|
||||
return 0;
|
||||
|
||||
char* end = static_cast<char*>(ptr) + aligned_size;
|
||||
|
||||
@ -66,43 +67,44 @@ namespace
|
||||
VirtualProtect(end, page_size, PAGE_NOACCESS, &old_flags);
|
||||
|
||||
return end - size;
|
||||
}
|
||||
}
|
||||
|
||||
void deallocate(void* ptr, size_t size)
|
||||
{
|
||||
void deallocate(void* ptr, size_t size)
|
||||
{
|
||||
size_t aligned_size = align_to_page(size);
|
||||
|
||||
void* rptr = static_cast<char*>(ptr) + size - aligned_size;
|
||||
|
||||
DWORD old_flags;
|
||||
VirtualProtect(rptr, aligned_size + page_size, PAGE_NOACCESS, &old_flags);
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
#elif (defined(__APPLE__) || defined(__linux__)) && (defined(__i386) || defined(__x86_64)) && !ADDRESS_SANITIZER
|
||||
# include <sys/mman.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
const size_t page_size = 4096;
|
||||
const size_t page_size = 4096;
|
||||
|
||||
size_t align_to_page(size_t value)
|
||||
{
|
||||
size_t align_to_page(size_t value)
|
||||
{
|
||||
return (value + page_size - 1) & ~(page_size - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void* allocate_page_aligned(size_t size)
|
||||
{
|
||||
void* allocate_page_aligned(size_t size)
|
||||
{
|
||||
void* result = malloc(size + page_size);
|
||||
|
||||
return reinterpret_cast<void*>(align_to_page(reinterpret_cast<size_t>(result)));
|
||||
}
|
||||
}
|
||||
|
||||
void* allocate(size_t size)
|
||||
{
|
||||
void* allocate(size_t size)
|
||||
{
|
||||
size_t aligned_size = align_to_page(size);
|
||||
|
||||
void* ptr = allocate_page_aligned(aligned_size + page_size);
|
||||
if (!ptr) return 0;
|
||||
if (!ptr)
|
||||
return 0;
|
||||
|
||||
char* end = static_cast<char*>(ptr) + aligned_size;
|
||||
|
||||
@ -111,10 +113,10 @@ namespace
|
||||
(void)!res;
|
||||
|
||||
return end - size;
|
||||
}
|
||||
}
|
||||
|
||||
void deallocate(void* ptr, size_t size)
|
||||
{
|
||||
void deallocate(void* ptr, size_t size)
|
||||
{
|
||||
size_t aligned_size = align_to_page(size);
|
||||
|
||||
void* rptr = static_cast<char*>(ptr) + size - aligned_size;
|
||||
@ -122,23 +124,23 @@ namespace
|
||||
int res = mprotect(rptr, aligned_size + page_size, PROT_NONE);
|
||||
assert(res == 0);
|
||||
(void)!res;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
#else
|
||||
namespace
|
||||
{
|
||||
void* allocate(size_t size)
|
||||
{
|
||||
void* allocate(size_t size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
}
|
||||
|
||||
void deallocate(void* ptr, size_t size)
|
||||
{
|
||||
void deallocate(void* ptr, size_t size)
|
||||
{
|
||||
(void)size;
|
||||
|
||||
free(ptr);
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
#endif
|
||||
|
||||
// High-level allocation functions
|
||||
@ -147,7 +149,8 @@ const size_t memory_alignment = sizeof(double) > sizeof(void*) ? sizeof(double)
|
||||
void* memory_allocate(size_t size)
|
||||
{
|
||||
void* result = allocate(size + memory_alignment);
|
||||
if (!result) return 0;
|
||||
if (!result)
|
||||
return 0;
|
||||
|
||||
memcpy(result, &size, sizeof(size_t));
|
||||
|
||||
@ -166,10 +169,10 @@ size_t memory_size(void* ptr)
|
||||
|
||||
void memory_deallocate(void* ptr)
|
||||
{
|
||||
if (!ptr) return;
|
||||
if (!ptr)
|
||||
return;
|
||||
|
||||
size_t size = memory_size(ptr);
|
||||
|
||||
deallocate(static_cast<char*>(ptr) - memory_alignment, size + memory_alignment);
|
||||
}
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size)
|
||||
{
|
||||
pugi::xml_document doc;
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size)
|
||||
{
|
||||
char* text = new char[Size + 1];
|
||||
memcpy(text, Data, Size);
|
||||
|
||||
@ -5,7 +5,8 @@
|
||||
|
||||
#include <utility>
|
||||
|
||||
template <typename T> static void generic_bool_ops_test(const T& obj)
|
||||
template <typename T>
|
||||
static void generic_bool_ops_test(const T& obj)
|
||||
{
|
||||
T null;
|
||||
|
||||
@ -14,14 +15,14 @@ template <typename T> static void generic_bool_ops_test(const T& obj)
|
||||
CHECK(!!obj);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4800) // forcing value to bool 'true' or 'false' (performance warning) - we really want to just cast to bool instead of !!
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4800) // forcing value to bool 'true' or 'false' (performance warning) - we really want to just cast to bool instead of !!
|
||||
#endif
|
||||
|
||||
bool b1 = null, b2 = obj;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(pop)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
CHECK(!b1);
|
||||
@ -33,7 +34,8 @@ template <typename T> static void generic_bool_ops_test(const T& obj)
|
||||
CHECK(obj || obj);
|
||||
}
|
||||
|
||||
template <typename T> static void generic_eq_ops_test(const T& obj1, const T& obj2)
|
||||
template <typename T>
|
||||
static void generic_eq_ops_test(const T& obj1, const T& obj2)
|
||||
{
|
||||
T null = T();
|
||||
|
||||
@ -54,7 +56,8 @@ template <typename T> static void generic_eq_ops_test(const T& obj1, const T& ob
|
||||
CHECK(!(T(obj1) != obj1));
|
||||
}
|
||||
|
||||
template <typename T> static void generic_rel_ops_test(T obj1, T obj2)
|
||||
template <typename T>
|
||||
static void generic_rel_ops_test(T obj1, T obj2)
|
||||
{
|
||||
T null = T();
|
||||
|
||||
@ -103,7 +106,8 @@ template <typename T> static void generic_rel_ops_test(T obj1, T obj2)
|
||||
CHECK(!(obj1 >= obj2));
|
||||
}
|
||||
|
||||
template <typename T> static void generic_empty_test(const T& obj)
|
||||
template <typename T>
|
||||
static void generic_empty_test(const T& obj)
|
||||
{
|
||||
T null;
|
||||
|
||||
|
||||
@ -1,21 +1,21 @@
|
||||
#include "test.hpp"
|
||||
#include "allocator.hpp"
|
||||
#include "test.hpp"
|
||||
|
||||
#include <assert.h>
|
||||
#include <float.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <float.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#ifndef PUGIXML_NO_EXCEPTIONS
|
||||
# include <exception>
|
||||
#include <exception>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
# undef DebugBreak
|
||||
# pragma warning(disable: 4201) // nonstandard extension used: nameless struct/union
|
||||
# include <windows.h>
|
||||
#undef DebugBreak
|
||||
#pragma warning(disable : 4201) // nonstandard extension used: nameless struct/union
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
test_runner* test_runner::_tests = 0;
|
||||
@ -41,7 +41,8 @@ static void* custom_allocate(size_t size)
|
||||
else
|
||||
{
|
||||
void* ptr = memory_allocate(size);
|
||||
if (!ptr) return 0;
|
||||
if (!ptr)
|
||||
return 0;
|
||||
|
||||
g_memory_total_size += memory_size(ptr);
|
||||
g_memory_total_count++;
|
||||
@ -89,9 +90,9 @@ static void replace_memory_management()
|
||||
|
||||
namespace std
|
||||
{
|
||||
_CRTIMP2 _Prhand _Raise_handler;
|
||||
_CRTIMP2 void __cdecl _Throw(const exception&) {}
|
||||
}
|
||||
_CRTIMP2 _Prhand _Raise_handler;
|
||||
_CRTIMP2 void __cdecl _Throw(const exception&) {}
|
||||
} // namespace std
|
||||
#endif
|
||||
|
||||
static bool run_test(test_runner* test, const char* test_name, pugi::allocation_function allocate)
|
||||
@ -109,15 +110,15 @@ static bool run_test(test_runner* test, const char* test_name, pugi::allocation_
|
||||
pugi::set_memory_management_functions(allocate, custom_deallocate);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4611) // interaction between _setjmp and C++ object destruction is non-portable
|
||||
# pragma warning(disable: 4793) // function compiled as native: presence of '_setjmp' makes a function unmanaged
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4611) // interaction between _setjmp and C++ object destruction is non-portable
|
||||
#pragma warning(disable : 4793) // function compiled as native: presence of '_setjmp' makes a function unmanaged
|
||||
#endif
|
||||
|
||||
volatile int result = setjmp(test_runner::_failure_buffer);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(pop)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
if (result)
|
||||
@ -193,10 +194,10 @@ int main(int, char** argv)
|
||||
if (g_memory_fail_triggered)
|
||||
{
|
||||
// run tests that trigger memory failures twice - with an allocator that returns NULL and with an allocator that throws
|
||||
#ifndef PUGIXML_NO_EXCEPTIONS
|
||||
#ifndef PUGIXML_NO_EXCEPTIONS
|
||||
total++;
|
||||
passed += run_test(test, (test->_name + std::string(" (throw)")).c_str(), custom_allocate_throw);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
|
||||
#include "writer_string.hpp"
|
||||
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
|
||||
@ -33,10 +33,12 @@ static void build_document_order(std::vector<pugi::xpath_node>& result, pugi::xm
|
||||
cur = cur.next_sibling();
|
||||
else
|
||||
{
|
||||
while (cur && !cur.next_sibling()) cur = cur.parent();
|
||||
while (cur && !cur.next_sibling())
|
||||
cur = cur.parent();
|
||||
cur = cur.next_sibling();
|
||||
|
||||
if (!cur) break;
|
||||
if (!cur)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -45,11 +47,11 @@ static void build_document_order(std::vector<pugi::xpath_node>& result, pugi::xm
|
||||
bool test_string_equal(const pugi::char_t* lhs, const pugi::char_t* rhs)
|
||||
{
|
||||
return (!lhs || !rhs) ? lhs == rhs :
|
||||
#ifdef PUGIXML_WCHAR_MODE
|
||||
#ifdef PUGIXML_WCHAR_MODE
|
||||
wcscmp(lhs, rhs) == 0;
|
||||
#else
|
||||
#else
|
||||
strcmp(lhs, rhs) == 0;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
bool test_node(const pugi::xml_node& node, const pugi::char_t* contents, const pugi::char_t* indent, unsigned int flags)
|
||||
@ -83,7 +85,8 @@ static size_t strlength(const pugi::char_t* s)
|
||||
bool test_xpath_string(const pugi::xpath_node& node, const pugi::char_t* query, pugi::xpath_variable_set* variables, const pugi::char_t* expected)
|
||||
{
|
||||
pugi::xpath_query q(query, variables);
|
||||
if (!q) return false;
|
||||
if (!q)
|
||||
return false;
|
||||
|
||||
const size_t capacity = 64;
|
||||
pugi::char_t result[capacity];
|
||||
@ -104,7 +107,8 @@ bool test_xpath_string(const pugi::xpath_node& node, const pugi::char_t* query,
|
||||
bool test_xpath_boolean(const pugi::xpath_node& node, const pugi::char_t* query, pugi::xpath_variable_set* variables, bool expected)
|
||||
{
|
||||
pugi::xpath_query q(query, variables);
|
||||
if (!q) return false;
|
||||
if (!q)
|
||||
return false;
|
||||
|
||||
return q.evaluate_boolean(node) == expected;
|
||||
}
|
||||
@ -112,7 +116,8 @@ bool test_xpath_boolean(const pugi::xpath_node& node, const pugi::char_t* query,
|
||||
bool test_xpath_number(const pugi::xpath_node& node, const pugi::char_t* query, pugi::xpath_variable_set* variables, double expected)
|
||||
{
|
||||
pugi::xpath_query q(query, variables);
|
||||
if (!q) return false;
|
||||
if (!q)
|
||||
return false;
|
||||
|
||||
double value = q.evaluate_number(node);
|
||||
double absolute_error = fabs(value - expected);
|
||||
@ -124,7 +129,8 @@ bool test_xpath_number(const pugi::xpath_node& node, const pugi::char_t* query,
|
||||
bool test_xpath_number_nan(const pugi::xpath_node& node, const pugi::char_t* query, pugi::xpath_variable_set* variables)
|
||||
{
|
||||
pugi::xpath_query q(query, variables);
|
||||
if (!q) return false;
|
||||
if (!q)
|
||||
return false;
|
||||
|
||||
return test_double_nan(q.evaluate_number(node));
|
||||
}
|
||||
@ -155,12 +161,15 @@ void xpath_node_set_tester::check(bool condition)
|
||||
}
|
||||
}
|
||||
|
||||
xpath_node_set_tester::xpath_node_set_tester(const pugi::xpath_node_set& set, const char* message_): last(0), message(message_)
|
||||
xpath_node_set_tester::xpath_node_set_tester(const pugi::xpath_node_set& set, const char* message_)
|
||||
: last(0)
|
||||
, message(message_)
|
||||
{
|
||||
result = set;
|
||||
|
||||
// only sort unsorted sets so that we're able to verify reverse order for some axes
|
||||
if (result.type() == pugi::xpath_node_set::type_unsorted) result.sort();
|
||||
if (result.type() == pugi::xpath_node_set::type_unsorted)
|
||||
result.sort();
|
||||
|
||||
if (result.empty())
|
||||
{
|
||||
|
||||
@ -36,7 +36,8 @@ struct test_runner
|
||||
|
||||
bool test_string_equal(const pugi::char_t* lhs, const pugi::char_t* rhs);
|
||||
|
||||
template <typename Node> inline bool test_node_name_value(const Node& node, const pugi::char_t* name, const pugi::char_t* value)
|
||||
template <typename Node>
|
||||
inline bool test_node_name_value(const Node& node, const pugi::char_t* name, const pugi::char_t* value)
|
||||
{
|
||||
return test_string_equal(node.name(), name) && test_string_equal(node.value(), value);
|
||||
}
|
||||
@ -71,17 +72,22 @@ struct xpath_node_set_tester
|
||||
|
||||
#endif
|
||||
|
||||
struct dummy_fixture {};
|
||||
struct dummy_fixture
|
||||
{
|
||||
};
|
||||
|
||||
#define TEST_FIXTURE(name, fixture) \
|
||||
struct test_runner_helper_##name: fixture \
|
||||
struct test_runner_helper_##name : fixture \
|
||||
{ \
|
||||
void run(); \
|
||||
}; \
|
||||
static struct test_runner_##name: test_runner \
|
||||
static struct test_runner_##name : test_runner \
|
||||
{ \
|
||||
test_runner_##name(): test_runner(#name) {} \
|
||||
\
|
||||
test_runner_##name() \
|
||||
: test_runner(#name) \
|
||||
{ \
|
||||
} \
|
||||
\
|
||||
virtual void run() PUGIXML_OVERRIDE \
|
||||
{ \
|
||||
test_runner_helper_##name helper; \
|
||||
@ -96,30 +102,34 @@ struct dummy_fixture {};
|
||||
struct test_fixture_##name \
|
||||
{ \
|
||||
pugi::xml_document doc; \
|
||||
\
|
||||
\
|
||||
test_fixture_##name() \
|
||||
{ \
|
||||
CHECK(doc.load_string(PUGIXML_TEXT(xml), flags)); \
|
||||
} \
|
||||
\
|
||||
\
|
||||
private: \
|
||||
test_fixture_##name(const test_fixture_##name&); \
|
||||
test_fixture_##name& operator=(const test_fixture_##name&); \
|
||||
}; \
|
||||
\
|
||||
\
|
||||
TEST_FIXTURE(name, test_fixture_##name)
|
||||
|
||||
#define TEST_XML(name, xml) TEST_XML_FLAGS(name, xml, pugi::parse_default)
|
||||
|
||||
#define CHECK_JOIN(text, file, line) text " at " file ":" #line
|
||||
#define CHECK_JOIN2(text, file, line) CHECK_JOIN(text, file, line)
|
||||
#define CHECK_TEXT(condition, text) if (condition) ; else test_runner::_failure_message = CHECK_JOIN2(text, __FILE__, __LINE__), longjmp(test_runner::_failure_buffer, 1)
|
||||
#define CHECK_TEXT(condition, text) \
|
||||
if (condition) \
|
||||
; \
|
||||
else \
|
||||
test_runner::_failure_message = CHECK_JOIN2(text, __FILE__, __LINE__), longjmp(test_runner::_failure_buffer, 1)
|
||||
#define CHECK_FORCE_FAIL(text) test_runner::_failure_message = CHECK_JOIN2(text, __FILE__, __LINE__), longjmp(test_runner::_failure_buffer, 1)
|
||||
|
||||
#if (defined(_MSC_VER) && _MSC_VER == 1200) || defined(__MWERKS__) || (defined(__BORLANDC__) && __BORLANDC__ <= 0x540)
|
||||
# define STRINGIZE(value) "??" // Some compilers have issues with stringizing expressions that contain strings w/escaping inside
|
||||
#define STRINGIZE(value) "??" // Some compilers have issues with stringizing expressions that contain strings w/escaping inside
|
||||
#else
|
||||
# define STRINGIZE(value) #value
|
||||
#define STRINGIZE(value) #value
|
||||
#endif
|
||||
|
||||
#define CHECK(condition) CHECK_TEXT(condition, STRINGIZE(condition) " is false")
|
||||
@ -147,9 +157,29 @@ struct dummy_fixture {};
|
||||
#endif
|
||||
|
||||
#ifdef PUGIXML_NO_EXCEPTIONS
|
||||
#define CHECK_ALLOC_FAIL(code) do { CHECK(!test_runner::_memory_fail_triggered); code; CHECK(test_runner::_memory_fail_triggered); test_runner::_memory_fail_triggered = false; } while (test_runner::_memory_fail_triggered)
|
||||
#define CHECK_ALLOC_FAIL(code) \
|
||||
do \
|
||||
{ \
|
||||
CHECK(!test_runner::_memory_fail_triggered); \
|
||||
code; \
|
||||
CHECK(test_runner::_memory_fail_triggered); \
|
||||
test_runner::_memory_fail_triggered = false; \
|
||||
} while (test_runner::_memory_fail_triggered)
|
||||
#else
|
||||
#define CHECK_ALLOC_FAIL(code) do { CHECK(!test_runner::_memory_fail_triggered); try { code; } catch (std::bad_alloc&) {} CHECK(test_runner::_memory_fail_triggered); test_runner::_memory_fail_triggered = false; } while (test_runner::_memory_fail_triggered)
|
||||
#define CHECK_ALLOC_FAIL(code) \
|
||||
do \
|
||||
{ \
|
||||
CHECK(!test_runner::_memory_fail_triggered); \
|
||||
try \
|
||||
{ \
|
||||
code; \
|
||||
} \
|
||||
catch (std::bad_alloc&) \
|
||||
{ \
|
||||
} \
|
||||
CHECK(test_runner::_memory_fail_triggered); \
|
||||
test_runner::_memory_fail_triggered = false; \
|
||||
} while (test_runner::_memory_fail_triggered)
|
||||
#endif
|
||||
|
||||
#define STR(text) PUGIXML_TEXT(text)
|
||||
@ -161,7 +191,7 @@ struct dummy_fixture {};
|
||||
#if (defined(_MSC_VER) && _MSC_VER == 1200) || (defined(__INTEL_COMPILER) && __INTEL_COMPILER == 800) || defined(__BORLANDC__)
|
||||
// NaN comparison on MSVC6 is incorrect, see http://www.nabble.com/assertDoubleEquals,-NaN---Microsoft-Visual-Studio-6-td9137859.html
|
||||
// IC8 and BCC are also affected by the same bug
|
||||
# define MSVC6_NAN_BUG
|
||||
#define MSVC6_NAN_BUG
|
||||
#endif
|
||||
|
||||
inline wchar_t wchar_cast(unsigned int value)
|
||||
|
||||
@ -15,19 +15,19 @@
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
#ifndef PUGIXML_NO_EXCEPTIONS
|
||||
# include <stdexcept>
|
||||
#include <stdexcept>
|
||||
#endif
|
||||
|
||||
#ifdef __MINGW32__
|
||||
# include <io.h> // for unlink in C++0x mode
|
||||
#include <io.h> // for unlink in C++0x mode
|
||||
#endif
|
||||
|
||||
#if defined(__CELLOS_LV2__) || defined(ANDROID) || defined(_GLIBCXX_HAVE_UNISTD_H) || defined(__APPLE__)
|
||||
# include <unistd.h> // for unlink
|
||||
#include <unistd.h> // for unlink
|
||||
#endif
|
||||
|
||||
using namespace pugi;
|
||||
@ -35,7 +35,8 @@ using namespace pugi;
|
||||
static bool load_file_in_memory(const char* path, char*& data, size_t& size)
|
||||
{
|
||||
FILE* file = fopen(path, "rb");
|
||||
if (!file) return false;
|
||||
if (!file)
|
||||
return false;
|
||||
|
||||
fseek(file, 0, SEEK_END);
|
||||
long length = ftell(file);
|
||||
@ -55,7 +56,8 @@ static bool test_file_contents(const char* path, const char* data, size_t size)
|
||||
{
|
||||
char* fdata;
|
||||
size_t fsize;
|
||||
if (!load_file_in_memory(path, fdata, fsize)) return false;
|
||||
if (!load_file_in_memory(path, fdata, fsize))
|
||||
return false;
|
||||
|
||||
bool result = (size == fsize && memcmp(data, fdata, size) == 0);
|
||||
|
||||
@ -199,7 +201,8 @@ TEST(document_load_stream_wide_error_previous)
|
||||
CHECK(!doc.first_child());
|
||||
}
|
||||
|
||||
template <typename T> class char_array_buffer: public std::basic_streambuf<T>
|
||||
template <typename T>
|
||||
class char_array_buffer : public std::basic_streambuf<T>
|
||||
{
|
||||
public:
|
||||
char_array_buffer(T* begin, T* end)
|
||||
@ -234,7 +237,8 @@ TEST(document_load_stream_nonseekable_large)
|
||||
{
|
||||
std::basic_string<char_t> str;
|
||||
str += STR("<node>");
|
||||
for (int i = 0; i < 10000; ++i) str += STR("<node/>");
|
||||
for (int i = 0; i < 10000; ++i)
|
||||
str += STR("<node/>");
|
||||
str += STR("</node>");
|
||||
|
||||
char_array_buffer<char_t> buffer(&str[0], &str[0] + str.length());
|
||||
@ -273,7 +277,8 @@ TEST(document_load_stream_nonseekable_out_of_memory_large)
|
||||
{
|
||||
std::basic_string<char> str;
|
||||
str += "<node>";
|
||||
for (int i = 0; i < 10000; ++i) str += "<node />";
|
||||
for (int i = 0; i < 10000; ++i)
|
||||
str += "<node />";
|
||||
str += "</node>";
|
||||
|
||||
char_array_buffer<char> buffer(&str[0], &str[0] + str.length());
|
||||
@ -289,7 +294,8 @@ TEST(document_load_stream_wide_nonseekable_out_of_memory_large)
|
||||
{
|
||||
std::basic_string<wchar_t> str;
|
||||
str += L"<node>";
|
||||
for (int i = 0; i < 10000; ++i) str += L"<node />";
|
||||
for (int i = 0; i < 10000; ++i)
|
||||
str += L"<node />";
|
||||
str += L"</node>";
|
||||
|
||||
char_array_buffer<wchar_t> buffer(&str[0], &str[0] + str.length());
|
||||
@ -301,12 +307,14 @@ TEST(document_load_stream_wide_nonseekable_out_of_memory_large)
|
||||
CHECK_ALLOC_FAIL(CHECK(doc.load(in).status == status_out_of_memory));
|
||||
}
|
||||
|
||||
template <typename T> class seek_fail_buffer: public std::basic_streambuf<T>
|
||||
template <typename T>
|
||||
class seek_fail_buffer : public std::basic_streambuf<T>
|
||||
{
|
||||
public:
|
||||
int seeks;
|
||||
|
||||
seek_fail_buffer(): seeks(0)
|
||||
seek_fail_buffer()
|
||||
: seeks(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -337,12 +345,14 @@ TEST(document_load_stream_wide_seekable_fail_seek)
|
||||
CHECK(doc.load(in).status == status_io_error);
|
||||
}
|
||||
|
||||
template <typename T> class tell_fail_buffer: public std::basic_streambuf<T>
|
||||
template <typename T>
|
||||
class tell_fail_buffer : public std::basic_streambuf<T>
|
||||
{
|
||||
public:
|
||||
int seeks;
|
||||
|
||||
tell_fail_buffer(): seeks(0)
|
||||
tell_fail_buffer()
|
||||
: seeks(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -378,16 +388,17 @@ TEST(document_load_stream_wide_seekable_fail_tell)
|
||||
}
|
||||
|
||||
#ifndef PUGIXML_NO_EXCEPTIONS
|
||||
template <typename T> class read_fail_buffer: public std::basic_streambuf<T>
|
||||
template <typename T>
|
||||
class read_fail_buffer : public std::basic_streambuf<T>
|
||||
{
|
||||
public:
|
||||
typename std::basic_streambuf<T>::int_type underflow() PUGIXML_OVERRIDE
|
||||
{
|
||||
throw std::runtime_error("underflow failed");
|
||||
|
||||
#ifdef __DMC__
|
||||
#ifdef __DMC__
|
||||
return 0;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
@ -409,12 +420,14 @@ TEST(document_load_stream_wide_nonseekable_fail_read)
|
||||
CHECK(doc.load(in).status == status_io_error);
|
||||
}
|
||||
|
||||
template <typename T> class read_fail_seekable_buffer: public std::basic_streambuf<T>
|
||||
template <typename T>
|
||||
class read_fail_seekable_buffer : public std::basic_streambuf<T>
|
||||
{
|
||||
public:
|
||||
typename std::basic_streambuf<T>::pos_type offset;
|
||||
|
||||
read_fail_seekable_buffer(): offset(0)
|
||||
read_fail_seekable_buffer()
|
||||
: offset(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -422,19 +435,25 @@ public:
|
||||
{
|
||||
throw std::runtime_error("underflow failed");
|
||||
|
||||
#ifdef __DMC__
|
||||
#ifdef __DMC__
|
||||
return 0;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
typename std::basic_streambuf<T>::pos_type seekoff(typename std::basic_streambuf<T>::off_type off, std::ios_base::seekdir dir, std::ios_base::openmode) PUGIXML_OVERRIDE
|
||||
{
|
||||
switch (dir)
|
||||
{
|
||||
case std::ios_base::beg: offset = off; break;
|
||||
case std::ios_base::cur: offset += off; break;
|
||||
case std::ios_base::end: offset = 16 + off; break;
|
||||
default: ;
|
||||
case std::ios_base::beg:
|
||||
offset = off;
|
||||
break;
|
||||
case std::ios_base::cur:
|
||||
offset += off;
|
||||
break;
|
||||
case std::ios_base::end:
|
||||
offset = 16 + off;
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
@ -498,7 +517,8 @@ TEST(document_load_file_large)
|
||||
|
||||
std::basic_string<char_t> str;
|
||||
str += STR("<node>");
|
||||
for (int i = 0; i < 10000; ++i) str += STR("<node/>");
|
||||
for (int i = 0; i < 10000; ++i)
|
||||
str += STR("<node/>");
|
||||
str += STR("</node>");
|
||||
|
||||
CHECK_NODE(doc, str.c_str());
|
||||
@ -744,9 +764,9 @@ struct temp_file
|
||||
|
||||
~temp_file()
|
||||
{
|
||||
#ifndef _WIN32_WCE
|
||||
#ifndef _WIN32_WCE
|
||||
CHECK(unlink(path) == 0);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
@ -941,8 +961,7 @@ TEST(document_load_file_convert_auto)
|
||||
"tests/data/utftest_utf32_le_nodecl.xml",
|
||||
"tests/data/utftest_utf8.xml",
|
||||
"tests/data/utftest_utf8_bom.xml",
|
||||
"tests/data/utftest_utf8_nodecl.xml"
|
||||
};
|
||||
"tests/data/utftest_utf8_nodecl.xml"};
|
||||
|
||||
xml_encoding encodings[] =
|
||||
{
|
||||
@ -950,8 +969,7 @@ TEST(document_load_file_convert_auto)
|
||||
encoding_utf16_le, encoding_utf16_le, encoding_utf16_le,
|
||||
encoding_utf32_be, encoding_utf32_be, encoding_utf32_be,
|
||||
encoding_utf32_le, encoding_utf32_le, encoding_utf32_le,
|
||||
encoding_utf8, encoding_utf8, encoding_utf8
|
||||
};
|
||||
encoding_utf8, encoding_utf8, encoding_utf8};
|
||||
|
||||
for (unsigned int i = 0; i < sizeof(files) / sizeof(files[0]); ++i)
|
||||
{
|
||||
@ -982,8 +1000,7 @@ TEST(document_load_file_convert_specific)
|
||||
"tests/data/utftest_utf32_le_nodecl.xml",
|
||||
"tests/data/utftest_utf8.xml",
|
||||
"tests/data/utftest_utf8_bom.xml",
|
||||
"tests/data/utftest_utf8_nodecl.xml"
|
||||
};
|
||||
"tests/data/utftest_utf8_nodecl.xml"};
|
||||
|
||||
xml_encoding encodings[] =
|
||||
{
|
||||
@ -991,8 +1008,7 @@ TEST(document_load_file_convert_specific)
|
||||
encoding_utf16_le, encoding_utf16_le, encoding_utf16_le,
|
||||
encoding_utf32_be, encoding_utf32_be, encoding_utf32_be,
|
||||
encoding_utf32_le, encoding_utf32_le, encoding_utf32_le,
|
||||
encoding_utf8, encoding_utf8, encoding_utf8
|
||||
};
|
||||
encoding_utf8, encoding_utf8, encoding_utf8};
|
||||
|
||||
for (unsigned int i = 0; i < sizeof(files) / sizeof(files[0]); ++i)
|
||||
{
|
||||
@ -1037,14 +1053,12 @@ TEST(document_load_file_convert_native_endianness)
|
||||
"tests/data/utftest_utf32_le.xml",
|
||||
"tests/data/utftest_utf32_le_bom.xml",
|
||||
"tests/data/utftest_utf32_le_nodecl.xml",
|
||||
}
|
||||
};
|
||||
}};
|
||||
|
||||
xml_encoding encodings[] =
|
||||
{
|
||||
encoding_utf16, encoding_utf16, encoding_utf16,
|
||||
encoding_utf32, encoding_utf32, encoding_utf32
|
||||
};
|
||||
encoding_utf32, encoding_utf32, encoding_utf32};
|
||||
|
||||
for (unsigned int i = 0; i < sizeof(files[0]) / sizeof(files[0][0]); ++i)
|
||||
{
|
||||
@ -1091,7 +1105,6 @@ struct file_data_t
|
||||
size_t size;
|
||||
};
|
||||
|
||||
|
||||
TEST(document_contents_preserve)
|
||||
{
|
||||
file_data_t files[] =
|
||||
@ -1100,8 +1113,7 @@ TEST(document_contents_preserve)
|
||||
{"tests/data/utftest_utf16_le_clean.xml", encoding_utf16_le, 0, 0},
|
||||
{"tests/data/utftest_utf32_be_clean.xml", encoding_utf32_be, 0, 0},
|
||||
{"tests/data/utftest_utf32_le_clean.xml", encoding_utf32_le, 0, 0},
|
||||
{"tests/data/utftest_utf8_clean.xml", encoding_utf8, 0, 0}
|
||||
};
|
||||
{"tests/data/utftest_utf8_clean.xml", encoding_utf8, 0, 0}};
|
||||
|
||||
// load files in memory
|
||||
for (unsigned int i = 0; i < sizeof(files) / sizeof(files[0]); ++i)
|
||||
@ -1135,8 +1147,7 @@ TEST(document_contents_preserve_latin1)
|
||||
file_data_t files[] =
|
||||
{
|
||||
{"tests/data/latintest_utf8.xml", encoding_utf8, 0, 0},
|
||||
{"tests/data/latintest_latin1.xml", encoding_latin1, 0, 0}
|
||||
};
|
||||
{"tests/data/latintest_latin1.xml", encoding_latin1, 0, 0}};
|
||||
|
||||
// load files in memory
|
||||
for (unsigned int i = 0; i < sizeof(files) / sizeof(files[0]); ++i)
|
||||
@ -1226,8 +1237,7 @@ TEST(document_load_buffer_empty)
|
||||
encoding_utf32_be,
|
||||
encoding_utf32,
|
||||
encoding_wchar,
|
||||
encoding_latin1
|
||||
};
|
||||
encoding_latin1};
|
||||
|
||||
char buffer[1];
|
||||
|
||||
@ -1262,8 +1272,7 @@ TEST(document_load_buffer_empty_fragment)
|
||||
encoding_utf32_be,
|
||||
encoding_utf32,
|
||||
encoding_wchar,
|
||||
encoding_latin1
|
||||
};
|
||||
encoding_latin1};
|
||||
|
||||
char buffer[1];
|
||||
|
||||
@ -1395,7 +1404,8 @@ TEST(document_load_exceptions)
|
||||
try
|
||||
{
|
||||
xml_document doc;
|
||||
if (!doc.load_string(STR("<node attribute='value"))) throw std::bad_alloc();
|
||||
if (!doc.load_string(STR("<node attribute='value")))
|
||||
throw std::bad_alloc();
|
||||
|
||||
CHECK_FORCE_FAIL("Expected parsing failure");
|
||||
}
|
||||
@ -1495,11 +1505,11 @@ TEST(document_load_buffer_utf_truncated)
|
||||
|
||||
const document_data_t data[] =
|
||||
{
|
||||
{ encoding_utf8, utf8, sizeof(utf8) },
|
||||
{ encoding_utf16_be, utf16_be, sizeof(utf16_be) },
|
||||
{ encoding_utf16_le, utf16_le, sizeof(utf16_le) },
|
||||
{ encoding_utf32_be, utf32_be, sizeof(utf32_be) },
|
||||
{ encoding_utf32_le, utf32_le, sizeof(utf32_le) },
|
||||
{encoding_utf8, utf8, sizeof(utf8)},
|
||||
{encoding_utf16_be, utf16_be, sizeof(utf16_be)},
|
||||
{encoding_utf16_le, utf16_le, sizeof(utf16_le)},
|
||||
{encoding_utf32_be, utf32_be, sizeof(utf32_be)},
|
||||
{encoding_utf32_le, utf32_le, sizeof(utf32_le)},
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < sizeof(data) / sizeof(data[0]); ++i)
|
||||
@ -1520,11 +1530,11 @@ TEST(document_load_buffer_utf_truncated)
|
||||
|
||||
const char_t* name = doc.first_child().name();
|
||||
|
||||
#ifdef PUGIXML_WCHAR_MODE
|
||||
#ifdef PUGIXML_WCHAR_MODE
|
||||
CHECK(name[0] == 0x20ac && name[1] == 0);
|
||||
#else
|
||||
#else
|
||||
CHECK_STRING(name, "\xe2\x82\xac");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1565,11 +1575,11 @@ TEST(document_load_stream_truncated)
|
||||
{
|
||||
const char_t* name = doc.first_child().name();
|
||||
|
||||
#ifdef PUGIXML_WCHAR_MODE
|
||||
#ifdef PUGIXML_WCHAR_MODE
|
||||
CHECK(name[0] == 0x20ac && name[1] == 0);
|
||||
#else
|
||||
#else
|
||||
CHECK_STRING(name, "\xe2\x82\xac");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1600,8 +1610,7 @@ TEST(document_convert_out_of_memory)
|
||||
{"tests/data/utftest_utf32_be_clean.xml", encoding_utf32_be, 0, 0},
|
||||
{"tests/data/utftest_utf32_le_clean.xml", encoding_utf32_le, 0, 0},
|
||||
{"tests/data/utftest_utf8_clean.xml", encoding_utf8, 0, 0},
|
||||
{"tests/data/latintest_latin1.xml", encoding_latin1, 0, 0}
|
||||
};
|
||||
{"tests/data/latintest_latin1.xml", encoding_latin1, 0, 0}};
|
||||
|
||||
// load files in memory
|
||||
for (unsigned int i = 0; i < sizeof(files) / sizeof(files[0]); ++i)
|
||||
@ -1761,7 +1770,7 @@ TEST(document_move_empty_zero_alloc)
|
||||
test_runner::_memory_fail_threshold = 1;
|
||||
|
||||
for (int i = 1; i < 32; ++i)
|
||||
docs[i] = std::move(docs[i-1]);
|
||||
docs[i] = std::move(docs[i - 1]);
|
||||
|
||||
delete[] docs;
|
||||
}
|
||||
@ -1776,7 +1785,7 @@ TEST(document_move_repeated_zero_alloc)
|
||||
test_runner::_memory_fail_threshold = 1;
|
||||
|
||||
for (int i = 1; i < 32; ++i)
|
||||
docs[i] = std::move(docs[i-1]);
|
||||
docs[i] = std::move(docs[i - 1]);
|
||||
|
||||
for (int i = 0; i < 31; ++i)
|
||||
CHECK(!docs[i].first_child());
|
||||
@ -1797,15 +1806,15 @@ TEST(document_move_compact_fail)
|
||||
int safe_count = 21;
|
||||
|
||||
for (int i = 1; i <= safe_count; ++i)
|
||||
docs[i] = std::move(docs[i-1]);
|
||||
docs[i] = std::move(docs[i - 1]);
|
||||
|
||||
CHECK_ALLOC_FAIL(docs[safe_count+1] = std::move(docs[safe_count]));
|
||||
CHECK_ALLOC_FAIL(docs[safe_count + 1] = std::move(docs[safe_count]));
|
||||
|
||||
for (int i = 0; i < safe_count; ++i)
|
||||
CHECK(!docs[i].first_child());
|
||||
|
||||
CHECK_NODE(docs[safe_count], STR("<node><child/></node>"));
|
||||
CHECK(!docs[safe_count+1].first_child());
|
||||
CHECK(!docs[safe_count + 1].first_child());
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -3,9 +3,9 @@
|
||||
#include <limits>
|
||||
#include <string>
|
||||
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
using namespace pugi;
|
||||
|
||||
@ -926,7 +926,8 @@ TEST(dom_string_out_of_memory)
|
||||
const unsigned int length = 65536;
|
||||
static char_t string[length + 1];
|
||||
|
||||
for (unsigned int i = 0; i < length; ++i) string[i] = 'a';
|
||||
for (unsigned int i = 0; i < length; ++i)
|
||||
string[i] = 'a';
|
||||
string[length] = 0;
|
||||
|
||||
xml_document doc;
|
||||
@ -976,8 +977,8 @@ TEST(dom_node_out_of_memory)
|
||||
xml_attribute a = n.append_attribute(STR("a"));
|
||||
CHECK(a);
|
||||
|
||||
CHECK_ALLOC_FAIL(while (n.append_child(node_comment)) { /* nop */ });
|
||||
CHECK_ALLOC_FAIL(while (n.append_attribute(STR("b"))) { /* nop */ });
|
||||
CHECK_ALLOC_FAIL(while (n.append_child(node_comment)){/* nop */});
|
||||
CHECK_ALLOC_FAIL(while (n.append_attribute(STR("b"))){/* nop */});
|
||||
|
||||
// verify all node modification operations
|
||||
CHECK_ALLOC_FAIL(CHECK(!n.append_child()));
|
||||
@ -1005,7 +1006,8 @@ TEST(dom_node_memory_limit)
|
||||
const unsigned int length = 65536;
|
||||
static char_t string[length + 1];
|
||||
|
||||
for (unsigned int i = 0; i < length; ++i) string[i] = 'a';
|
||||
for (unsigned int i = 0; i < length; ++i)
|
||||
string[i] = 'a';
|
||||
string[length] = 0;
|
||||
|
||||
test_runner::_memory_fail_threshold = 32768 * 2 + sizeof(string);
|
||||
@ -1024,7 +1026,8 @@ TEST(dom_node_memory_limit_pi)
|
||||
const unsigned int length = 65536;
|
||||
static char_t string[length + 1];
|
||||
|
||||
for (unsigned int i = 0; i < length; ++i) string[i] = 'a';
|
||||
for (unsigned int i = 0; i < length; ++i)
|
||||
string[i] = 'a';
|
||||
string[length] = 0;
|
||||
|
||||
test_runner::_memory_fail_threshold = 32768 * 2 + sizeof(string);
|
||||
@ -1112,7 +1115,6 @@ TEST_XML(dom_node_append_buffer_convert, "<node>test</node>")
|
||||
CHECK_NODE(doc, STR("<node>test<n/><n/></node>"));
|
||||
}
|
||||
|
||||
|
||||
TEST_XML(dom_node_append_buffer_remove, "<node>test</node>")
|
||||
{
|
||||
xml_node node = doc.child(STR("node"));
|
||||
@ -1127,15 +1129,21 @@ TEST_XML(dom_node_append_buffer_remove, "<node>test</node>")
|
||||
|
||||
CHECK_NODE(doc, STR("<node>test<child1 id=\"1\"/><child2>text</child2><child3/><child1 id=\"1\"/><child2>text</child2><child3/></node>"));
|
||||
|
||||
while (node.remove_child(STR("child2"))) {}
|
||||
while (node.remove_child(STR("child2")))
|
||||
{
|
||||
}
|
||||
|
||||
CHECK_NODE(doc, STR("<node>test<child1 id=\"1\"/><child3/><child1 id=\"1\"/><child3/></node>"));
|
||||
|
||||
while (node.remove_child(STR("child1"))) {}
|
||||
while (node.remove_child(STR("child1")))
|
||||
{
|
||||
}
|
||||
|
||||
CHECK_NODE(doc, STR("<node>test<child3/><child3/></node>"));
|
||||
|
||||
while (node.remove_child(STR("child3"))) {}
|
||||
while (node.remove_child(STR("child3")))
|
||||
{
|
||||
}
|
||||
|
||||
CHECK_NODE(doc, STR("<node>test</node>"));
|
||||
|
||||
@ -1665,7 +1673,8 @@ TEST(dom_node_copy_declaration_empty_name)
|
||||
CHECK_STRING(decl2.name(), STR(""));
|
||||
}
|
||||
|
||||
template <typename T> bool fp_equal(T lhs, T rhs)
|
||||
template <typename T>
|
||||
bool fp_equal(T lhs, T rhs)
|
||||
{
|
||||
// Several compilers compare float/double values on x87 stack without proper rounding
|
||||
// This causes roundtrip tests to fail, although they correctly preserve the data.
|
||||
@ -1703,7 +1712,7 @@ TEST(dom_fp_roundtrip_min_max_double)
|
||||
}
|
||||
|
||||
const double fp_roundtrip_base[] =
|
||||
{
|
||||
{
|
||||
0.31830988618379067154,
|
||||
0.43429448190325182765,
|
||||
0.57721566490153286061,
|
||||
@ -1738,17 +1747,17 @@ TEST(dom_fp_roundtrip_double)
|
||||
{
|
||||
for (size_t i = 0; i < sizeof(fp_roundtrip_base) / sizeof(fp_roundtrip_base[0]); ++i)
|
||||
{
|
||||
#if (defined(_MSC_VER) && _MSC_VER < 1400) || defined(__MWERKS__)
|
||||
#if (defined(_MSC_VER) && _MSC_VER < 1400) || defined(__MWERKS__)
|
||||
// Not all runtime libraries guarantee roundtripping for denormals
|
||||
if (e == -1021 && fp_roundtrip_base[i] < 0.5)
|
||||
continue;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __DMC__
|
||||
#ifdef __DMC__
|
||||
// Digital Mars C does not roundtrip on exactly one combination
|
||||
if (e == -12 && i == 1)
|
||||
continue;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
double value = ldexp(fp_roundtrip_base[i], e);
|
||||
|
||||
|
||||
@ -4,28 +4,34 @@
|
||||
|
||||
#include "test.hpp"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "helpers.hpp"
|
||||
|
||||
using namespace pugi;
|
||||
|
||||
#ifdef PUGIXML_NO_STL
|
||||
template <typename I> static I move_iter(I base, int n)
|
||||
template <typename I>
|
||||
static I move_iter(I base, int n)
|
||||
{
|
||||
if (n > 0) while (n--) ++base;
|
||||
else while (n++) --base;
|
||||
if (n > 0)
|
||||
while (n--)
|
||||
++base;
|
||||
else
|
||||
while (n++)
|
||||
--base;
|
||||
return base;
|
||||
}
|
||||
#else
|
||||
template <typename I> static I move_iter(I base, int n)
|
||||
template <typename I>
|
||||
static I move_iter(I base, int n)
|
||||
{
|
||||
std::advance(base, n);
|
||||
return base;
|
||||
@ -659,11 +665,13 @@ struct find_predicate_const
|
||||
{
|
||||
bool result;
|
||||
|
||||
find_predicate_const(bool result_): result(result_)
|
||||
find_predicate_const(bool result_)
|
||||
: result(result_)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T> bool operator()(const T&) const
|
||||
template <typename T>
|
||||
bool operator()(const T&) const
|
||||
{
|
||||
return result;
|
||||
}
|
||||
@ -673,18 +681,20 @@ struct find_predicate_prefix
|
||||
{
|
||||
const char_t* prefix;
|
||||
|
||||
find_predicate_prefix(const char_t* prefix_): prefix(prefix_)
|
||||
find_predicate_prefix(const char_t* prefix_)
|
||||
: prefix(prefix_)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T> bool operator()(const T& obj) const
|
||||
template <typename T>
|
||||
bool operator()(const T& obj) const
|
||||
{
|
||||
#ifdef PUGIXML_WCHAR_MODE
|
||||
#ifdef PUGIXML_WCHAR_MODE
|
||||
// can't use wcsncmp here because of a bug in DMC
|
||||
return std::basic_string<char_t>(obj.name()).compare(0, wcslen(prefix), prefix) == 0;
|
||||
#else
|
||||
#else
|
||||
return strncmp(obj.name(), prefix, strlen(prefix)) == 0;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
@ -782,13 +792,15 @@ TEST_XML(dom_node_first_element_by_path, "<node><child1>text<child2/></child1></
|
||||
CHECK(doc.first_element_by_path(STR("//node")) == doc.child(STR("node")));
|
||||
}
|
||||
|
||||
struct test_walker: xml_tree_walker
|
||||
struct test_walker : xml_tree_walker
|
||||
{
|
||||
std::basic_string<char_t> log;
|
||||
unsigned int call_count;
|
||||
unsigned int stop_count;
|
||||
|
||||
test_walker(unsigned int stop_count_ = 0): call_count(0), stop_count(stop_count_)
|
||||
test_walker(unsigned int stop_count_ = 0)
|
||||
: call_count(0)
|
||||
, stop_count(stop_count_)
|
||||
{
|
||||
}
|
||||
|
||||
@ -797,14 +809,14 @@ struct test_walker: xml_tree_walker
|
||||
char buf[32];
|
||||
sprintf(buf, "%d", depth());
|
||||
|
||||
#ifdef PUGIXML_WCHAR_MODE
|
||||
#ifdef PUGIXML_WCHAR_MODE
|
||||
wchar_t wbuf[32];
|
||||
std::copy(buf, buf + strlen(buf) + 1, &wbuf[0]);
|
||||
|
||||
return std::basic_string<char_t>(wbuf);
|
||||
#else
|
||||
#else
|
||||
return std::basic_string<char_t>(buf);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual bool begin(xml_node& node) PUGIXML_OVERRIDE
|
||||
@ -935,7 +947,7 @@ TEST_XML_FLAGS(dom_offset_debug, "<?xml?><!DOCTYPE><?pi?><!--comment--><node>pcd
|
||||
|
||||
TEST(dom_offset_debug_encoding)
|
||||
{
|
||||
char buf[] = { 0, '<', 0, 'n', 0, '/', 0, '>' };
|
||||
char buf[] = {0, '<', 0, 'n', 0, '/', 0, '>'};
|
||||
|
||||
xml_document doc;
|
||||
CHECK(doc.load_buffer(buf, sizeof(buf)));
|
||||
@ -1121,15 +1133,15 @@ TEST_XML(dom_ranged_for, "<node attr1='1' attr2='2'><test>3</test><fake>5</fake>
|
||||
{
|
||||
int index = 1;
|
||||
|
||||
for (xml_node n: doc.children())
|
||||
for (xml_node n : doc.children())
|
||||
{
|
||||
for (xml_attribute a: n.attributes())
|
||||
for (xml_attribute a : n.attributes())
|
||||
{
|
||||
CHECK(a.as_int() == index);
|
||||
index++;
|
||||
}
|
||||
|
||||
for (xml_node c: n.children(STR("test")))
|
||||
for (xml_node c : n.children(STR("test")))
|
||||
{
|
||||
CHECK(c.text().as_int() == index);
|
||||
index++;
|
||||
|
||||
@ -1,3 +1,2 @@
|
||||
// Tests header guards
|
||||
#include "../src/pugixml.hpp"
|
||||
#include "../src/pugixml.hpp"
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
// Tests compatibility with iosfwd
|
||||
#include <iosfwd>
|
||||
#include "../src/pugixml.hpp"
|
||||
#include <iosfwd>
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
// Tests compatibility with iostream
|
||||
#include <iostream>
|
||||
#include "../src/pugixml.hpp"
|
||||
#include <iostream>
|
||||
|
||||
@ -5,7 +5,6 @@
|
||||
|
||||
// Check header guards
|
||||
#include "../src/pugixml.hpp"
|
||||
#include "../src/pugixml.hpp"
|
||||
|
||||
using namespace pugi;
|
||||
|
||||
|
||||
@ -5,7 +5,6 @@
|
||||
|
||||
// Check header guards
|
||||
#include "../src/pugixml.hpp"
|
||||
#include "../src/pugixml.hpp"
|
||||
|
||||
using namespace pugi;
|
||||
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
// Tests compatibility with string
|
||||
#include <string>
|
||||
#include "../src/pugixml.hpp"
|
||||
#include <string>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
// Tests compatibility with string/iostream
|
||||
#include <string>
|
||||
#include "../src/pugixml.hpp"
|
||||
#include <istream>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#include "test.hpp"
|
||||
|
||||
#include "writer_string.hpp"
|
||||
#include "allocator.hpp"
|
||||
#include "writer_string.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@ -10,27 +10,27 @@ using namespace pugi;
|
||||
|
||||
namespace
|
||||
{
|
||||
int page_allocs = 0;
|
||||
int page_deallocs = 0;
|
||||
int page_allocs = 0;
|
||||
int page_deallocs = 0;
|
||||
|
||||
bool is_page(size_t size)
|
||||
{
|
||||
bool is_page(size_t size)
|
||||
{
|
||||
return size >= 16384;
|
||||
}
|
||||
}
|
||||
|
||||
void* allocate(size_t size)
|
||||
{
|
||||
void* allocate(size_t size)
|
||||
{
|
||||
void* ptr = memory_allocate(size);
|
||||
page_allocs += is_page(memory_size(ptr));
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
|
||||
void deallocate(void* ptr)
|
||||
{
|
||||
void deallocate(void* ptr)
|
||||
{
|
||||
page_deallocs += is_page(memory_size(ptr));
|
||||
memory_deallocate(ptr);
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TEST(memory_custom_memory_management)
|
||||
{
|
||||
@ -116,7 +116,7 @@ TEST(memory_large_allocations)
|
||||
}
|
||||
|
||||
// prune
|
||||
for (node = doc.first_child(); node; )
|
||||
for (node = doc.first_child(); node;)
|
||||
{
|
||||
xml_node next = node.next_sibling().next_sibling();
|
||||
|
||||
@ -229,7 +229,8 @@ TEST(memory_string_allocate_decreasing)
|
||||
|
||||
std::basic_string<char_t> s = STR("ab");
|
||||
|
||||
for (int i = 0; i < 17; ++i) s += s;
|
||||
for (int i = 0; i < 17; ++i)
|
||||
s += s;
|
||||
|
||||
for (int j = 0; j < 17; ++j)
|
||||
{
|
||||
@ -286,7 +287,8 @@ TEST(memory_string_allocate_decreasing_inplace)
|
||||
|
||||
std::basic_string<char_t> s = STR("ab");
|
||||
|
||||
for (int i = 0; i < 17; ++i) s += s;
|
||||
for (int i = 0; i < 17; ++i)
|
||||
s += s;
|
||||
|
||||
for (int j = 0; j < 17; ++j)
|
||||
{
|
||||
|
||||
@ -448,24 +448,23 @@ TEST(parse_pcdata_trim)
|
||||
|
||||
test_data_t test_data[] =
|
||||
{
|
||||
{ STR("<node> text</node>"), STR("text"), 0 },
|
||||
{ STR("<node>\t\n text</node>"), STR("text"), 0 },
|
||||
{ STR("<node>text </node>"), STR("text"), 0 },
|
||||
{ STR("<node>text \t\n</node>"), STR("text"), 0 },
|
||||
{ STR("<node>\r\n\t text \t\n\r</node>"), STR("text"), 0 },
|
||||
{ STR(" text"), STR("text"), parse_fragment },
|
||||
{ STR("\t\n text"), STR("text"), parse_fragment },
|
||||
{ STR("text "), STR("text"), parse_fragment },
|
||||
{ STR("text \t\n"), STR("text"), parse_fragment },
|
||||
{ STR("\r\n\t text \t\n\r"), STR("text"), parse_fragment },
|
||||
{ STR("<node>\r\n\t text \t\n\r more \r\n\t</node>"), STR("text \t\n\r more"), 0 },
|
||||
{ STR("<node>\r\n\t text \t\n\r more \r\n\t</node>"), STR("text \t\n\n more"), parse_eol },
|
||||
{ STR("<node>\r\n\t text \r\n\r\n\r\n\r\n\r\n\r\n\r\n more \r\n\t</node>"), STR("text \n\n\n\n\n\n\n more"), parse_eol },
|
||||
{ STR("<node> test&&&&&&& </node>"), STR("test&&&&&&&"), 0 },
|
||||
{ STR("<node> test&&&&&&& </node>"), STR("test&&&&&&&"), parse_escapes },
|
||||
{ STR(" test&&&&&&& "), STR("test&&&&&&&"), parse_fragment | parse_escapes },
|
||||
{ STR("<node>\r\n\t text \t\n\r m&&e \r\n\t</node>"), STR("text \t\n\n m&&e"), parse_eol | parse_escapes }
|
||||
};
|
||||
{STR("<node> text</node>"), STR("text"), 0},
|
||||
{STR("<node>\t\n text</node>"), STR("text"), 0},
|
||||
{STR("<node>text </node>"), STR("text"), 0},
|
||||
{STR("<node>text \t\n</node>"), STR("text"), 0},
|
||||
{STR("<node>\r\n\t text \t\n\r</node>"), STR("text"), 0},
|
||||
{STR(" text"), STR("text"), parse_fragment},
|
||||
{STR("\t\n text"), STR("text"), parse_fragment},
|
||||
{STR("text "), STR("text"), parse_fragment},
|
||||
{STR("text \t\n"), STR("text"), parse_fragment},
|
||||
{STR("\r\n\t text \t\n\r"), STR("text"), parse_fragment},
|
||||
{STR("<node>\r\n\t text \t\n\r more \r\n\t</node>"), STR("text \t\n\r more"), 0},
|
||||
{STR("<node>\r\n\t text \t\n\r more \r\n\t</node>"), STR("text \t\n\n more"), parse_eol},
|
||||
{STR("<node>\r\n\t text \r\n\r\n\r\n\r\n\r\n\r\n\r\n more \r\n\t</node>"), STR("text \n\n\n\n\n\n\n more"), parse_eol},
|
||||
{STR("<node> test&&&&&&& </node>"), STR("test&&&&&&&"), 0},
|
||||
{STR("<node> test&&&&&&& </node>"), STR("test&&&&&&&"), parse_escapes},
|
||||
{STR(" test&&&&&&& "), STR("test&&&&&&&"), parse_fragment | parse_escapes},
|
||||
{STR("<node>\r\n\t text \t\n\r m&&e \r\n\t</node>"), STR("text \t\n\n m&&e"), parse_eol | parse_escapes}};
|
||||
|
||||
for (size_t i = 0; i < sizeof(test_data) / sizeof(test_data[0]); ++i)
|
||||
{
|
||||
@ -481,7 +480,7 @@ TEST(parse_pcdata_trim)
|
||||
|
||||
TEST(parse_pcdata_trim_empty)
|
||||
{
|
||||
unsigned int flags[] = { 0, parse_ws_pcdata, parse_ws_pcdata_single, parse_ws_pcdata | parse_ws_pcdata_single };
|
||||
unsigned int flags[] = {0, parse_ws_pcdata, parse_ws_pcdata_single, parse_ws_pcdata | parse_ws_pcdata_single};
|
||||
|
||||
for (size_t i = 0; i < sizeof(flags) / sizeof(flags[0]); ++i)
|
||||
{
|
||||
@ -696,7 +695,6 @@ TEST(parse_attribute_variations)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST(parse_attribute_error)
|
||||
{
|
||||
xml_document doc;
|
||||
@ -926,10 +924,10 @@ TEST(parse_out_of_memory_halfway_node)
|
||||
|
||||
for (unsigned int i = 0; i < count; ++i)
|
||||
{
|
||||
text[4*i + 0] = '<';
|
||||
text[4*i + 1] = 'n';
|
||||
text[4*i + 2] = '/';
|
||||
text[4*i + 3] = '>';
|
||||
text[4 * i + 0] = '<';
|
||||
text[4 * i + 1] = 'n';
|
||||
text[4 * i + 2] = '/';
|
||||
text[4 * i + 3] = '>';
|
||||
}
|
||||
|
||||
test_runner::_memory_fail_threshold = 65536;
|
||||
@ -949,11 +947,11 @@ TEST(parse_out_of_memory_halfway_attr)
|
||||
|
||||
for (unsigned int i = 0; i < count; ++i)
|
||||
{
|
||||
text[5*i + 2] = ' ';
|
||||
text[5*i + 3] = 'a';
|
||||
text[5*i + 4] = '=';
|
||||
text[5*i + 5] = '"';
|
||||
text[5*i + 6] = '"';
|
||||
text[5 * i + 2] = ' ';
|
||||
text[5 * i + 3] = 'a';
|
||||
text[5 * i + 4] = '=';
|
||||
text[5 * i + 5] = '"';
|
||||
text[5 * i + 6] = '"';
|
||||
}
|
||||
|
||||
text[5 * count + 2] = '/';
|
||||
@ -984,10 +982,10 @@ TEST(parse_out_of_memory_allocator_state_sync)
|
||||
|
||||
for (unsigned int i = 0; i < count; ++i)
|
||||
{
|
||||
text[4*i + 0] = '<';
|
||||
text[4*i + 1] = 'n';
|
||||
text[4*i + 2] = '/';
|
||||
text[4*i + 3] = '>';
|
||||
text[4 * i + 0] = '<';
|
||||
text[4 * i + 1] = 'n';
|
||||
text[4 * i + 2] = '/';
|
||||
text[4 * i + 3] = '>';
|
||||
}
|
||||
|
||||
test_runner::_memory_fail_threshold = 65536;
|
||||
@ -1073,16 +1071,16 @@ TEST(parse_bom_fragment)
|
||||
|
||||
const test_data_t data[] =
|
||||
{
|
||||
{ encoding_utf8, "\xef\xbb\xbf", 3, STR("") },
|
||||
{ encoding_utf8, "\xef\xbb\xbftest", 7, STR("test") },
|
||||
{ encoding_utf16_be, "\xfe\xff", 2, STR("") },
|
||||
{ encoding_utf16_be, "\xfe\xff\x00t\x00o\x00s\x00t", 10, STR("tost") },
|
||||
{ encoding_utf16_le, "\xff\xfe", 2, STR("") },
|
||||
{ encoding_utf16_le, "\xff\xfet\x00o\x00s\x00t\x00", 10, STR("tost") },
|
||||
{ encoding_utf32_be, "\x00\x00\xfe\xff", 4, STR("") },
|
||||
{ encoding_utf32_be, "\x00\x00\xfe\xff\x00\x00\x00t\x00\x00\x00o\x00\x00\x00s\x00\x00\x00t", 20, STR("tost") },
|
||||
{ encoding_utf32_le, "\xff\xfe\x00\x00", 4, STR("") },
|
||||
{ encoding_utf32_le, "\xff\xfe\x00\x00t\x00\x00\x00o\x00\x00\x00s\x00\x00\x00t\x00\x00\x00", 20, STR("tost") },
|
||||
{encoding_utf8, "\xef\xbb\xbf", 3, STR("")},
|
||||
{encoding_utf8, "\xef\xbb\xbftest", 7, STR("test")},
|
||||
{encoding_utf16_be, "\xfe\xff", 2, STR("")},
|
||||
{encoding_utf16_be, "\xfe\xff\x00t\x00o\x00s\x00t", 10, STR("tost")},
|
||||
{encoding_utf16_le, "\xff\xfe", 2, STR("")},
|
||||
{encoding_utf16_le, "\xff\xfet\x00o\x00s\x00t\x00", 10, STR("tost")},
|
||||
{encoding_utf32_be, "\x00\x00\xfe\xff", 4, STR("")},
|
||||
{encoding_utf32_be, "\x00\x00\xfe\xff\x00\x00\x00t\x00\x00\x00o\x00\x00\x00s\x00\x00\x00t", 20, STR("tost")},
|
||||
{encoding_utf32_le, "\xff\xfe\x00\x00", 4, STR("")},
|
||||
{encoding_utf32_le, "\xff\xfe\x00\x00t\x00\x00\x00o\x00\x00\x00s\x00\x00\x00t\x00\x00\x00", 20, STR("tost")},
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < sizeof(data) / sizeof(data[0]); ++i)
|
||||
@ -1175,8 +1173,7 @@ TEST(parse_fuzz_doctype)
|
||||
0x3b, 0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0xef, 0xbb, 0xbf, 0x3c, 0x3f, 0x78,
|
||||
0x6d, 0x6c, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x31, 0x2e, 0x30, 0x22,
|
||||
0x3f, 0x3e, 0x3c, 0x21, 0x2d, 0x2d, 0x20, 0xe9, 0x80, 0xb1, 0xe5, 0xa0, 0xb1, 0xe3, 0x82, 0xb4,
|
||||
0xe3, 0x83, 0xb3, 0x20, 0xef, 0x83, 0x97, 0xe3, 0xa9, 0x2a, 0x20, 0x2d, 0x2d, 0x3e
|
||||
};
|
||||
0xe3, 0x83, 0xb3, 0x20, 0xef, 0x83, 0x97, 0xe3, 0xa9, 0x2a, 0x20, 0x2d, 0x2d, 0x3e};
|
||||
|
||||
xml_document doc;
|
||||
CHECK(doc.load_buffer(data, sizeof(data)).status == status_bad_doctype);
|
||||
@ -1215,9 +1212,9 @@ TEST(parse_embed_pcdata)
|
||||
CHECK_STRING(child.child_value(), STR("outer"));
|
||||
CHECK_STRING(child.child_value(STR("inner2")), STR("value2"));
|
||||
|
||||
#ifndef PUGIXML_NO_XPATH
|
||||
#ifndef PUGIXML_NO_XPATH
|
||||
CHECK_XPATH_NUMBER(doc, STR("count(node/child/*[starts-with(., 'value')])"), 2);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
CHECK_NODE(doc, STR("<node><key>value</key><child><inner1>value1</inner1><inner2>value2</inner2>outer</child><two>text<data/></two></node>"));
|
||||
CHECK_NODE_EX(doc, STR("<node>\n<key>value</key>\n<child>\n<inner1>value1</inner1>\n<inner2>value2</inner2>outer</child>\n<two>text<data />\n</two>\n</node>\n"), STR("\t"), 0);
|
||||
@ -1288,20 +1285,20 @@ TEST(parse_encoding_detect_auto)
|
||||
const data_t data[] =
|
||||
{
|
||||
// BOM
|
||||
{ "\x00\x00\xfe\xff", 4, encoding_utf32_be },
|
||||
{ "\xff\xfe\x00\x00", 4, encoding_utf32_le },
|
||||
{ "\xfe\xff ", 4, encoding_utf16_be },
|
||||
{ "\xff\xfe ", 4, encoding_utf16_le },
|
||||
{ "\xef\xbb\xbf ", 4, encoding_utf8 },
|
||||
{"\x00\x00\xfe\xff", 4, encoding_utf32_be},
|
||||
{"\xff\xfe\x00\x00", 4, encoding_utf32_le},
|
||||
{"\xfe\xff ", 4, encoding_utf16_be},
|
||||
{"\xff\xfe ", 4, encoding_utf16_le},
|
||||
{"\xef\xbb\xbf ", 4, encoding_utf8},
|
||||
// automatic tag detection for < or <?
|
||||
{ "\x00\x00\x00<\x00\x00\x00n\x00\x00\x00/\x00\x00\x00>", 16, encoding_utf32_be },
|
||||
{ "<\x00\x00\x00n\x00\x00\x00/\x00\x00\x00>\x00\x00\x00", 16, encoding_utf32_le },
|
||||
{ "\x00<\x00?\x00n\x00?\x00>", 10, encoding_utf16_be },
|
||||
{ "<\x00?\x00n\x00?\x00>\x00", 10, encoding_utf16_le },
|
||||
{ "\x00<\x00n\x00/\x00>", 8, encoding_utf16_be },
|
||||
{ "<\x00n\x00/\x00>\x00", 8, encoding_utf16_le },
|
||||
{"\x00\x00\x00<\x00\x00\x00n\x00\x00\x00/\x00\x00\x00>", 16, encoding_utf32_be},
|
||||
{"<\x00\x00\x00n\x00\x00\x00/\x00\x00\x00>\x00\x00\x00", 16, encoding_utf32_le},
|
||||
{"\x00<\x00?\x00n\x00?\x00>", 10, encoding_utf16_be},
|
||||
{"<\x00?\x00n\x00?\x00>\x00", 10, encoding_utf16_le},
|
||||
{"\x00<\x00n\x00/\x00>", 8, encoding_utf16_be},
|
||||
{"<\x00n\x00/\x00>\x00", 8, encoding_utf16_le},
|
||||
// <?xml encoding
|
||||
{ "<?xml encoding='latin1'?>", 25, encoding_latin1 },
|
||||
{"<?xml encoding='latin1'?>", 25, encoding_latin1},
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < sizeof(data) / sizeof(data[0]); ++i)
|
||||
@ -1326,24 +1323,24 @@ TEST(parse_encoding_detect_auto_incomplete)
|
||||
const data_t data[] =
|
||||
{
|
||||
// BOM
|
||||
{ "\x00\x00\xfe ", 4, encoding_utf8 },
|
||||
{ "\x00\x00 ", 4, encoding_utf8 },
|
||||
{ "\xff\xfe\x00 ", 4, encoding_utf16_le },
|
||||
{ "\xfe ", 4, encoding_utf8 },
|
||||
{ "\xff ", 4, encoding_utf8 },
|
||||
{ "\xef\xbb ", 4, encoding_utf8 },
|
||||
{ "\xef ", 4, encoding_utf8 },
|
||||
{"\x00\x00\xfe ", 4, encoding_utf8},
|
||||
{"\x00\x00 ", 4, encoding_utf8},
|
||||
{"\xff\xfe\x00 ", 4, encoding_utf16_le},
|
||||
{"\xfe ", 4, encoding_utf8},
|
||||
{"\xff ", 4, encoding_utf8},
|
||||
{"\xef\xbb ", 4, encoding_utf8},
|
||||
{"\xef ", 4, encoding_utf8},
|
||||
// automatic tag detection for < or <?
|
||||
{ "\x00\x00\x00 ", 4, encoding_utf8 },
|
||||
{ "<\x00\x00n/\x00>\x00", 8, encoding_utf16_le },
|
||||
{ "\x00<n\x00\x00/\x00>", 8, encoding_utf16_be },
|
||||
{ "<\x00?n/\x00>\x00", 8, encoding_utf16_le },
|
||||
{ "\x00 ", 2, encoding_utf8 },
|
||||
{"\x00\x00\x00 ", 4, encoding_utf8},
|
||||
{"<\x00\x00n/\x00>\x00", 8, encoding_utf16_le},
|
||||
{"\x00<n\x00\x00/\x00>", 8, encoding_utf16_be},
|
||||
{"<\x00?n/\x00>\x00", 8, encoding_utf16_le},
|
||||
{"\x00 ", 2, encoding_utf8},
|
||||
// <?xml encoding
|
||||
{ "<?xmC encoding='latin1'?>", 25, encoding_utf8 },
|
||||
{ "<?xBC encoding='latin1'?>", 25, encoding_utf8 },
|
||||
{ "<?ABC encoding='latin1'?>", 25, encoding_utf8 },
|
||||
{ "<_ABC encoding='latin1'/>", 25, encoding_utf8 },
|
||||
{"<?xmC encoding='latin1'?>", 25, encoding_utf8},
|
||||
{"<?xBC encoding='latin1'?>", 25, encoding_utf8},
|
||||
{"<?ABC encoding='latin1'?>", 25, encoding_utf8},
|
||||
{"<_ABC encoding='latin1'/>", 25, encoding_utf8},
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < sizeof(data) / sizeof(data[0]); ++i)
|
||||
|
||||
@ -3,8 +3,8 @@
|
||||
#include "test.hpp"
|
||||
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <string>
|
||||
#include <wchar.h>
|
||||
|
||||
using namespace pugi;
|
||||
|
||||
@ -30,17 +30,24 @@ static bool test_doctype_wf(const char_t* decl)
|
||||
xml_document doc;
|
||||
|
||||
// standalone
|
||||
if (!load_concat(doc, decl) || !doc.first_child().empty()) return false;
|
||||
if (!load_concat(doc, decl) || !doc.first_child().empty())
|
||||
return false;
|
||||
|
||||
// pcdata pre/postfix
|
||||
if (!load_concat(doc, STR("a"), decl) || !test_node(doc, STR("a"), STR(""), format_raw)) return false;
|
||||
if (!load_concat(doc, decl, STR("b")) || !test_node(doc, STR("b"), STR(""), format_raw)) return false;
|
||||
if (!load_concat(doc, STR("a"), decl, STR("b")) || !test_node(doc, STR("ab"), STR(""), format_raw)) return false;
|
||||
if (!load_concat(doc, STR("a"), decl) || !test_node(doc, STR("a"), STR(""), format_raw))
|
||||
return false;
|
||||
if (!load_concat(doc, decl, STR("b")) || !test_node(doc, STR("b"), STR(""), format_raw))
|
||||
return false;
|
||||
if (!load_concat(doc, STR("a"), decl, STR("b")) || !test_node(doc, STR("ab"), STR(""), format_raw))
|
||||
return false;
|
||||
|
||||
// node pre/postfix
|
||||
if (!load_concat(doc, STR("<nodea/>"), decl) || !test_node(doc, STR("<nodea/>"), STR(""), format_raw)) return false;
|
||||
if (!load_concat(doc, decl, STR("<nodeb/>")) || !test_node(doc, STR("<nodeb/>"), STR(""), format_raw)) return false;
|
||||
if (!load_concat(doc, STR("<nodea/>"), decl, STR("<nodeb/>")) || !test_node(doc, STR("<nodea/><nodeb/>"), STR(""), format_raw)) return false;
|
||||
if (!load_concat(doc, STR("<nodea/>"), decl) || !test_node(doc, STR("<nodea/>"), STR(""), format_raw))
|
||||
return false;
|
||||
if (!load_concat(doc, decl, STR("<nodeb/>")) || !test_node(doc, STR("<nodeb/>"), STR(""), format_raw))
|
||||
return false;
|
||||
if (!load_concat(doc, STR("<nodea/>"), decl, STR("<nodeb/>")) || !test_node(doc, STR("<nodea/><nodeb/>"), STR(""), format_raw))
|
||||
return false;
|
||||
|
||||
// check load-store contents preservation
|
||||
CHECK(doc.load_string(decl, parse_doctype | parse_fragment));
|
||||
@ -54,13 +61,16 @@ static bool test_doctype_nwf(const char_t* decl)
|
||||
xml_document doc;
|
||||
|
||||
// standalone
|
||||
if (load_concat(doc, decl).status != status_bad_doctype) return false;
|
||||
if (load_concat(doc, decl).status != status_bad_doctype)
|
||||
return false;
|
||||
|
||||
// pcdata postfix
|
||||
if (load_concat(doc, decl, STR("b")).status != status_bad_doctype) return false;
|
||||
if (load_concat(doc, decl, STR("b")).status != status_bad_doctype)
|
||||
return false;
|
||||
|
||||
// node postfix
|
||||
if (load_concat(doc, decl, STR("<nodeb/>")).status != status_bad_doctype) return false;
|
||||
if (load_concat(doc, decl, STR("<nodeb/>")).status != status_bad_doctype)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -110,11 +110,11 @@ TEST(as_utf8_valid_astral)
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef U_LITERALS
|
||||
#ifdef U_LITERALS
|
||||
CHECK(as_utf8(L"\uda1d\ude24 \udbc0\udfff") == "\xf2\x97\x98\xa4 \xf4\x80\x8f\xbf");
|
||||
#else
|
||||
#else
|
||||
CHECK(as_utf8(L"\xda1d\xde24 \xdbc0\xdfff") == "\xf2\x97\x98\xa4 \xf4\x80\x8f\xbf");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -125,22 +125,22 @@ TEST(as_utf8_invalid)
|
||||
if (wcharsize == 2)
|
||||
{
|
||||
// check non-terminated degenerate handling
|
||||
#ifdef U_LITERALS
|
||||
#ifdef U_LITERALS
|
||||
CHECK(as_utf8(L"a\uda1d") == "a");
|
||||
CHECK(as_utf8(L"a\uda1d_") == "a_");
|
||||
#else
|
||||
#else
|
||||
CHECK(as_utf8(L"a\xda1d") == "a");
|
||||
CHECK(as_utf8(L"a\xda1d_") == "a_");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// check incorrect leading code
|
||||
#ifdef U_LITERALS
|
||||
#ifdef U_LITERALS
|
||||
CHECK(as_utf8(L"a\ude24") == "a");
|
||||
CHECK(as_utf8(L"a\ude24_") == "a_");
|
||||
#else
|
||||
#else
|
||||
CHECK(as_utf8(L"a\xde24") == "a");
|
||||
CHECK(as_utf8(L"a\xde24_") == "a_");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2,9 +2,9 @@
|
||||
|
||||
#include "writer_string.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
using namespace pugi;
|
||||
|
||||
@ -199,11 +199,11 @@ TEST_XML(write_escape, "<node attr=''>text</node>")
|
||||
TEST_XML(write_escape_unicode, "<node attr='㰀'/>")
|
||||
{
|
||||
#ifdef PUGIXML_WCHAR_MODE
|
||||
#ifdef U_LITERALS
|
||||
#ifdef U_LITERALS
|
||||
CHECK_NODE(doc, STR("<node attr=\"\u3c00\"/>"));
|
||||
#else
|
||||
#else
|
||||
CHECK_NODE(doc, STR("<node attr=\"\x3c00\"/>"));
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
CHECK_NODE(doc, STR("<node attr=\"\xe3\xb0\x80\"/>"));
|
||||
#endif
|
||||
@ -217,7 +217,7 @@ TEST_XML(write_no_escapes, "<node attr=''>text</node>")
|
||||
CHECK_NODE_EX(doc, STR("<node attr=\"<>'\"&\x04\r\n\t\"><>'\"&\x04\r\n\t</node>"), STR(""), format_raw | format_no_escapes);
|
||||
}
|
||||
|
||||
struct test_writer: xml_writer
|
||||
struct test_writer : xml_writer
|
||||
{
|
||||
std::basic_string<char_t> contents;
|
||||
|
||||
@ -313,7 +313,8 @@ TEST(write_encoding_huge)
|
||||
// make a large utf16 name consisting of 6-byte char pairs (6 does not divide internal buffer size, so will need split correction)
|
||||
std::string s_utf16 = std::string("\x00<", 2);
|
||||
|
||||
for (unsigned int i = 0; i < N; ++i) s_utf16 += "\x20\xAC\xd8\x52\xdf\x62";
|
||||
for (unsigned int i = 0; i < N; ++i)
|
||||
s_utf16 += "\x20\xAC\xd8\x52\xdf\x62";
|
||||
|
||||
s_utf16 += std::string("\x00/\x00>", 4);
|
||||
|
||||
@ -322,7 +323,8 @@ TEST(write_encoding_huge)
|
||||
|
||||
std::string s_utf8 = "<";
|
||||
|
||||
for (unsigned int j = 0; j < N; ++j) s_utf8 += "\xE2\x82\xAC\xF0\xA4\xAD\xA2";
|
||||
for (unsigned int j = 0; j < N; ++j)
|
||||
s_utf8 += "\xE2\x82\xAC\xF0\xA4\xAD\xA2";
|
||||
|
||||
s_utf8 += " />\n";
|
||||
|
||||
@ -340,7 +342,8 @@ TEST(write_encoding_huge_invalid)
|
||||
// make a large utf16 name consisting of leading surrogate chars
|
||||
std::basic_string<wchar_t> s_utf16;
|
||||
|
||||
for (unsigned int i = 0; i < N; ++i) s_utf16 += static_cast<wchar_t>(0xd852);
|
||||
for (unsigned int i = 0; i < N; ++i)
|
||||
s_utf16 += static_cast<wchar_t>(0xd852);
|
||||
|
||||
xml_document doc;
|
||||
doc.append_child().set_name(s_utf16.c_str());
|
||||
@ -356,7 +359,8 @@ TEST(write_encoding_huge)
|
||||
// make a large utf8 name consisting of 3-byte chars (3 does not divide internal buffer size, so will need split correction)
|
||||
std::string s_utf8 = "<";
|
||||
|
||||
for (unsigned int i = 0; i < N; ++i) s_utf8 += "\xE2\x82\xAC";
|
||||
for (unsigned int i = 0; i < N; ++i)
|
||||
s_utf8 += "\xE2\x82\xAC";
|
||||
|
||||
s_utf8 += "/>";
|
||||
|
||||
@ -365,7 +369,8 @@ TEST(write_encoding_huge)
|
||||
|
||||
std::string s_utf16 = std::string("\x00<", 2);
|
||||
|
||||
for (unsigned int j = 0; j < N; ++j) s_utf16 += "\x20\xAC";
|
||||
for (unsigned int j = 0; j < N; ++j)
|
||||
s_utf16 += "\x20\xAC";
|
||||
|
||||
s_utf16 += std::string("\x00 \x00/\x00>\x00\n", 8);
|
||||
|
||||
@ -379,7 +384,8 @@ TEST(write_encoding_huge_invalid)
|
||||
// make a large utf8 name consisting of non-leading chars
|
||||
std::string s_utf8;
|
||||
|
||||
for (unsigned int i = 0; i < N; ++i) s_utf8 += "\x82";
|
||||
for (unsigned int i = 0; i < N; ++i)
|
||||
s_utf8 += "\x82";
|
||||
|
||||
xml_document doc;
|
||||
doc.append_child().set_name(s_utf8.c_str());
|
||||
@ -416,22 +422,22 @@ TEST(write_unicode_invalid_utf16)
|
||||
if (wcharsize == 2)
|
||||
{
|
||||
// check non-terminated degenerate handling
|
||||
#ifdef U_LITERALS
|
||||
#ifdef U_LITERALS
|
||||
CHECK(test_write_unicode_invalid(L"a\uda1d", "a"));
|
||||
CHECK(test_write_unicode_invalid(L"a\uda1d_", "a_"));
|
||||
#else
|
||||
#else
|
||||
CHECK(test_write_unicode_invalid(L"a\xda1d", "a"));
|
||||
CHECK(test_write_unicode_invalid(L"a\xda1d_", "a_"));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// check incorrect leading code
|
||||
#ifdef U_LITERALS
|
||||
#ifdef U_LITERALS
|
||||
CHECK(test_write_unicode_invalid(L"a\ude24", "a"));
|
||||
CHECK(test_write_unicode_invalid(L"a\ude24_", "a_"));
|
||||
#else
|
||||
#else
|
||||
CHECK(test_write_unicode_invalid(L"a\xde24", "a"));
|
||||
CHECK(test_write_unicode_invalid(L"a\xde24_", "a_"));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#else
|
||||
@ -573,15 +579,13 @@ TEST(write_pcdata_whitespace_fixedpoint)
|
||||
0,
|
||||
parse_ws_pcdata,
|
||||
parse_ws_pcdata_single,
|
||||
parse_trim_pcdata
|
||||
};
|
||||
parse_trim_pcdata};
|
||||
|
||||
static const unsigned int flags_format[] =
|
||||
{
|
||||
0,
|
||||
format_raw,
|
||||
format_indent
|
||||
};
|
||||
format_indent};
|
||||
|
||||
for (unsigned int i = 0; i < sizeof(flags_parse) / sizeof(flags_parse[0]); ++i)
|
||||
{
|
||||
@ -618,7 +622,7 @@ TEST_XML(write_no_empty_element_tags, "<node><child1/><child2>text</child2><chil
|
||||
|
||||
TEST_XML_FLAGS(write_roundtrip, "<node><child1 attr1='value1' attr2='value2'/><child2 attr='value'>pre<![CDATA[data]]>mid<text&escape<!--comment--><test/>post<?pi value?>fin</child2><child3/></node>", parse_full)
|
||||
{
|
||||
const unsigned int flagset[] = { format_indent, format_raw, format_no_declaration, format_indent_attributes, format_no_empty_element_tags };
|
||||
const unsigned int flagset[] = {format_indent, format_raw, format_no_declaration, format_indent_attributes, format_no_empty_element_tags};
|
||||
size_t flagcount = sizeof(flagset) / sizeof(flagset[0]);
|
||||
|
||||
for (size_t i = 0; i < (size_t(1) << flagcount); ++i)
|
||||
@ -669,7 +673,7 @@ TEST(write_flush_coverage)
|
||||
}
|
||||
|
||||
#ifndef PUGIXML_NO_EXCEPTIONS
|
||||
struct throwing_writer: xml_writer
|
||||
struct throwing_writer : xml_writer
|
||||
{
|
||||
virtual void write(const void*, size_t) PUGIXML_OVERRIDE
|
||||
{
|
||||
|
||||
@ -5,10 +5,10 @@
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using namespace pugi;
|
||||
|
||||
@ -24,7 +24,8 @@ TEST(xpath_allocator_many_pages)
|
||||
{
|
||||
std::basic_string<char_t> query = STR("0");
|
||||
|
||||
for (int i = 0; i < 128; ++i) query += STR("+string-length('abcdefgh')");
|
||||
for (int i = 0; i < 128; ++i)
|
||||
query += STR("+string-length('abcdefgh')");
|
||||
|
||||
CHECK_XPATH_NUMBER(xml_node(), query.c_str(), 1024);
|
||||
}
|
||||
@ -33,7 +34,8 @@ TEST(xpath_allocator_large_page)
|
||||
{
|
||||
std::basic_string<char_t> query;
|
||||
|
||||
for (int i = 0; i < 1024; ++i) query += STR("abcdefgh");
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
query += STR("abcdefgh");
|
||||
|
||||
CHECK_XPATH_NUMBER(xml_node(), (STR("string-length('") + query + STR("')")).c_str(), 8192);
|
||||
}
|
||||
@ -162,7 +164,8 @@ TEST(xpath_sort_random_medium)
|
||||
|
||||
xpath_node_set_tester tester(copy, "sorted order failed");
|
||||
|
||||
for (unsigned int i = 2; i < 39; ++i) tester % i;
|
||||
for (unsigned int i = 2; i < 39; ++i)
|
||||
tester % i;
|
||||
}
|
||||
|
||||
TEST(xpath_sort_random_large)
|
||||
@ -191,7 +194,8 @@ TEST(xpath_sort_random_large)
|
||||
|
||||
xpath_node_set_tester tester(copy, "sorted order failed");
|
||||
|
||||
for (unsigned int i = 2; i < 129; ++i) tester % i;
|
||||
for (unsigned int i = 2; i < 129; ++i)
|
||||
tester % i;
|
||||
}
|
||||
|
||||
TEST(xpath_long_numbers_parse)
|
||||
@ -247,7 +251,8 @@ TEST(xpath_denorm_numbers)
|
||||
// 10^-318 - double denormal
|
||||
for (int i = 0; i < 106; ++i)
|
||||
{
|
||||
if (i != 0) query += STR(" * ");
|
||||
if (i != 0)
|
||||
query += STR(" * ");
|
||||
query += STR("0.001");
|
||||
}
|
||||
|
||||
@ -716,7 +721,7 @@ TEST(xpath_sort_crossdoc_different_depth)
|
||||
TEST_XML(xpath_sort_empty_node, "<node><child1/><child2/></node>")
|
||||
{
|
||||
xml_node n = doc.child(STR("node"));
|
||||
xpath_node nodes[] = { n.child(STR("child2")), xml_node(), n.child(STR("child1")), xml_node() };
|
||||
xpath_node nodes[] = {n.child(STR("child2")), xml_node(), n.child(STR("child1")), xml_node()};
|
||||
xpath_node_set ns(nodes, nodes + sizeof(nodes) / sizeof(nodes[0]));
|
||||
|
||||
ns.sort();
|
||||
@ -728,9 +733,10 @@ TEST(xpath_allocate_string_out_of_memory)
|
||||
{
|
||||
std::basic_string<char_t> query;
|
||||
|
||||
for (int i = 0; i < 1024; ++i) query += STR("abcdefgh");
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
query += STR("abcdefgh");
|
||||
|
||||
test_runner::_memory_fail_threshold = 8*1024;
|
||||
test_runner::_memory_fail_threshold = 8 * 1024;
|
||||
|
||||
#ifndef __DMC__ // DigitalMars exception handling crashes instead of catching the exception...
|
||||
CHECK_ALLOC_FAIL(CHECK(!xpath_query(query.c_str())));
|
||||
|
||||
@ -430,7 +430,6 @@ TEST_XML(xpath_api_nodeset_move_ctor, "<node><foo/><foo/><bar/></node>")
|
||||
CHECK(move[1] == doc.first_child().first_child());
|
||||
}
|
||||
|
||||
|
||||
TEST_XML(xpath_api_nodeset_move_ctor_single, "<node><foo/><foo/><bar/></node>")
|
||||
{
|
||||
xpath_node_set set = doc.select_nodes(STR("node/bar"));
|
||||
|
||||
@ -829,7 +829,8 @@ TEST(xpath_string_translate_table_out_of_memory)
|
||||
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
{
|
||||
if (i != 0) query += STR(",");
|
||||
if (i != 0)
|
||||
query += STR(",");
|
||||
query += STR("translate('a','a','A')");
|
||||
}
|
||||
|
||||
|
||||
@ -109,8 +109,7 @@ TEST(xpath_parse_paths_valid)
|
||||
STR("/foo|/bar[@id='1234']"), STR("count(//author/attribute::*)"), STR("/child::node()/child::node()[@id='_13563275']"),
|
||||
STR("10 + (count(descendant::author) * 5)"), STR("10 + count(descendant::author) * 5"), STR("2 + (2 * 5)"), STR("//foo:bar"),
|
||||
STR("count(//author)+5"), STR("count(//author)+count(//author/attribute::*)"), STR("/foo/bar[@a='1' and @c!='2']"),
|
||||
STR("12 + (count(//author)+count(//author/attribute::*)) div 2"), STR("text()[.='foo']"), STR("/*/*[@id='123']")
|
||||
STR("/foo/bar[@a='1' and @b='2']"), STR("/foo/bar[@a='1' and @b!='2']"), STR("//attribute::*[.!='crunchy']"),
|
||||
STR("12 + (count(//author)+count(//author/attribute::*)) div 2"), STR("text()[.='foo']"), STR("/*/*[@id='123']") STR("/foo/bar[@a='1' and @b='2']"), STR("/foo/bar[@a='1' and @b!='2']"), STR("//attribute::*[.!='crunchy']"),
|
||||
STR("'//*[contains(string(text()),\"yada yada\")]'"),
|
||||
|
||||
// From ajaxslt tests
|
||||
@ -173,8 +172,7 @@ TEST(xpath_parse_paths_valid)
|
||||
STR("**..**"),
|
||||
|
||||
// Miscellaneous
|
||||
STR("..***..***.***.***..***..***..")
|
||||
};
|
||||
STR("..***..***.***.***..***..***..")};
|
||||
|
||||
for (size_t i = 0; i < sizeof(paths) / sizeof(paths[0]); ++i)
|
||||
{
|
||||
@ -188,45 +186,97 @@ TEST(xpath_parse_paths_valid_unicode)
|
||||
// From ajaxslt
|
||||
const wchar_t* paths[] =
|
||||
{
|
||||
#ifdef U_LITERALS
|
||||
L"/descendant-or-self::\u90e8\u5206", L"//\u90e8\u5206", L"substring('\uff11\uff12\uff13\uff14\uff15', 0, 3)", L"//\u30bf\u30a4\u30c8\u30eb | //\u30ea\u30f3\u30af",
|
||||
L"\u8b0e//\u30bf\u30a4\u30c8\u30eb", L"//*[@\u30c7\u30b9\u30c6\u30a3\u30cd\u30a4\u30b7\u30e7\u30f3]", L"\u30da\u30fc\u30b8 = '\u304b\u3089'",
|
||||
#ifdef U_LITERALS
|
||||
L"/descendant-or-self::\u90e8\u5206",
|
||||
L"//\u90e8\u5206",
|
||||
L"substring('\uff11\uff12\uff13\uff14\uff15', 0, 3)",
|
||||
L"//\u30bf\u30a4\u30c8\u30eb | //\u30ea\u30f3\u30af",
|
||||
L"\u8b0e//\u30bf\u30a4\u30c8\u30eb",
|
||||
L"//*[@\u30c7\u30b9\u30c6\u30a3\u30cd\u30a4\u30b7\u30e7\u30f3]",
|
||||
L"\u30da\u30fc\u30b8 = '\u304b\u3089'",
|
||||
L"concat(substring-before(@\u30a4\u30e1\u30fc\u30b8,'\u76ee\u5370'),'\u30a2\u30a4\u30b3\u30f3',substring-after(@\u30a4\u30e1\u30fc\u30b8,'\u76ee\u5370'))",
|
||||
L"\u30bd\u30fc\u30b9|\u30c7\u30b9\u30c6\u30a3\u30cd\u30a4\u30b7\u30e7\u30f3", L"\u30da\u30fc\u30b8 != '\u307e\u3067' and \u30da\u30fc\u30b8 != '\u304b\u3089'",
|
||||
L"substring-after(\u30a2\u30a4\u30b3\u30f3/@\u30a4\u30e1\u30fc\u30b8, '/\u5730\u56f3\u30d5\u30a1\u30a4\u30eb/\u76ee\u5370')", L"child::\u6bb5\u843d",
|
||||
L"substring-before(\u6587\u5b57\u5217, \u6587\u5b57)", L"\u30bb\u30b0\u30e1\u30f3\u30c8/@\u6642\u523b", L"attribute::\u540d\u524d", L"descendant::\u6bb5\u843d",
|
||||
L"ancestor::\u90e8\u5206", L"ancestor-or-self::\u90e8\u5206", L"descendant-or-self::\u6bb5\u843d", L"self::\u6bb5\u843d", L"child::\u7ae0/descendant::\u6bb5\u843d",
|
||||
L"child::*/child::\u6bb5\u843d", L"/descendant::\u6bb5\u843d", L"/descendant::\u9806\u5e8f\u30ea\u30b9\u30c8/child::\u9805\u76ee", L"child::\u6bb5\u843d[position()=1]",
|
||||
L"child::\u6bb5\u843d[position()=last()]", L"child::\u6bb5\u843d[position()=last()-1]", L"child::\u6bb5\u843d[position()>1]", L"following-sibling::\u7ae0[position()=1]",
|
||||
L"preceding-sibling::\u7ae0[position()=1]", L"/descendant::\u56f3\u8868[position()=42]", L"/child::\u6587\u66f8/child::\u7ae0[position()=5]/child::\u7bc0[position()=2]",
|
||||
L"child::\u6bb5\u843d[attribute::\u30bf\u30a4\u30d7='\u8b66\u544a']", L"child::\u6bb5\u843d[attribute::\u30bf\u30a4\u30d7='\u8b66\u544a'][position()=5]",
|
||||
L"child::\u6bb5\u843d[position()=5][attribute::\u30bf\u30a4\u30d7='\u8b66\u544a']", L"child::\u7ae0[child::\u30bf\u30a4\u30c8\u30eb='\u306f\u3058\u3081\u306b']",
|
||||
L"child::\u7ae0[child::\u30bf\u30a4\u30c8\u30eb]", L"child::*[self::\u7ae0 or self::\u4ed8\u9332]", L"child::*[self::\u7ae0 or self::\u4ed8\u9332][position()=last()]",
|
||||
#else
|
||||
L"/descendant-or-self::\x90e8\x5206", L"//\x90e8\x5206", L"substring('\xff11\xff12\xff13\xff14\xff15', 0, 3)", L"//\x30bf\x30a4\x30c8\x30eb | //\x30ea\x30f3\x30af",
|
||||
L"\x8b0e//\x30bf\x30a4\x30c8\x30eb", L"//*[@\x30c7\x30b9\x30c6\x30a3\x30cd\x30a4\x30b7\x30e7\x30f3]", L"\x30da\x30fc\x30b8 = '\x304b\x3089'",
|
||||
L"\u30bd\u30fc\u30b9|\u30c7\u30b9\u30c6\u30a3\u30cd\u30a4\u30b7\u30e7\u30f3",
|
||||
L"\u30da\u30fc\u30b8 != '\u307e\u3067' and \u30da\u30fc\u30b8 != '\u304b\u3089'",
|
||||
L"substring-after(\u30a2\u30a4\u30b3\u30f3/@\u30a4\u30e1\u30fc\u30b8, '/\u5730\u56f3\u30d5\u30a1\u30a4\u30eb/\u76ee\u5370')",
|
||||
L"child::\u6bb5\u843d",
|
||||
L"substring-before(\u6587\u5b57\u5217, \u6587\u5b57)",
|
||||
L"\u30bb\u30b0\u30e1\u30f3\u30c8/@\u6642\u523b",
|
||||
L"attribute::\u540d\u524d",
|
||||
L"descendant::\u6bb5\u843d",
|
||||
L"ancestor::\u90e8\u5206",
|
||||
L"ancestor-or-self::\u90e8\u5206",
|
||||
L"descendant-or-self::\u6bb5\u843d",
|
||||
L"self::\u6bb5\u843d",
|
||||
L"child::\u7ae0/descendant::\u6bb5\u843d",
|
||||
L"child::*/child::\u6bb5\u843d",
|
||||
L"/descendant::\u6bb5\u843d",
|
||||
L"/descendant::\u9806\u5e8f\u30ea\u30b9\u30c8/child::\u9805\u76ee",
|
||||
L"child::\u6bb5\u843d[position()=1]",
|
||||
L"child::\u6bb5\u843d[position()=last()]",
|
||||
L"child::\u6bb5\u843d[position()=last()-1]",
|
||||
L"child::\u6bb5\u843d[position()>1]",
|
||||
L"following-sibling::\u7ae0[position()=1]",
|
||||
L"preceding-sibling::\u7ae0[position()=1]",
|
||||
L"/descendant::\u56f3\u8868[position()=42]",
|
||||
L"/child::\u6587\u66f8/child::\u7ae0[position()=5]/child::\u7bc0[position()=2]",
|
||||
L"child::\u6bb5\u843d[attribute::\u30bf\u30a4\u30d7='\u8b66\u544a']",
|
||||
L"child::\u6bb5\u843d[attribute::\u30bf\u30a4\u30d7='\u8b66\u544a'][position()=5]",
|
||||
L"child::\u6bb5\u843d[position()=5][attribute::\u30bf\u30a4\u30d7='\u8b66\u544a']",
|
||||
L"child::\u7ae0[child::\u30bf\u30a4\u30c8\u30eb='\u306f\u3058\u3081\u306b']",
|
||||
L"child::\u7ae0[child::\u30bf\u30a4\u30c8\u30eb]",
|
||||
L"child::*[self::\u7ae0 or self::\u4ed8\u9332]",
|
||||
L"child::*[self::\u7ae0 or self::\u4ed8\u9332][position()=last()]",
|
||||
#else
|
||||
L"/descendant-or-self::\x90e8\x5206",
|
||||
L"//\x90e8\x5206",
|
||||
L"substring('\xff11\xff12\xff13\xff14\xff15', 0, 3)",
|
||||
L"//\x30bf\x30a4\x30c8\x30eb | //\x30ea\x30f3\x30af",
|
||||
L"\x8b0e//\x30bf\x30a4\x30c8\x30eb",
|
||||
L"//*[@\x30c7\x30b9\x30c6\x30a3\x30cd\x30a4\x30b7\x30e7\x30f3]",
|
||||
L"\x30da\x30fc\x30b8 = '\x304b\x3089'",
|
||||
L"concat(substring-before(@\x30a4\x30e1\x30fc\x30b8,'\x76ee\x5370'),'\x30a2\x30a4\x30b3\x30f3',substring-after(@\x30a4\x30e1\x30fc\x30b8,'\x76ee\x5370'))",
|
||||
L"\x30bd\x30fc\x30b9|\x30c7\x30b9\x30c6\x30a3\x30cd\x30a4\x30b7\x30e7\x30f3", L"\x30da\x30fc\x30b8 != '\x307e\x3067' and \x30da\x30fc\x30b8 != '\x304b\x3089'",
|
||||
L"substring-after(\x30a2\x30a4\x30b3\x30f3/@\x30a4\x30e1\x30fc\x30b8, '/\x5730\x56f3\x30d5\x30a1\x30a4\x30eb/\x76ee\x5370')", L"child::\x6bb5\x843d",
|
||||
L"substring-before(\x6587\x5b57\x5217, \x6587\x5b57)", L"\x30bb\x30b0\x30e1\x30f3\x30c8/@\x6642\x523b", L"attribute::\x540d\x524d", L"descendant::\x6bb5\x843d",
|
||||
L"ancestor::\x90e8\x5206", L"ancestor-or-self::\x90e8\x5206", L"descendant-or-self::\x6bb5\x843d", L"self::\x6bb5\x843d", L"child::\x7ae0/descendant::\x6bb5\x843d",
|
||||
L"child::*/child::\x6bb5\x843d", L"/descendant::\x6bb5\x843d", L"/descendant::\x9806\x5e8f\x30ea\x30b9\x30c8/child::\x9805\x76ee", L"child::\x6bb5\x843d[position()=1]",
|
||||
L"child::\x6bb5\x843d[position()=last()]", L"child::\x6bb5\x843d[position()=last()-1]", L"child::\x6bb5\x843d[position()>1]", L"following-sibling::\x7ae0[position()=1]",
|
||||
L"preceding-sibling::\x7ae0[position()=1]", L"/descendant::\x56f3\x8868[position()=42]", L"/child::\x6587\x66f8/child::\x7ae0[position()=5]/child::\x7bc0[position()=2]",
|
||||
L"child::\x6bb5\x843d[attribute::\x30bf\x30a4\x30d7='\x8b66\x544a']", L"child::\x6bb5\x843d[attribute::\x30bf\x30a4\x30d7='\x8b66\x544a'][position()=5]",
|
||||
L"child::\x6bb5\x843d[position()=5][attribute::\x30bf\x30a4\x30d7='\x8b66\x544a']", L"child::\x7ae0[child::\x30bf\x30a4\x30c8\x30eb='\x306f\x3058\x3081\x306b']",
|
||||
L"child::\x7ae0[child::\x30bf\x30a4\x30c8\x30eb]", L"child::*[self::\x7ae0 or self::\x4ed8\x9332]", L"child::*[self::\x7ae0 or self::\x4ed8\x9332][position()=last()]",
|
||||
#endif
|
||||
L"\x30bd\x30fc\x30b9|\x30c7\x30b9\x30c6\x30a3\x30cd\x30a4\x30b7\x30e7\x30f3",
|
||||
L"\x30da\x30fc\x30b8 != '\x307e\x3067' and \x30da\x30fc\x30b8 != '\x304b\x3089'",
|
||||
L"substring-after(\x30a2\x30a4\x30b3\x30f3/@\x30a4\x30e1\x30fc\x30b8, '/\x5730\x56f3\x30d5\x30a1\x30a4\x30eb/\x76ee\x5370')",
|
||||
L"child::\x6bb5\x843d",
|
||||
L"substring-before(\x6587\x5b57\x5217, \x6587\x5b57)",
|
||||
L"\x30bb\x30b0\x30e1\x30f3\x30c8/@\x6642\x523b",
|
||||
L"attribute::\x540d\x524d",
|
||||
L"descendant::\x6bb5\x843d",
|
||||
L"ancestor::\x90e8\x5206",
|
||||
L"ancestor-or-self::\x90e8\x5206",
|
||||
L"descendant-or-self::\x6bb5\x843d",
|
||||
L"self::\x6bb5\x843d",
|
||||
L"child::\x7ae0/descendant::\x6bb5\x843d",
|
||||
L"child::*/child::\x6bb5\x843d",
|
||||
L"/descendant::\x6bb5\x843d",
|
||||
L"/descendant::\x9806\x5e8f\x30ea\x30b9\x30c8/child::\x9805\x76ee",
|
||||
L"child::\x6bb5\x843d[position()=1]",
|
||||
L"child::\x6bb5\x843d[position()=last()]",
|
||||
L"child::\x6bb5\x843d[position()=last()-1]",
|
||||
L"child::\x6bb5\x843d[position()>1]",
|
||||
L"following-sibling::\x7ae0[position()=1]",
|
||||
L"preceding-sibling::\x7ae0[position()=1]",
|
||||
L"/descendant::\x56f3\x8868[position()=42]",
|
||||
L"/child::\x6587\x66f8/child::\x7ae0[position()=5]/child::\x7bc0[position()=2]",
|
||||
L"child::\x6bb5\x843d[attribute::\x30bf\x30a4\x30d7='\x8b66\x544a']",
|
||||
L"child::\x6bb5\x843d[attribute::\x30bf\x30a4\x30d7='\x8b66\x544a'][position()=5]",
|
||||
L"child::\x6bb5\x843d[position()=5][attribute::\x30bf\x30a4\x30d7='\x8b66\x544a']",
|
||||
L"child::\x7ae0[child::\x30bf\x30a4\x30c8\x30eb='\x306f\x3058\x3081\x306b']",
|
||||
L"child::\x7ae0[child::\x30bf\x30a4\x30c8\x30eb]",
|
||||
L"child::*[self::\x7ae0 or self::\x4ed8\x9332]",
|
||||
L"child::*[self::\x7ae0 or self::\x4ed8\x9332][position()=last()]",
|
||||
#endif
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < sizeof(paths) / sizeof(paths[0]); ++i)
|
||||
{
|
||||
#if defined(PUGIXML_WCHAR_MODE)
|
||||
#if defined(PUGIXML_WCHAR_MODE)
|
||||
xpath_query q(paths[i]);
|
||||
#elif !defined(PUGIXML_NO_STL)
|
||||
#elif !defined(PUGIXML_NO_STL)
|
||||
std::basic_string<char> path_utf8 = as_utf8(paths[i]);
|
||||
xpath_query q(path_utf8.c_str());
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -250,8 +300,8 @@ TEST(xpath_parse_invalid)
|
||||
STR("|/gjs"), STR("+3"), STR("/html/body/p != ---'div'/a"), STR(""), STR("@"), STR("#akf"), STR(",")
|
||||
|
||||
// Miscellaneous
|
||||
STR("..."), STR("...."), STR("**"), STR("****"), STR("******"), STR("..***..***.***.***..***..***..*"), STR("/[1]")
|
||||
};
|
||||
STR("..."),
|
||||
STR("...."), STR("**"), STR("****"), STR("******"), STR("..***..***.***.***..***..***..*"), STR("/[1]")};
|
||||
|
||||
for (size_t i = 0; i < sizeof(paths) / sizeof(paths[0]); ++i)
|
||||
{
|
||||
|
||||
@ -404,11 +404,11 @@ TEST(xpath_variables_name_case)
|
||||
TEST(xpath_variables_name_unicode)
|
||||
{
|
||||
#ifdef PUGIXML_WCHAR_MODE
|
||||
#ifdef U_LITERALS
|
||||
#ifdef U_LITERALS
|
||||
const char_t* name = L"\u0400\u203D";
|
||||
#else
|
||||
#else
|
||||
const char_t* name = L"\x0400\x203D";
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
const char_t* name = "\xd0\x80\xe2\x80\xbd";
|
||||
#endif
|
||||
|
||||
@ -4,8 +4,8 @@
|
||||
|
||||
#include "test.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
using namespace pugi;
|
||||
|
||||
|
||||
@ -111,7 +111,6 @@ TEST_XML(xpath_xalan_match_1, "<root><x spot='a' num='1'/><x spot='b' num='2'/><
|
||||
CHECK_XPATH_NODESET(c, STR("x[(((((2*10)-4)+9) div 5) mod 3)]")) % 6;
|
||||
}
|
||||
|
||||
|
||||
TEST_XML(xpath_xalan_match_2, "<doc><l1><v2>doc-l1-v2</v2><x2>doc-l1-x2</x2><l2><v3>doc-l1-l2-v3</v3><w3>doc-l1-l2-w3</w3><x3>doc-l1-l2-x3</x3><y3>doc-l1-l2-y3</y3><l3><v4>doc-l1-l2-l3-v4</v4><x4>doc-l1-l2-l3-x4</x4></l3></l2></l1></doc>")
|
||||
{
|
||||
CHECK_XPATH_STRING(doc, STR("doc/l1/v2"), STR("doc-l1-v2"));
|
||||
|
||||
@ -5,10 +5,12 @@
|
||||
static bool test_narrow(const std::string& result, const char* expected, size_t length)
|
||||
{
|
||||
// check result
|
||||
if (result != std::string(expected, expected + length)) return false;
|
||||
if (result != std::string(expected, expected + length))
|
||||
return false;
|
||||
|
||||
// check comparison operator (incorrect implementation can theoretically early-out on zero terminators...)
|
||||
if (length > 0 && result == std::string(expected, expected + length - 1) + "?") return false;
|
||||
if (length > 0 && result == std::string(expected, expected + length - 1) + "?")
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
struct xml_writer_string: public pugi::xml_writer
|
||||
struct xml_writer_string : public pugi::xml_writer
|
||||
{
|
||||
std::string contents;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user