#include "pch.h"
#include <gtest/gtest.h>
extern "C"
{
	#include "../../Externals/xdiff/xinclude.h"
}

#define sl(x) x, static_cast<long>(strlen(x))

TEST(xutils, xdl_recmatch)
{
	auto comp = [](const char* data1, const char* data2, int flags)
	{
		return xdl_recmatch(data1, static_cast<long>(strlen(data1)), data2, static_cast<long>(strlen(data2)), flags) != 0;
	};
	// flags = 0
	EXPECT_TRUE(comp("", "", 0));
	EXPECT_TRUE(comp("1234a", "1234a", 0));
	EXPECT_FALSE(comp("1234a", "1234b", 0));
	EXPECT_FALSE(comp("a1234", "b1234", 0));

	// XDF_IGNORE_NUMBERS
	EXPECT_TRUE(comp("1234a", "1234a", XDF_IGNORE_NUMBERS));
	EXPECT_TRUE(comp("1234a", "2a", XDF_IGNORE_NUMBERS));
	EXPECT_TRUE(comp("a1234", "a", XDF_IGNORE_NUMBERS));
	EXPECT_TRUE(comp("1234a", "2345a", XDF_IGNORE_NUMBERS));
	EXPECT_TRUE(comp("1234a\r\n", "2345a\r\n", XDF_IGNORE_NUMBERS));
	EXPECT_FALSE(comp("1234a", "2345b", XDF_IGNORE_NUMBERS));
	EXPECT_FALSE(comp("1234a\r", "2345a\n", XDF_IGNORE_NUMBERS));
	EXPECT_TRUE(comp("a1234", "a2345", XDF_IGNORE_NUMBERS));
	EXPECT_TRUE(comp("a1234\r\n", "a2345\r\n", XDF_IGNORE_NUMBERS));
	EXPECT_FALSE(comp("a1234", "b2345", XDF_IGNORE_NUMBERS));
	EXPECT_FALSE(comp("a1234\n", "a2345\r\n", XDF_IGNORE_NUMBERS));

	// XDF_IGNORE_WHITESPACE
	EXPECT_TRUE(comp("1234a", "1234a", XDF_IGNORE_WHITESPACE));
	EXPECT_TRUE(comp(" 1234a", "1234a", XDF_IGNORE_WHITESPACE));
	EXPECT_TRUE(comp("1234a", " 1234a", XDF_IGNORE_WHITESPACE));
	EXPECT_TRUE(comp("1234a ", "1234a", XDF_IGNORE_WHITESPACE));
	EXPECT_TRUE(comp("1234a", "1234a ", XDF_IGNORE_WHITESPACE));
	EXPECT_TRUE(comp("1234a  ", "  1234a ", XDF_IGNORE_WHITESPACE));
	EXPECT_TRUE(comp("1234a  \n", "  1234a \n", XDF_IGNORE_WHITESPACE));
	EXPECT_FALSE(comp("1234a", "1234b", XDF_IGNORE_WHITESPACE));
	EXPECT_FALSE(comp("a1234", "b1234", XDF_IGNORE_WHITESPACE));
	EXPECT_FALSE(comp("1234a  ", "  2345a ", XDF_IGNORE_WHITESPACE));
	EXPECT_FALSE(comp("1234a  \n", "  1234a \r\n", XDF_IGNORE_WHITESPACE));

	// XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE
	EXPECT_TRUE(comp("1234a", "1234a", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE));
	EXPECT_TRUE(comp(" 1234a", "12a", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE));
	EXPECT_TRUE(comp("1234a", " a", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE));
	EXPECT_TRUE(comp("a ", "1234a", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE));
	EXPECT_TRUE(comp("1234a", "1a ", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE));
	EXPECT_FALSE(comp("1234a", "1234b", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE));
	EXPECT_FALSE(comp("a1234", "b1234", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE));
	EXPECT_TRUE(comp("1234a  ", "  2345a ", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE));
	EXPECT_TRUE(comp("1234a  \n", "  2345a \n", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE));
	EXPECT_FALSE(comp("1234b  ", "  2345a ", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE));
	EXPECT_FALSE(comp("1234  \n", "2345a \r", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE));

	// XDF_IGNORE_WHITESPACE_CHANGE
	EXPECT_TRUE(comp("1234a", "1234a", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_TRUE(comp(" 1234a", "  1234a", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_TRUE(comp(" 1234a  ", "  1234a ", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_FALSE(comp("1234a", "2345a", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_FALSE(comp(" 1234a", "1234a", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_FALSE(comp("1234a b\n", "1234ab\n", XDF_IGNORE_WHITESPACE_CHANGE));

	EXPECT_TRUE(comp(" 1234a  \r\n", "  1234a \r\n", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_TRUE(comp(" 1234a  \n", "  1234a \n", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_TRUE(comp(" 1234a  \r", "  1234a \r", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_FALSE(comp(" 1234a  \r\n", "  1234a ", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_FALSE(comp(" 1234a  \r\n", "  1234a \n", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_FALSE(comp(" 1234a  \r\n", "  1234a \r", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_FALSE(comp(" 1234a  \r", "  1234a ", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_FALSE(comp(" 1234a  \r", "  1234a \n", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_FALSE(comp(" 1234a  \r", "  1234a \r\n", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_FALSE(comp(" 1234a  \n", "  1234a ", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_FALSE(comp(" 1234a  \n", "  1234a \r", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_FALSE(comp(" 1234a  \n", "  1234a \r\n", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_FALSE(comp(" 1234a  ", "  1234a \n", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_FALSE(comp(" 1234a  ", "  1234a \r", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_FALSE(comp(" 1234a  ", "  1234a \r\n", XDF_IGNORE_WHITESPACE_CHANGE));

	// XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE_CHANGE
	EXPECT_TRUE(comp("1234a  ", "2345a ", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_TRUE(comp("1234a  \r\n", "2345a \r\n", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_FALSE(comp("1234a  ", " 2345a ", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_FALSE(comp("1234a  \r\n", " 2345a \r\n", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE_CHANGE));

	// XDF_IGNORE_WHITESPACE_AT_EOL
	EXPECT_TRUE(comp("1234a\r\n", "1234a\r\n", XDF_IGNORE_WHITESPACE_AT_EOL));
	EXPECT_TRUE(comp("1234a\r\n", "1234a \r\n", XDF_IGNORE_WHITESPACE_AT_EOL));
	EXPECT_TRUE(comp("1234a  \r\n", "1234a \r\n", XDF_IGNORE_WHITESPACE_AT_EOL));
	EXPECT_FALSE(comp("1234a\r\n", "2345a\r\n", XDF_IGNORE_WHITESPACE_AT_EOL));
	EXPECT_FALSE(comp("1234a  \r\n", "2345a \r\n", XDF_IGNORE_WHITESPACE_AT_EOL));

	// XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE_AT_EOL
	EXPECT_TRUE(comp("1234a  ", "2345a ", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE_AT_EOL));
	EXPECT_TRUE(comp("1234a  \r\n", "2345a \r\n", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE_AT_EOL));
	EXPECT_FALSE(comp("  1234a  \r\n", " 2345a \r\n", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE_AT_EOL));
	EXPECT_TRUE(comp("1234a  \r\n", "2345a\r\n", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE_AT_EOL));

	// XDF_IGNORE_CR_AT_EOL 
	EXPECT_TRUE(comp("", "", XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("\n", "\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("\n", "\r", XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("\n", "\r\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("\r", "\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("\r", "\r", XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("\r", "\r\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("\r\n", "\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("\r\n", "\r", XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("\r\n", "\r\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("1234a\n", "1234a\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("1234a\n", "1234a\r", XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("1234a\n", "1234a\r\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("1234a\r", "1234a\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("1234a\r", "1234a\r", XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("1234a\r", "1234a\r\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("1234a\r\n", "1234a\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("1234a\r\n", "1234a\r", XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("1234a\r\n", "1234a\r\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("", "\r\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("", "\r", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("", "\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("\n", "", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("\r", "", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("\r\n", "", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a", "1234a\r\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a", "1234a\r", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a", "1234a\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a\r\n", "1234a", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a\r", "1234a", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a\n", "1234a", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a\r\n", "1234b\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a\r\n", "1234b\r", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a\r\n", "1234b\r\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a\n", "1234b\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a\n", "1234b\r", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a\n", "1234b\r\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a\r", "1234b\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a\r", "1234b\r", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a\r", "1234b\r\n", XDF_IGNORE_CR_AT_EOL));

	// XDF_IGNORE_WHITESPACE_CHANGE|XDF_IGNORE_CR_AT_EOL 
	EXPECT_TRUE(comp("1234a", "1234a", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp(" 1234a", "  1234a", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp(" 1234a  ", "  1234a ", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("1234a\n", "1234a\n", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp(" 1234a\r", "  1234a\n", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp(" 1234a  \r\n", "  1234a \n", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("1234a\n", "1234a\r", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp(" 1234a\r", "  1234a\r", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp(" 1234a  \r\n", "  1234a \r", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("1234a\n", "1234a\r\n", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp(" 1234a\r", "  1234a\r\n", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp(" 1234a  \r\n", "  1234a \r\n", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a", "2345a", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp(" 1234a", "1234a", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a b\n", "1234ab\n", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a\n", "2345a\n", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp(" 1234a\r", "1234a\n", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a b\r\n", "1234ab\n", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a\n", "2345a\r", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp(" 1234a\r", "1234a\r", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a b\r\n", "1234ab\r", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a\n", "2345a\r\n", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp(" 1234a\r", "1234a\r\n", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a b\r\n", "1234ab\r\n", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));

	// XDF_IGNORE_NUMBERS | XDF_IGNORE_CR_AT_EOL 
	EXPECT_TRUE(comp("\r", "\n", XDF_IGNORE_NUMBERS | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("1234a", "1234a", XDF_IGNORE_NUMBERS | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("1234a\n", "34a\n", XDF_IGNORE_NUMBERS | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("a\r", "1234a\n", XDF_IGNORE_NUMBERS | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("1234a\n", "12a\r", XDF_IGNORE_NUMBERS | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("12a\r", "1234a\r", XDF_IGNORE_NUMBERS | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("1234a\r\n", "a\r", XDF_IGNORE_NUMBERS | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("a\r", "1234a\r\n", XDF_IGNORE_NUMBERS | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("1234a", "2345a", XDF_IGNORE_NUMBERS | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("1234a\r\n", "2345a\n", XDF_IGNORE_NUMBERS | XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a\r\n", "1234b\r\n", XDF_IGNORE_NUMBERS | XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("a1234\r\n", "b1234\r\n", XDF_IGNORE_NUMBERS | XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a", "2345b", XDF_IGNORE_NUMBERS | XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a\n", "2345a", XDF_IGNORE_NUMBERS | XDF_IGNORE_CR_AT_EOL));
}

TEST(xutils, xdl_hash_record)
{
	const char* str1 = "1\n2\r3\r\n";
	const char* ptr = str1;
	xdl_hash_record(&ptr, str1 + strlen(str1), 0);
	EXPECT_EQ(ptr, str1 + 2);
	xdl_hash_record(&ptr, str1 + strlen(str1), 0);
	EXPECT_EQ(ptr, str1 + 2 + 2);
	xdl_hash_record(&ptr, str1 + strlen(str1), 0);
	EXPECT_EQ(ptr, str1 + 2 + 2 + 3);

	const char* str2 = "1\n2\r3\r\n";
	ptr = str2;
	xdl_hash_record(&ptr, str1 + strlen(str1), XDF_IGNORE_WHITESPACE_AT_EOL);
	EXPECT_EQ(ptr, str1 + 2);
	xdl_hash_record(&ptr, str1 + strlen(str1), XDF_IGNORE_WHITESPACE_AT_EOL);
	EXPECT_EQ(ptr, str1 + 2 + 2);
	xdl_hash_record(&ptr, str1 + strlen(str1), XDF_IGNORE_WHITESPACE_AT_EOL);
	EXPECT_EQ(ptr, str1 + 2 + 2 + 3);

	auto comp = [](const char* data1, const char* data2, int flags)
	{
		const char* ptr1 = data1, * ptr2 = data2;
		return xdl_hash_record(&ptr1, ptr1 + strlen(ptr1), flags) == xdl_hash_record(&ptr2, ptr2 + strlen(ptr2), flags);
	};
	// flags = 0
	EXPECT_TRUE(comp("", "", 0));
	EXPECT_TRUE(comp("1234a", "1234a", 0));
	EXPECT_FALSE(comp("1234a", "1234b", 0));
	EXPECT_FALSE(comp("a1234", "b1234", 0));

	// XDF_IGNORE_NUMBERS
	EXPECT_TRUE(comp("1234a", "1234a", XDF_IGNORE_NUMBERS));
	EXPECT_TRUE(comp("1234a", "2a", XDF_IGNORE_NUMBERS));
	EXPECT_TRUE(comp("a1234", "a", XDF_IGNORE_NUMBERS));
	EXPECT_TRUE(comp("1234a", "2345a", XDF_IGNORE_NUMBERS));
	EXPECT_TRUE(comp("1234a\r\n", "2345a\r\n", XDF_IGNORE_NUMBERS));
	EXPECT_FALSE(comp("1234a", "2345b", XDF_IGNORE_NUMBERS));
	EXPECT_FALSE(comp("1234a\r", "2345a\n", XDF_IGNORE_NUMBERS));
	EXPECT_TRUE(comp("a1234", "a2345", XDF_IGNORE_NUMBERS));
	EXPECT_TRUE(comp("a1234\r\n", "a2345\r\n", XDF_IGNORE_NUMBERS));
	EXPECT_FALSE(comp("a1234", "b2345", XDF_IGNORE_NUMBERS));
	EXPECT_FALSE(comp("a1234\n", "a2345\r\n", XDF_IGNORE_NUMBERS));

	// XDF_IGNORE_WHITESPACE
	EXPECT_TRUE(comp("1234a", "1234a", XDF_IGNORE_WHITESPACE));
	EXPECT_TRUE(comp(" 1234a", "1234a", XDF_IGNORE_WHITESPACE));
	EXPECT_TRUE(comp("1234a", " 1234a", XDF_IGNORE_WHITESPACE));
	EXPECT_TRUE(comp("1234a ", "1234a", XDF_IGNORE_WHITESPACE));
	EXPECT_TRUE(comp("1234a", "1234a ", XDF_IGNORE_WHITESPACE));
	EXPECT_TRUE(comp("1234a  ", "  1234a ", XDF_IGNORE_WHITESPACE));
	EXPECT_TRUE(comp("1234a  \n", "  1234a \n", XDF_IGNORE_WHITESPACE));
	EXPECT_FALSE(comp("1234a", "1234b", XDF_IGNORE_WHITESPACE));
	EXPECT_FALSE(comp("a1234", "b1234", XDF_IGNORE_WHITESPACE));
	EXPECT_FALSE(comp("1234a  ", "  2345a ", XDF_IGNORE_WHITESPACE));
	EXPECT_FALSE(comp("1234a  \n", "  1234a \r\n", XDF_IGNORE_WHITESPACE));

	// XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE
	EXPECT_TRUE(comp("1234a", "1234a", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE));
	EXPECT_TRUE(comp(" 1234a", "12a", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE));
	EXPECT_TRUE(comp("1234a", " a", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE));
	EXPECT_TRUE(comp("a ", "1234a", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE));
	EXPECT_TRUE(comp("1234a", "1a ", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE));
	EXPECT_FALSE(comp("1234a", "1234b", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE));
	EXPECT_FALSE(comp("a1234", "b1234", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE));
	EXPECT_TRUE(comp("1234a  ", "  2345a ", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE));
	EXPECT_TRUE(comp("1234a  \n", "  2345a \n", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE));
	EXPECT_FALSE(comp("1234b  ", "  2345a ", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE));
	EXPECT_FALSE(comp("1234  \n", "2345a \r", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE));

	// XDF_IGNORE_WHITESPACE_CHANGE
	EXPECT_TRUE(comp("1234a", "1234a", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_TRUE(comp(" 1234a", "  1234a", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_TRUE(comp(" 1234a  ", "  1234a ", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_FALSE(comp("1234a", "2345a", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_FALSE(comp(" 1234a", "1234a", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_FALSE(comp("1234a b\n", "1234ab\n", XDF_IGNORE_WHITESPACE_CHANGE));

	EXPECT_TRUE(comp(" 1234a  \r\n", "  1234a \r\n", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_TRUE(comp(" 1234a  \n", "  1234a \n", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_TRUE(comp(" 1234a  \r", "  1234a \r", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_FALSE(comp(" 1234a  \r\n", "  1234a ", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_FALSE(comp(" 1234a  \r\n", "  1234a \n", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_FALSE(comp(" 1234a  \r\n", "  1234a \r", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_FALSE(comp(" 1234a  \r", "  1234a ", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_FALSE(comp(" 1234a  \r", "  1234a \n", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_FALSE(comp(" 1234a  \r", "  1234a \r\n", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_FALSE(comp(" 1234a  \n", "  1234a ", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_FALSE(comp(" 1234a  \n", "  1234a \r", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_FALSE(comp(" 1234a  \n", "  1234a \r\n", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_FALSE(comp(" 1234a  ", "  1234a \n", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_FALSE(comp(" 1234a  ", "  1234a \r", XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_FALSE(comp(" 1234a  ", "  1234a \r\n", XDF_IGNORE_WHITESPACE_CHANGE));

	// XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE_CHANGE
	EXPECT_TRUE(comp("1234a  ", "2345a ", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_TRUE(comp("1234a  \r\n", "2345a \r\n", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_FALSE(comp("1234a  ", " 2345a ", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE_CHANGE));
	EXPECT_FALSE(comp("1234a  \r\n", " 2345a \r\n", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE_CHANGE));

	// XDF_IGNORE_WHITESPACE_AT_EOL
	EXPECT_TRUE(comp("1234a\r\n", "1234a\r\n", XDF_IGNORE_WHITESPACE_AT_EOL));
	EXPECT_TRUE(comp("1234a\r\n", "1234a \r\n", XDF_IGNORE_WHITESPACE_AT_EOL));
	EXPECT_TRUE(comp("1234a  \r\n", "1234a \r\n", XDF_IGNORE_WHITESPACE_AT_EOL));
	EXPECT_FALSE(comp("1234a\r\n", "2345a\r\n", XDF_IGNORE_WHITESPACE_AT_EOL));
	EXPECT_FALSE(comp("1234a  \r\n", "2345a \r\n", XDF_IGNORE_WHITESPACE_AT_EOL));

	// XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE_AT_EOL
	EXPECT_TRUE(comp("1234a  ", "2345a ", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE_AT_EOL));
	EXPECT_TRUE(comp("1234a  \r\n", "2345a \r\n", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE_AT_EOL));
	EXPECT_FALSE(comp("  1234a  \r\n", " 2345a \r\n", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE_AT_EOL));
	EXPECT_TRUE(comp("1234a  \r\n", "2345a\r\n", XDF_IGNORE_NUMBERS | XDF_IGNORE_WHITESPACE_AT_EOL));

	// XDF_IGNORE_CR_AT_EOL 
	EXPECT_TRUE(comp("", "", XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("\n", "\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("\n", "\r", XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("\n", "\r\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("\r", "\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("\r", "\r", XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("\r", "\r\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("\r\n", "\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("\r\n", "\r", XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("\r\n", "\r\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("1234a\n", "1234a\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("1234a\n", "1234a\r", XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("1234a\n", "1234a\r\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("1234a\r", "1234a\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("1234a\r", "1234a\r", XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("1234a\r", "1234a\r\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("1234a\r\n", "1234a\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("1234a\r\n", "1234a\r", XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("1234a\r\n", "1234a\r\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("", "\r\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("", "\r", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("", "\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("\n", "", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("\r", "", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("\r\n", "", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a", "1234a\r\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a", "1234a\r", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a", "1234a\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a\r\n", "1234a", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a\r", "1234a", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a\n", "1234a", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a\r\n", "1234b\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a\r\n", "1234b\r", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a\r\n", "1234b\r\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a\n", "1234b\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a\n", "1234b\r", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a\n", "1234b\r\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a\r", "1234b\n", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a\r", "1234b\r", XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a\r", "1234b\r\n", XDF_IGNORE_CR_AT_EOL));

	// XDF_IGNORE_WHITESPACE_CHANGE|XDF_IGNORE_CR_AT_EOL 
	EXPECT_TRUE(comp("1234a", "1234a", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp(" 1234a", "  1234a", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp(" 1234a  ", "  1234a ", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("1234a\n", "1234a\n", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp(" 1234a\r", "  1234a\n", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp(" 1234a  \r\n", "  1234a \n", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("1234a\n", "1234a\r", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp(" 1234a\r", "  1234a\r", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp(" 1234a  \r\n", "  1234a \r", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("1234a\n", "1234a\r\n", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp(" 1234a\r", "  1234a\r\n", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp(" 1234a  \r\n", "  1234a \r\n", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a", "2345a", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp(" 1234a", "1234a", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a b\n", "1234ab\n", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a\n", "2345a\n", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp(" 1234a\r", "1234a\n", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a b\r\n", "1234ab\n", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a\n", "2345a\r", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp(" 1234a\r", "1234a\r", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a b\r\n", "1234ab\r", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a\n", "2345a\r\n", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp(" 1234a\r", "1234a\r\n", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a b\r\n", "1234ab\r\n", XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_CR_AT_EOL));

	// XDF_IGNORE_NUMBERS | XDF_IGNORE_CR_AT_EOL 
	EXPECT_TRUE(comp("\r", "\n", XDF_IGNORE_NUMBERS | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("1234a", "1234a", XDF_IGNORE_NUMBERS | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("1234a\n", "34a\n", XDF_IGNORE_NUMBERS | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("a\r", "1234a\n", XDF_IGNORE_NUMBERS | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("1234a\n", "12a\r", XDF_IGNORE_NUMBERS | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("12a\r", "1234a\r", XDF_IGNORE_NUMBERS | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("1234a\r\n", "a\r", XDF_IGNORE_NUMBERS | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("a\r", "1234a\r\n", XDF_IGNORE_NUMBERS | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("1234a", "2345a", XDF_IGNORE_NUMBERS | XDF_IGNORE_CR_AT_EOL));
	EXPECT_TRUE(comp("1234a\r\n", "2345a\n", XDF_IGNORE_NUMBERS | XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a\r\n", "1234b\r\n", XDF_IGNORE_NUMBERS | XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("a1234\r\n", "b1234\r\n", XDF_IGNORE_NUMBERS | XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a", "2345b", XDF_IGNORE_NUMBERS | XDF_IGNORE_CR_AT_EOL));
	EXPECT_FALSE(comp("1234a\n", "2345a", XDF_IGNORE_NUMBERS | XDF_IGNORE_CR_AT_EOL));
}
