summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArseny Kapoulkine <arseny.kapoulkine@gmail.com>2017-06-22 22:43:55 -0700
committerArseny Kapoulkine <arseny.kapoulkine@gmail.com>2017-06-22 22:51:41 -0700
commit0fff224d7287de8f52927179423fc499fcf2fbc1 (patch)
tree2b849559706e4b30f5070862db8e9c8782b28e42
parent20a8eced3b86c03d9dce7823feb3536a75c78b3e (diff)
tests: Add -fshort-wchar tests
These tests are very tricky - in general -fshort-wchar is a dangerous option because, since the standard library is not compiled with it, you can't use any functions from either C or C++ standard library without getting ABI mismatch. The reason we want to use this is to do coverage testing on UTF32->UTF16 and UTF16->UTF32 conversion paths, that generally aren't hit on gcc/clang. To do this, we carefully work around any internal calls to wcslen/wcscmp that pugixml might be doing and don't use any wstring functions.
-rw-r--r--Makefile4
-rw-r--r--tests/test_short_wchar.cpp80
2 files changed, 84 insertions, 0 deletions
diff --git a/Makefile b/Makefile
index edc3c42..4b340a3 100644
--- a/Makefile
+++ b/Makefile
@@ -99,6 +99,10 @@ $(BUILD)/%.o: %
@mkdir -p $(dir $@)
$(CXX) $< $(CXXFLAGS) -c -MMD -MP -o $@
+$(BUILD)/tests/test_short_wchar.cpp.o: tests/test_short_wchar.cpp
+ @mkdir -p $(dir $@)
+ $(CXX) $< $(CXXFLAGS) -fshort-wchar -c -MMD -MP -o $@
+
-include $(OBJECTS:.o=.d)
.SECONDEXPANSION:
diff --git a/tests/test_short_wchar.cpp b/tests/test_short_wchar.cpp
new file mode 100644
index 0000000..2892495
--- /dev/null
+++ b/tests/test_short_wchar.cpp
@@ -0,0 +1,80 @@
+#if defined(__GNUC__) && __WCHAR_MAX__ == 0xffff
+#define PUGIXML_HEADER_ONLY
+#define PUGIXML_WCHAR_MODE
+#define PUGIXML_NO_STL
+#define pugi pugisw
+
+#include "test.hpp"
+
+#include <string.h>
+
+using namespace pugi;
+
+TEST(short_wchar_parse_utf32_be)
+{
+ xml_document doc;
+ CHECK(doc.load_buffer("\x00\x00\xfe\xff\x00\x00\x00t\x00\x00\x00o\x00\x00\x00s\x00\x00\x00t", 20, parse_fragment));
+
+ const char_t* text = doc.text().get();
+
+ CHECK(text[0] == 't');
+ CHECK(text[1] == 'o');
+ CHECK(text[2] == 's');
+ CHECK(text[3] == 't');
+ CHECK(text[4] == 0);
+}
+
+TEST(short_wchar_parse_utf32_le)
+{
+ xml_document doc;
+ CHECK(doc.load_buffer("\xff\xfe\x00\x00t\x00\x00\x00o\x00\x00\x00s\x00\x00\x00t\x00\x00\x00", 20, parse_fragment));
+
+ const char_t* text = doc.text().get();
+
+ CHECK(text[0] == 't');
+ CHECK(text[1] == 'o');
+ CHECK(text[2] == 's');
+ CHECK(text[3] == 't');
+ CHECK(text[4] == 0);
+}
+
+struct buffer_writer: xml_writer
+{
+ char buffer[128];
+ size_t offset;
+
+ buffer_writer(): offset(0)
+ {
+ }
+
+ virtual void write(const void* data, size_t size) PUGIXML_OVERRIDE
+ {
+ CHECK(offset + size <= sizeof(buffer));
+
+ memcpy(buffer + offset, data, size);
+ offset += size;
+ }
+};
+
+TEST(short_wchar_output_utf32_be)
+{
+ xml_document doc;
+ doc.append_child(node_doctype);
+
+ buffer_writer writer;
+ doc.print(writer, L"", format_raw, encoding_utf32_be);
+
+ CHECK(memcmp(writer.buffer, "\0\0\0<\0\0\0!\0\0\0D\0\0\0O\0\0\0C\0\0\0T\0\0\0Y\0\0\0P\0\0\0E\0\0\0>", 40) == 0);
+}
+
+TEST(short_wchar_output_utf32_le)
+{
+ xml_document doc;
+ doc.append_child(node_doctype);
+
+ buffer_writer writer;
+ doc.print(writer, L"", format_raw, encoding_utf32_le);
+
+ CHECK(memcmp(writer.buffer, "<\0\0\0!\0\0\0D\0\0\0O\0\0\0C\0\0\0T\0\0\0Y\0\0\0P\0\0\0E\0\0\0>\0\0\0", 40) == 0);
+}
+#endif