From 931096bb5023fe95e049fd7f91aa799953129eb8 Mon Sep 17 00:00:00 2001 From: Adam Heinermann Date: Sat, 15 Nov 2025 01:35:07 -0800 Subject: [PATCH] feat(unicode): add 8 SUni functions --- CMakeLists.txt | 1 + CONTRIBUTING.md | 3 +- storm/Unicode.cpp | 197 ++++++ storm/Unicode.hpp | 19 + test/Unicode.cpp | 1094 +++++++++++++++++++++++++++++++++- test/stormdll/storm.def | 968 +++++++++++++++--------------- test/stormdll/stormstubs.cpp | 252 ++++---- 7 files changed, 1924 insertions(+), 610 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d4341d5..729a07c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,6 +39,7 @@ if(WHOA_STORM_FLAVOR STREQUAL "SC1") add_definitions(-DWHOA_RECT_USES_SCREEN_COORDINATES) add_definitions(-DWHOA_SSTRHASH64_SUBTRACTS) + add_definitions(-DWHOA_SUPPORTS_KOREAN_CODEPAGE) elseif(WHOA_STORM_FLAVOR STREQUAL "WOW") message(STATUS "Building Storm with World of Warcraft flavoring") else() diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 054b4a9..bfedac8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -28,6 +28,7 @@ To use a different version of Storm.dll, use the following arguments in the cmak |-----------|-------| |`-DWHOA_STORMDLL_VERSION=2016`| Starcraft 1.17 | |`-DWHOA_STORMDLL_VERSION=2007`| Starcraft 1.15.0 ~ 1.16.1 | -|`-DWHOA_STORMDLL_VERSION=2003`| Starcraft 1.10 ~ 1.14.0, Diablo II 1.10 ~ 1.13d | +|`-DWHOA_STORMDLL_VERSION=2004`| Starcraft 1.11b ~ 1.14 | +|`-DWHOA_STORMDLL_VERSION=2003`| Starcraft 1.10 ~ 1.11, Diablo II 1.10 ~ 1.13d | |`-DWHOA_STORMDLL_VERSION=2000`| Diablo 1.09, Starcraft 1.08 ~ Starcraft 1.09b, Diablo II 1.06 ~ Diablo II 1.09d, Warcraft II: BNE 2.02.1 | |`-DWHOA_STORMDLL_VERSION=1999`| Diablo 1.08, Diablo II 1.0 ~ Diablo II 1.05b | diff --git a/storm/Unicode.cpp b/storm/Unicode.cpp index 025e0b2..63540ca 100644 --- a/storm/Unicode.cpp +++ b/storm/Unicode.cpp @@ -1,4 +1,201 @@ #include "storm/Unicode.hpp" +#include "storm/Error.hpp" +#include "storm/String.hpp" + +// Windows +// https://en.wikipedia.org/wiki/Windows-1252 +const char16_t CP1252[256] = { + 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, + 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + 0x20AC, 0xFFFF, 0x201A, 0x192, 0x201E, 0x2026, 0x2020, 0x2021, + 0x2C6, 0x2030, 0x160, 0x2039, 0x152, 0xFFFF, 0x17D, 0xFFFF, + 0xFFFF, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x2DC, 0x2122, 0x161, 0x203A, 0x153, 0xFFFF, 0x17E, 0x178, + 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, + 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, + 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, + 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, + 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, + 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, + 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, + 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, + 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, +}; + +// Mac +// https://en.wikipedia.org/wiki/Mac_OS_Roman +const char16_t CP10000[256] = { + 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, + 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + 0xC4, 0xC5, 0xC7, 0xC9, 0xD1, 0xD6, 0xDC, 0xE1, + 0xE0, 0xE2, 0xE4, 0xE3, 0xE5, 0xE7, 0xE9, 0xE8, + 0xEA, 0xEB, 0xED, 0xEC, 0xEE, 0xEF, 0xF1, 0xF3, + 0xF2, 0xF4, 0xF6, 0xF5, 0xFA, 0xF9, 0xFB, 0xFC, + 0x2020, 0xB0, 0xA2, 0xA3, 0xA7, 0x2022, 0xB6, 0xDF, + 0xAE, 0xA9, 0x2122, 0xB4, 0xA8, 0x2260, 0xC6, 0xD8, + 0x221E, 0xB1, 0x2264, 0x2265, 0xA5, 0xB5, 0x2202, 0x2211, + 0x220F, 0x3C0, 0x222B, 0xAA, 0xBA, 0x2126, 0xE6, 0xF8, + 0xBF, 0xA1, 0xAC, 0x221A, 0x192, 0x2248, 0x2206, 0xAB, + 0xBB, 0x2026, 0xA0, 0xC0, 0xC3, 0xD5, 0x152, 0x153, + 0x2013, 0x2014, 0x201C, 0x201D, 0x2018, 0x2019, 0xF7, 0x25CA, + 0xFF, 0x178, 0x2044, 0xA4, 0x2039, 0x203A, 0xFB01, 0xFB02, + 0x2021, 0xB7, 0x201A, 0x201E, 0x2030, 0xC2, 0xCA, 0xC1, + 0xCB, 0xC8, 0xCD, 0xCE, 0xCF, 0xCC, 0xD3, 0xD4, + 0xFFFF, 0xD2, 0xDA, 0xDB, 0xD9, 0x131, 0x2C6, 0x2DC, + 0xAF, 0x2D8, 0x2D9, 0x2DA, 0xB8, 0x2DD, 0x2DB, 0x2C7, +}; + +// DOS +// https://en.wikipedia.org/wiki/Code_page_437 +const char16_t CP437[256] = { + 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, + 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + 0xC7, 0xFC, 0xE9, 0xE2, 0xE4, 0xE0, 0xE5, 0xE7, + 0xEA, 0xEB, 0xE8, 0xEF, 0xEE, 0xEC, 0xC4, 0xC5, + 0xC9, 0xE6, 0xC6, 0xF4, 0xF6, 0xF2, 0xFB, 0xF9, + 0xFF, 0xD6, 0xDC, 0xA2, 0xA3, 0xA5, 0x20A7, 0x192, + 0xE1, 0xED, 0xF3, 0xFA, 0xF1, 0xD1, 0xAA, 0xBA, + 0xBF, 0x2310, 0xAC, 0xBD, 0xBC, 0xA1, 0xAB, 0xBB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, + 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x3B1, 0xDF, 0x393, 0x3C0, 0x3A3, 0x3C3, 0xB5, 0x3C4, + 0x3A6, 0x398, 0x3A9, 0x3B4, 0x221E, 0x3C6, 0x3B5, 0x2229, + 0x2261, 0xB1, 0x2265, 0x2264, 0x2320, 0x2321, 0xF7, 0x2248, + 0xB0, 0x2219, 0xB7, 0x221A, 0x207F, 0xB2, 0x25A0, 0xA0, +}; + +ptrdiff_t SUniConvertCPToUTF16(const char16_t* codepage, char16_t* dest, const char* source, uint32_t destsize) { + if (destsize == 0) return 0; + + char16_t* curr = dest; + while (*source && destsize != 0) { + *curr++ = codepage[static_cast(*source)]; + source++; + destsize--; + } + + if (destsize != 0) *curr++ = '\0'; + STORM_ASSERT(curr >= dest); + STORM_ASSERT(curr - dest <= STORM_MAX_STR); + return curr - dest; +} + +ptrdiff_t SUniConvertUTF16ToCP(const char16_t* codepage, char* dest, const char16_t* source, uint32_t destsize) { + if (destsize == 0) return 0; + + char* curr = dest; + while (*source && destsize != 0) { + if (*source < 256 && *source == codepage[*source]) { + *curr++ = static_cast(*source++); + } + else { + int i = 255; + while (i > 0 && *source != codepage[i]) { + i--; + } + *curr++ = i ? i : '?'; + source++; + } + destsize--; + } + + if (destsize != 0) *curr++ = '\0'; + STORM_ASSERT(curr >= dest); + STORM_ASSERT(curr - dest <= STORM_MAX_STR); + return curr - dest; +} + +int32_t FindUTF8Character(const char* utf8String, int32_t index, int32_t direction) { + for (; index > 0; index += direction) { + char c = utf8String[index]; + if (c == '\0') break; + if ((c & 0xC0) != 0x80) break; + } + return index; +} + +ptrdiff_t STORMAPI SUniConvertUTF16ToDos(char* dest, const char16_t* source, uint32_t destsize) { + return SUniConvertUTF16ToCP(CP437, dest, source, destsize); +} + +ptrdiff_t STORMAPI SUniConvertUTF16ToMac(char* dest, const char16_t* source, uint32_t destsize) { + return SUniConvertUTF16ToCP(CP10000, dest, source, destsize); +} + +ptrdiff_t STORMAPI SUniConvertUTF16ToWin(char* dest, const char16_t* source, uint32_t destsize) { + // TODO: Starcraft flavour branches with `GetACP() == 949` (IBM Korean lang) + return SUniConvertUTF16ToCP(CP1252, dest, source, destsize); +} + +ptrdiff_t STORMAPI SUniConvertDosToUTF16(char16_t* dest, const char* source, uint32_t destsize) { + return SUniConvertCPToUTF16(CP437, dest, source, destsize); +} + +ptrdiff_t STORMAPI SUniConvertMacToUTF16(char16_t* dest, const char* source, uint32_t destsize) { + return SUniConvertCPToUTF16(CP10000, dest, source, destsize); +} + +ptrdiff_t STORMAPI SUniConvertWinToUTF16(char16_t* dest, const char* source, uint32_t destsize) { + // TODO: Starcraft flavour branches with `GetACP() == 949` (IBM Korean lang) + return SUniConvertCPToUTF16(CP1252, dest, source, destsize); +} + +int32_t STORMAPI SUniFindAfterUTF8Chr(const char* utf8String, int32_t index) { + return FindUTF8Character(utf8String, index + 1, 1); +} + +int32_t STORMAPI SUniFindUTF8ChrStart(const char* utf8String, int32_t index) { + return FindUTF8Character(utf8String, index, -1); +} uint32_t STORMAPI SUniSGetUTF8(const uint8_t* strptr, int32_t* chars) { if (chars) { diff --git a/storm/Unicode.hpp b/storm/Unicode.hpp index 7e5e5a3..f27ab92 100644 --- a/storm/Unicode.hpp +++ b/storm/Unicode.hpp @@ -2,6 +2,25 @@ #define STORM_UNICODE_HPP #include "Core.hpp" +#include + +ptrdiff_t STORMAPI SUniConvertUTF16ToDos(char* dest, const char16_t* source, uint32_t destsize); + +ptrdiff_t STORMAPI SUniConvertUTF16ToMac(char* dest, const char16_t* source, uint32_t destsize); + +ptrdiff_t STORMAPI SUniConvertUTF16ToWin(char* dest, const char16_t* source, uint32_t destsize); + +ptrdiff_t STORMAPI SUniConvertDosToUTF16(char16_t* dest, const char* source, uint32_t destsize); + +ptrdiff_t STORMAPI SUniConvertMacToUTF16(char16_t* dest, const char* source, uint32_t destsize); + +ptrdiff_t STORMAPI SUniConvertWinToUTF16(char16_t* dest, const char* source, uint32_t destsize); + +// Assumes index is within the bounds of utf8String +int32_t STORMAPI SUniFindAfterUTF8Chr(const char* utf8String, int32_t index); + +// Assumes index is within the bounds of utf8String +int32_t STORMAPI SUniFindUTF8ChrStart(const char* utf8String, int32_t index); uint32_t STORMAPI SUniSGetUTF8(const uint8_t* strptr, int32_t* chars); diff --git a/test/Unicode.cpp b/test/Unicode.cpp index f7e29db..15403ed 100644 --- a/test/Unicode.cpp +++ b/test/Unicode.cpp @@ -1,6 +1,1094 @@ #include "storm/Unicode.hpp" #include "storm/String.hpp" #include "test/Test.hpp" +#include + +constexpr uint32_t RESULT_STR_SIZE = 100; + +static std::pair make_testcase(const std::u16string& strA, const std::string& strB) { + return std::make_pair(strA, strB); +} + +TEST_CASE("SUniConvertUTF16ToDos", "[unicode]") { + SECTION("does nothing on empty dest size") { + auto result = SUniConvertUTF16ToDos(nullptr, nullptr, 0); + CHECK(result == 0); + } + + SECTION("operates on empty string") { + char resultStr[RESULT_STR_SIZE]; + const char16_t str[] = u""; + + auto result = SUniConvertUTF16ToDos(resultStr, str, RESULT_STR_SIZE); + CHECK(std::string(resultStr) == ""); + CHECK(result == 1); // wrote 1 null terminator + } + + SECTION("translates ASCII string") { + char resultStr[RESULT_STR_SIZE]; + const char16_t str[] = u"Quick lazy brown fox or something"; + + auto result = SUniConvertUTF16ToDos(resultStr, str, RESULT_STR_SIZE); + CHECK(std::string(resultStr) == "Quick lazy brown fox or something"); + CHECK(result == 34); + } + + SECTION("fails to write null terminator if string isn't long enough") { + char resultStr[RESULT_STR_SIZE]; + std::fill(std::begin(resultStr), std::end(resultStr), 0xCC); + const char16_t str[] = u"Quick lazy brown fox or something"; + + auto result = SUniConvertUTF16ToDos(resultStr, str, 5); + CHECK(std::string(resultStr, 5) == "Quick"); + CHECK(static_cast(resultStr[5]) == 0xCC); + CHECK(result == 5); + } + + SECTION("writes ??? on unsupported characters") { + char resultStr[RESULT_STR_SIZE]; + const char16_t str[] = u"\u8080\u8080lol\u8080\u8080\u8080"; + + auto result = SUniConvertUTF16ToDos(resultStr, str, RESULT_STR_SIZE); + CHECK(std::string(resultStr) == "??lol???"); + CHECK(result == 9); + } + + SECTION("translates shared ASCII characters") { + for (int i = 1; i < 128; i++) { + char16_t str[2] = { static_cast(i) }; + char resultStr[2]; + + auto result = SUniConvertUTF16ToDos(resultStr, str, 2); + INFO(i); + CHECK(resultStr[0] == static_cast(i)); + CHECK(resultStr[1] == '\0'); + CHECK(result == 2); + } + } + + SECTION("translates special characters") { + auto testCase = GENERATE( + make_testcase(u"\u00C7", "\x80"), // Ç + make_testcase(u"\u00FC", "\x81"), // ü + make_testcase(u"\u00E9", "\x82"), // é + make_testcase(u"\u00E2", "\x83"), // â + make_testcase(u"\u00E4", "\x84"), // ä + make_testcase(u"\u00E0", "\x85"), // à + make_testcase(u"\u00E5", "\x86"), // å + make_testcase(u"\u00E7", "\x87"), // ç + make_testcase(u"\u00EA", "\x88"), // ê + make_testcase(u"\u00EB", "\x89"), // ë + make_testcase(u"\u00E8", "\x8A"), // è + make_testcase(u"\u00EF", "\x8B"), // ï + make_testcase(u"\u00EE", "\x8C"), // î + make_testcase(u"\u00EC", "\x8D"), // ì + make_testcase(u"\u00C4", "\x8E"), // Ä + make_testcase(u"\u00C5", "\x8F"), // Å + make_testcase(u"\u00C9", "\x90"), // É + make_testcase(u"\u00E6", "\x91"), // æ + make_testcase(u"\u00C6", "\x92"), // Æ + make_testcase(u"\u00F4", "\x93"), // ô + make_testcase(u"\u00F6", "\x94"), // ö + make_testcase(u"\u00F2", "\x95"), // ò + make_testcase(u"\u00FB", "\x96"), // û + make_testcase(u"\u00F9", "\x97"), // ù + make_testcase(u"\u00FF", "\x98"), // ÿ + make_testcase(u"\u00D6", "\x99"), // Ö + make_testcase(u"\u00DC", "\x9A"), // Ü + make_testcase(u"\u00A2", "\x9B"), // ¢ + make_testcase(u"\u00A3", "\x9C"), // £ + make_testcase(u"\u00A5", "\x9D"), // ¥ + make_testcase(u"\u20A7", "\x9E"), // ₧ + make_testcase(u"\u0192", "\x9F"), // ƒ + make_testcase(u"\u00E1", "\xA0"), // á + make_testcase(u"\u00ED", "\xA1"), // í + make_testcase(u"\u00F3", "\xA2"), // ó + make_testcase(u"\u00FA", "\xA3"), // ú + make_testcase(u"\u00F1", "\xA4"), // ñ + make_testcase(u"\u00D1", "\xA5"), // Ñ + make_testcase(u"\u00AA", "\xA6"), // ª + make_testcase(u"\u00BA", "\xA7"), // º + make_testcase(u"\u00BF", "\xA8"), // ¿ + make_testcase(u"\u2310", "\xA9"), // ⌐ + make_testcase(u"\u00AC", "\xAA"), // ¬ + make_testcase(u"\u00BD", "\xAB"), // ½ + make_testcase(u"\u00BC", "\xAC"), // ¼ + make_testcase(u"\u00A1", "\xAD"), // ¡ + make_testcase(u"\u00AB", "\xAE"), // « + make_testcase(u"\u00BB", "\xAF"), // » + make_testcase(u"\u2591", "\xB0"), // ░ + make_testcase(u"\u2592", "\xB1"), // ▒ + make_testcase(u"\u2593", "\xB2"), // ▓ + make_testcase(u"\u2502", "\xB3"), // │ + make_testcase(u"\u2524", "\xB4"), // ┤ + make_testcase(u"\u2561", "\xB5"), // ╡ + make_testcase(u"\u2562", "\xB6"), // ╢ + make_testcase(u"\u2556", "\xB7"), // ╖ + make_testcase(u"\u2555", "\xB8"), // ╕ + make_testcase(u"\u2563", "\xB9"), // ╣ + make_testcase(u"\u2551", "\xBA"), // ║ + make_testcase(u"\u2557", "\xBB"), // ╗ + make_testcase(u"\u255D", "\xBC"), // ╝ + make_testcase(u"\u255C", "\xBD"), // ╜ + make_testcase(u"\u255B", "\xBE"), // ╛ + make_testcase(u"\u2510", "\xBF"), // ┐ + make_testcase(u"\u2514", "\xC0"), // └ + make_testcase(u"\u2534", "\xC1"), // ┴ + make_testcase(u"\u252C", "\xC2"), // ┬ + make_testcase(u"\u251C", "\xC3"), // ├ + make_testcase(u"\u2500", "\xC4"), // ─ + make_testcase(u"\u253C", "\xC5"), // ┼ + make_testcase(u"\u255E", "\xC6"), // ╞ + make_testcase(u"\u255F", "\xC7"), // ╟ + make_testcase(u"\u255A", "\xC8"), // ╚ + make_testcase(u"\u2554", "\xC9"), // ╔ + make_testcase(u"\u2569", "\xCA"), // ╩ + make_testcase(u"\u2566", "\xCB"), // ╦ + make_testcase(u"\u2560", "\xCC"), // ╠ + make_testcase(u"\u2550", "\xCD"), // ═ + make_testcase(u"\u256C", "\xCE"), // ╬ + make_testcase(u"\u2567", "\xCF"), // ╧ + make_testcase(u"\u2568", "\xD0"), // ╨ + make_testcase(u"\u2564", "\xD1"), // ╤ + make_testcase(u"\u2565", "\xD2"), // ╥ + make_testcase(u"\u2559", "\xD3"), // ╙ + make_testcase(u"\u2558", "\xD4"), // ╘ + make_testcase(u"\u2552", "\xD5"), // ╒ + make_testcase(u"\u2553", "\xD6"), // ╓ + make_testcase(u"\u256B", "\xD7"), // ╫ + make_testcase(u"\u256A", "\xD8"), // ╪ + make_testcase(u"\u2518", "\xD9"), // ┘ + make_testcase(u"\u250C", "\xDA"), // ┌ + make_testcase(u"\u2588", "\xDB"), // █ + make_testcase(u"\u2584", "\xDC"), // ▄ + make_testcase(u"\u258C", "\xDD"), // ▌ + make_testcase(u"\u2590", "\xDE"), // ▐ + make_testcase(u"\u2580", "\xDF"), // ▀ + make_testcase(u"\u03B1", "\xE0"), // α + make_testcase(u"\u00DF", "\xE1"), // ß + make_testcase(u"\u0393", "\xE2"), // Γ + make_testcase(u"\u03C0", "\xE3"), // π + make_testcase(u"\u03A3", "\xE4"), // Σ + make_testcase(u"\u03C3", "\xE5"), // σ + make_testcase(u"\u00B5", "\xE6"), // µ + make_testcase(u"\u03C4", "\xE7"), // τ + make_testcase(u"\u03A6", "\xE8"), // Φ + make_testcase(u"\u0398", "\xE9"), // Θ + make_testcase(u"\u03A9", "\xEA"), // Ω + make_testcase(u"\u03B4", "\xEB"), // δ + make_testcase(u"\u221E", "\xEC"), // ∞ + make_testcase(u"\u03C6", "\xED"), // φ + make_testcase(u"\u03B5", "\xEE"), // ε + make_testcase(u"\u2229", "\xEF"), // ∩ + make_testcase(u"\u2261", "\xF0"), // ≡ + make_testcase(u"\u00B1", "\xF1"), // ± + make_testcase(u"\u2265", "\xF2"), // ≥ + make_testcase(u"\u2264", "\xF3"), // ≤ + make_testcase(u"\u2320", "\xF4"), // ⌠ + make_testcase(u"\u2321", "\xF5"), // ⌡ + make_testcase(u"\u00F7", "\xF6"), // ÷ + make_testcase(u"\u2248", "\xF7"), // ≈ + make_testcase(u"\u00B0", "\xF8"), // ° + make_testcase(u"\u2219", "\xF9"), // ∙ + make_testcase(u"\u00B7", "\xFA"), // · + make_testcase(u"\u221A", "\xFB"), // √ + make_testcase(u"\u207F", "\xFC"), // ⁿ + make_testcase(u"\u00B2", "\xFD"), // ² + make_testcase(u"\u25A0", "\xFE"), // ■ + make_testcase(u"\u00A0", "\xFF") // r + ); + + char resultStr[2]; + auto result = SUniConvertUTF16ToDos(resultStr, testCase.first.c_str(), 2); + + INFO(testCase.second); + CHECK(std::string(resultStr) == testCase.second); + CHECK(result == 2); + } +} + +TEST_CASE("SUniConvertUTF16ToMac", "[unicode]") { + SECTION("does nothing on empty dest size") { + auto result = SUniConvertUTF16ToMac(nullptr, nullptr, 0); + CHECK(result == 0); + } + + SECTION("operates on empty string") { + char resultStr[RESULT_STR_SIZE]; + const char16_t str[] = u""; + + auto result = SUniConvertUTF16ToMac(resultStr, str, RESULT_STR_SIZE); + CHECK(std::string(resultStr) == ""); + CHECK(result == 1); // wrote 1 null terminator + } + + SECTION("translates ASCII string") { + char resultStr[RESULT_STR_SIZE]; + const char16_t str[] = u"Quick lazy brown fox or something"; + + auto result = SUniConvertUTF16ToMac(resultStr, str, RESULT_STR_SIZE); + CHECK(std::string(resultStr) == "Quick lazy brown fox or something"); + CHECK(result == 34); + } + + SECTION("fails to write null terminator if string isn't long enough") { + char resultStr[RESULT_STR_SIZE]; + std::fill(std::begin(resultStr), std::end(resultStr), 0xCC); + const char16_t str[] = u"Quick lazy brown fox or something"; + + auto result = SUniConvertUTF16ToMac(resultStr, str, 5); + CHECK(std::string(resultStr, 5) == "Quick"); + CHECK(static_cast(resultStr[5]) == 0xCC); + CHECK(result == 5); + } + + SECTION("writes ??? on unsupported characters") { + char resultStr[RESULT_STR_SIZE]; + const char16_t str[] = u"\u8080\u8080lol\u8080\u8080\u8080"; + + auto result = SUniConvertUTF16ToMac(resultStr, str, RESULT_STR_SIZE); + CHECK(std::string(resultStr) == "??lol???"); + CHECK(result == 9); + } + + SECTION("translates shared ASCII characters") { + for (int i = 1; i < 128; i++) { + char16_t str[2] = { static_cast(i) }; + char resultStr[2]; + + auto result = SUniConvertUTF16ToMac(resultStr, str, 2); + INFO(i); + CHECK(resultStr[0] == static_cast(i)); + CHECK(resultStr[1] == '\0'); + CHECK(result == 2); + } + } + + SECTION("translates special characters") { + auto testCase = GENERATE( + make_testcase(u"\u00C4", "\x80"), // Ä + make_testcase(u"\u00C5", "\x81"), // Å + make_testcase(u"\u00C7", "\x82"), // Ç + make_testcase(u"\u00C9", "\x83"), // É + make_testcase(u"\u00D1", "\x84"), // Ñ + make_testcase(u"\u00D6", "\x85"), // Ö + make_testcase(u"\u00DC", "\x86"), // Ü + make_testcase(u"\u00E1", "\x87"), // á + make_testcase(u"\u00E0", "\x88"), // à + make_testcase(u"\u00E2", "\x89"), // â + make_testcase(u"\u00E4", "\x8A"), // ä + make_testcase(u"\u00E3", "\x8B"), // ã + make_testcase(u"\u00E5", "\x8C"), // å + make_testcase(u"\u00E7", "\x8D"), // ç + make_testcase(u"\u00E9", "\x8E"), // é + make_testcase(u"\u00E8", "\x8F"), // è + make_testcase(u"\u00EA", "\x90"), // ê + make_testcase(u"\u00EB", "\x91"), // ë + make_testcase(u"\u00ED", "\x92"), // í + make_testcase(u"\u00EC", "\x93"), // ì + make_testcase(u"\u00EE", "\x94"), // î + make_testcase(u"\u00EF", "\x95"), // ï + make_testcase(u"\u00F1", "\x96"), // ñ + make_testcase(u"\u00F3", "\x97"), // ó + make_testcase(u"\u00F2", "\x98"), // ò + make_testcase(u"\u00F4", "\x99"), // ô + make_testcase(u"\u00F6", "\x9A"), // ö + make_testcase(u"\u00F5", "\x9B"), // õ + make_testcase(u"\u00FA", "\x9C"), // ú + make_testcase(u"\u00F9", "\x9D"), // ù + make_testcase(u"\u00FB", "\x9E"), // û + make_testcase(u"\u00FC", "\x9F"), // ü + make_testcase(u"\u2020", "\xA0"), // † + make_testcase(u"\u00B0", "\xA1"), // ° + make_testcase(u"\u00A2", "\xA2"), // ¢ + make_testcase(u"\u00A3", "\xA3"), // £ + make_testcase(u"\u00A7", "\xA4"), // § + make_testcase(u"\u2022", "\xA5"), // • + make_testcase(u"\u00B6", "\xA6"), // ¶ + make_testcase(u"\u00DF", "\xA7"), // ß + make_testcase(u"\u00AE", "\xA8"), // ® + make_testcase(u"\u00A9", "\xA9"), // © + make_testcase(u"\u2122", "\xAA"), // ™ + make_testcase(u"\u00B4", "\xAB"), // ´ + make_testcase(u"\u00A8", "\xAC"), // ¨ + make_testcase(u"\u2260", "\xAD"), // ≠ + make_testcase(u"\u00C6", "\xAE"), // Æ + make_testcase(u"\u00D8", "\xAF"), // Ø + make_testcase(u"\u221E", "\xB0"), // ∞ + make_testcase(u"\u00B1", "\xB1"), // ± + make_testcase(u"\u2264", "\xB2"), // ≤ + make_testcase(u"\u2265", "\xB3"), // ≥ + make_testcase(u"\u00A5", "\xB4"), // ¥ + make_testcase(u"\u00B5", "\xB5"), // µ + make_testcase(u"\u2202", "\xB6"), // ∂ + make_testcase(u"\u2211", "\xB7"), // ∑ + make_testcase(u"\u220F", "\xB8"), // ∏ + make_testcase(u"\u03C0", "\xB9"), // π + make_testcase(u"\u222B", "\xBA"), // ∫ + make_testcase(u"\u00AA", "\xBB"), // ª + make_testcase(u"\u00BA", "\xBC"), // º + make_testcase(u"\u2126", "\xBD"), // Ω + make_testcase(u"\u00E6", "\xBE"), // æ + make_testcase(u"\u00F8", "\xBF"), // ø + make_testcase(u"\u00BF", "\xC0"), // ¿ + make_testcase(u"\u00A1", "\xC1"), // ¡ + make_testcase(u"\u00AC", "\xC2"), // ¬ + make_testcase(u"\u221A", "\xC3"), // √ + make_testcase(u"\u0192", "\xC4"), // ƒ + make_testcase(u"\u2248", "\xC5"), // ≈ + make_testcase(u"\u2206", "\xC6"), // ∆ + make_testcase(u"\u00AB", "\xC7"), // « + make_testcase(u"\u00BB", "\xC8"), // » + make_testcase(u"\u2026", "\xC9"), // … + make_testcase(u"\u00A0", "\xCA"), // NBSP + make_testcase(u"\u00C0", "\xCB"), // À + make_testcase(u"\u00C3", "\xCC"), // à + make_testcase(u"\u00D5", "\xCD"), // Õ + make_testcase(u"\u0152", "\xCE"), // Œ + make_testcase(u"\u0153", "\xCF"), // œ + make_testcase(u"\u2013", "\xD0"), // – + make_testcase(u"\u2014", "\xD1"), // — + make_testcase(u"\u201C", "\xD2"), // “ + make_testcase(u"\u201D", "\xD3"), // ” + make_testcase(u"\u2018", "\xD4"), // ‘ + make_testcase(u"\u2019", "\xD5"), // ’ + make_testcase(u"\u00F7", "\xD6"), // ÷ + make_testcase(u"\u25CA", "\xD7"), // ◊ + make_testcase(u"\u00FF", "\xD8"), // ÿ + make_testcase(u"\u0178", "\xD9"), // Ÿ + make_testcase(u"\u2044", "\xDA"), // ⁄ + make_testcase(u"\u00A4", "\xDB"), // ¤ + make_testcase(u"\u2039", "\xDC"), // ‹ + make_testcase(u"\u203A", "\xDD"), // › + make_testcase(u"\uFB01", "\xDE"), // fi + make_testcase(u"\uFB02", "\xDF"), // fl + make_testcase(u"\u2021", "\xE0"), // ‡ + make_testcase(u"\u00B7", "\xE1"), // · + make_testcase(u"\u201A", "\xE2"), // ‚ + make_testcase(u"\u201E", "\xE3"), // „ + make_testcase(u"\u2030", "\xE4"), // ‰ + make_testcase(u"\u00C2", "\xE5"), //  + make_testcase(u"\u00CA", "\xE6"), // Ê + make_testcase(u"\u00C1", "\xE7"), // Á + make_testcase(u"\u00CB", "\xE8"), // Ë + make_testcase(u"\u00C8", "\xE9"), // È + make_testcase(u"\u00CD", "\xEA"), // Í + make_testcase(u"\u00CE", "\xEB"), // Î + make_testcase(u"\u00CF", "\xEC"), // Ï + make_testcase(u"\u00CC", "\xED"), // Ì + make_testcase(u"\u00D3", "\xEE"), // Ó + make_testcase(u"\u00D4", "\xEF"), // Ô + make_testcase(u"\uFFFF", "\xF0"), // invalid (apple logo) + make_testcase(u"\u00D2", "\xF1"), // Ò + make_testcase(u"\u00DA", "\xF2"), // Ú + make_testcase(u"\u00DB", "\xF3"), // Û + make_testcase(u"\u00D9", "\xF4"), // Ù + make_testcase(u"\u0131", "\xF5"), // ı + make_testcase(u"\u02C6", "\xF6"), // ˆ + make_testcase(u"\u02DC", "\xF7"), // ˜ + make_testcase(u"\u00AF", "\xF8"), // ¯ + make_testcase(u"\u02D8", "\xF9"), // ˘ + make_testcase(u"\u02D9", "\xFA"), // ˙ + make_testcase(u"\u02DA", "\xFB"), // ˚ + make_testcase(u"\u00B8", "\xFC"), // ¸ + make_testcase(u"\u02DD", "\xFD"), // ˝ + make_testcase(u"\u02DB", "\xFE"), // ˛ + make_testcase(u"\u02C7", "\xFF") // ˇ + ); + + char resultStr[2]; + auto result = SUniConvertUTF16ToMac(resultStr, testCase.first.c_str(), 2); + + INFO(testCase.second); + CHECK(std::string(resultStr) == testCase.second); + CHECK(result == 2); + } +} + +TEST_CASE("SUniConvertUTF16ToWin", "[unicode]") { + SECTION("does nothing on empty dest size") { + auto result = SUniConvertUTF16ToWin(nullptr, nullptr, 0); + CHECK(result == 0); + } + + SECTION("operates on empty string") { + char resultStr[RESULT_STR_SIZE]; + const char16_t str[] = u""; + + auto result = SUniConvertUTF16ToWin(resultStr, str, RESULT_STR_SIZE); + CHECK(std::string(resultStr) == ""); + CHECK(result == 1); // wrote 1 null terminator + } + + SECTION("translates ASCII string") { + char resultStr[RESULT_STR_SIZE]; + const char16_t str[] = u"Quick lazy brown fox or something"; + + auto result = SUniConvertUTF16ToWin(resultStr, str, RESULT_STR_SIZE); + CHECK(std::string(resultStr) == "Quick lazy brown fox or something"); + CHECK(result == 34); + } + + SECTION("fails to write null terminator if string isn't long enough") { + char resultStr[RESULT_STR_SIZE]; + std::fill(std::begin(resultStr), std::end(resultStr), 0xCC); + const char16_t str[] = u"Quick lazy brown fox or something"; + + auto result = SUniConvertUTF16ToWin(resultStr, str, 5); + CHECK(std::string(resultStr, 5) == "Quick"); + CHECK(static_cast(resultStr[5]) == 0xCC); + CHECK(result == 5); + } + + SECTION("writes ??? on unsupported characters") { + char resultStr[RESULT_STR_SIZE]; + const char16_t str[] = u"\u8080\u8080lol\u8080\u8080\u8080"; + + auto result = SUniConvertUTF16ToWin(resultStr, str, RESULT_STR_SIZE); + CHECK(std::string(resultStr) == "??lol???"); + CHECK(result == 9); + } + + SECTION("translates shared ASCII characters") { + for (int i = 1; i < 128; i++) { + char16_t str[2] = { static_cast(i) }; + char resultStr[2]; + + auto result = SUniConvertUTF16ToWin(resultStr, str, 2); + INFO(i); + CHECK(resultStr[0] == static_cast(i)); + CHECK(resultStr[1] == '\0'); + CHECK(result == 2); + } + } + + SECTION("translates special characters") { + auto testCase = GENERATE( + make_testcase(u"\u20AC", "\x80"), // € + //make_testcase(u"\uFFFF", "\x81"), // invalid + make_testcase(u"\u201A", "\x82"), // ‚ + make_testcase(u"\u0192", "\x83"), // ƒ + make_testcase(u"\u201E", "\x84"), // „ + make_testcase(u"\u2026", "\x85"), // … + make_testcase(u"\u2020", "\x86"), // † + make_testcase(u"\u2021", "\x87"), // ‡ + make_testcase(u"\u02C6", "\x88"), // ˆ + make_testcase(u"\u2030", "\x89"), // ‰ + make_testcase(u"\u0160", "\x8A"), // Š + make_testcase(u"\u2039", "\x8B"), // ‹ + make_testcase(u"\u0152", "\x8C"), // Œ + //make_testcase(u"\uFFFF", "\x8D"), // invalid + make_testcase(u"\u017D", "\x8E"), // Ž + //make_testcase(u"\uFFFF", "\x8F"), // invalid + //make_testcase(u"\uFFFF", "\x90"), // invalid + make_testcase(u"\u2018", "\x91"), // ‘ + make_testcase(u"\u2019", "\x92"), // ’ + make_testcase(u"\u201C", "\x93"), // “ + make_testcase(u"\u201D", "\x94"), // ” + make_testcase(u"\u2022", "\x95"), // • + make_testcase(u"\u2013", "\x96"), // – + make_testcase(u"\u2014", "\x97"), // — + make_testcase(u"\u02DC", "\x98"), // ˜ + make_testcase(u"\u2122", "\x99"), // ™ + make_testcase(u"\u0161", "\x9A"), // š + make_testcase(u"\u203A", "\x9B"), // › + make_testcase(u"\u0153", "\x9C"), // œ + make_testcase(u"\uFFFF", "\x9D"), // invalid + make_testcase(u"\u017E", "\x9E"), // ž + make_testcase(u"\u0178", "\x9F") // Ÿ + ); + + char resultStr[2]; + auto result = SUniConvertUTF16ToWin(resultStr, testCase.first.c_str(), 2); + + INFO(testCase.second); + CHECK(std::string(resultStr) == testCase.second); + CHECK(result == 2); + } + + SECTION("translates extended ASCII characters") { + for (int i = 0xA0; i < 256; i++) { + char16_t str[2] = { static_cast(i) }; + char resultStr[2]; + + auto result = SUniConvertUTF16ToWin(resultStr, str, 2); + INFO(i); + CHECK(resultStr[0] == static_cast(i)); + CHECK(resultStr[1] == '\0'); + CHECK(result == 2); + } + } + + // TODO: Starcraft flavour Korean codepage +} + +TEST_CASE("SUniConvertDosToUTF16", "[unicode]") { + SECTION("does nothing on empty dest size") { + auto result = SUniConvertDosToUTF16(nullptr, nullptr, 0); + CHECK(result == 0); + } + + SECTION("operates on empty string") { + char16_t resultStr[RESULT_STR_SIZE]; + const char str[] = ""; + + auto result = SUniConvertDosToUTF16(resultStr, str, RESULT_STR_SIZE); + CHECK(std::u16string(resultStr) == u""); + CHECK(result == 1); // wrote 1 null terminator + } + + SECTION("translates ASCII string") { + char16_t resultStr[RESULT_STR_SIZE]; + const char str[] = "Quick lazy brown fox or something"; + + auto result = SUniConvertDosToUTF16(resultStr, str, RESULT_STR_SIZE); + CHECK(std::u16string(resultStr) == u"Quick lazy brown fox or something"); + CHECK(result == 34); + } + + SECTION("fails to write null terminator if string isn't long enough") { + char16_t resultStr[RESULT_STR_SIZE]; + std::fill(std::begin(resultStr), std::end(resultStr), 0xCCCC); + const char str[] = "Quick lazy brown fox or something"; + + auto result = SUniConvertDosToUTF16(resultStr, str, 5); + CHECK(std::u16string(resultStr, 5) == u"Quick"); + CHECK(static_cast(resultStr[5]) == 0xCCCC); + CHECK(result == 5); + } + + SECTION("translates shared ASCII characters") { + for (int i = 1; i < 128; i++) { + char str[2] = { static_cast(i) }; + char16_t resultStr[2]; + + auto result = SUniConvertDosToUTF16(resultStr, str, 2); + INFO(i); + CHECK(resultStr[0] == static_cast(i)); + CHECK(resultStr[1] == L'\0'); + CHECK(result == 2); + } + } + + SECTION("translates special characters") { + auto testCase = GENERATE( + make_testcase(u"\u00C7", "\x80"), // Ç + make_testcase(u"\u00FC", "\x81"), // ü + make_testcase(u"\u00E9", "\x82"), // é + make_testcase(u"\u00E2", "\x83"), // â + make_testcase(u"\u00E4", "\x84"), // ä + make_testcase(u"\u00E0", "\x85"), // à + make_testcase(u"\u00E5", "\x86"), // å + make_testcase(u"\u00E7", "\x87"), // ç + make_testcase(u"\u00EA", "\x88"), // ê + make_testcase(u"\u00EB", "\x89"), // ë + make_testcase(u"\u00E8", "\x8A"), // è + make_testcase(u"\u00EF", "\x8B"), // ï + make_testcase(u"\u00EE", "\x8C"), // î + make_testcase(u"\u00EC", "\x8D"), // ì + make_testcase(u"\u00C4", "\x8E"), // Ä + make_testcase(u"\u00C5", "\x8F"), // Å + make_testcase(u"\u00C9", "\x90"), // É + make_testcase(u"\u00E6", "\x91"), // æ + make_testcase(u"\u00C6", "\x92"), // Æ + make_testcase(u"\u00F4", "\x93"), // ô + make_testcase(u"\u00F6", "\x94"), // ö + make_testcase(u"\u00F2", "\x95"), // ò + make_testcase(u"\u00FB", "\x96"), // û + make_testcase(u"\u00F9", "\x97"), // ù + make_testcase(u"\u00FF", "\x98"), // ÿ + make_testcase(u"\u00D6", "\x99"), // Ö + make_testcase(u"\u00DC", "\x9A"), // Ü + make_testcase(u"\u00A2", "\x9B"), // ¢ + make_testcase(u"\u00A3", "\x9C"), // £ + make_testcase(u"\u00A5", "\x9D"), // ¥ + make_testcase(u"\u20A7", "\x9E"), // ₧ + make_testcase(u"\u0192", "\x9F"), // ƒ + make_testcase(u"\u00E1", "\xA0"), // á + make_testcase(u"\u00ED", "\xA1"), // í + make_testcase(u"\u00F3", "\xA2"), // ó + make_testcase(u"\u00FA", "\xA3"), // ú + make_testcase(u"\u00F1", "\xA4"), // ñ + make_testcase(u"\u00D1", "\xA5"), // Ñ + make_testcase(u"\u00AA", "\xA6"), // ª + make_testcase(u"\u00BA", "\xA7"), // º + make_testcase(u"\u00BF", "\xA8"), // ¿ + make_testcase(u"\u2310", "\xA9"), // ⌐ + make_testcase(u"\u00AC", "\xAA"), // ¬ + make_testcase(u"\u00BD", "\xAB"), // ½ + make_testcase(u"\u00BC", "\xAC"), // ¼ + make_testcase(u"\u00A1", "\xAD"), // ¡ + make_testcase(u"\u00AB", "\xAE"), // « + make_testcase(u"\u00BB", "\xAF"), // » + make_testcase(u"\u2591", "\xB0"), // ░ + make_testcase(u"\u2592", "\xB1"), // ▒ + make_testcase(u"\u2593", "\xB2"), // ▓ + make_testcase(u"\u2502", "\xB3"), // │ + make_testcase(u"\u2524", "\xB4"), // ┤ + make_testcase(u"\u2561", "\xB5"), // ╡ + make_testcase(u"\u2562", "\xB6"), // ╢ + make_testcase(u"\u2556", "\xB7"), // ╖ + make_testcase(u"\u2555", "\xB8"), // ╕ + make_testcase(u"\u2563", "\xB9"), // ╣ + make_testcase(u"\u2551", "\xBA"), // ║ + make_testcase(u"\u2557", "\xBB"), // ╗ + make_testcase(u"\u255D", "\xBC"), // ╝ + make_testcase(u"\u255C", "\xBD"), // ╜ + make_testcase(u"\u255B", "\xBE"), // ╛ + make_testcase(u"\u2510", "\xBF"), // ┐ + make_testcase(u"\u2514", "\xC0"), // └ + make_testcase(u"\u2534", "\xC1"), // ┴ + make_testcase(u"\u252C", "\xC2"), // ┬ + make_testcase(u"\u251C", "\xC3"), // ├ + make_testcase(u"\u2500", "\xC4"), // ─ + make_testcase(u"\u253C", "\xC5"), // ┼ + make_testcase(u"\u255E", "\xC6"), // ╞ + make_testcase(u"\u255F", "\xC7"), // ╟ + make_testcase(u"\u255A", "\xC8"), // ╚ + make_testcase(u"\u2554", "\xC9"), // ╔ + make_testcase(u"\u2569", "\xCA"), // ╩ + make_testcase(u"\u2566", "\xCB"), // ╦ + make_testcase(u"\u2560", "\xCC"), // ╠ + make_testcase(u"\u2550", "\xCD"), // ═ + make_testcase(u"\u256C", "\xCE"), // ╬ + make_testcase(u"\u2567", "\xCF"), // ╧ + make_testcase(u"\u2568", "\xD0"), // ╨ + make_testcase(u"\u2564", "\xD1"), // ╤ + make_testcase(u"\u2565", "\xD2"), // ╥ + make_testcase(u"\u2559", "\xD3"), // ╙ + make_testcase(u"\u2558", "\xD4"), // ╘ + make_testcase(u"\u2552", "\xD5"), // ╒ + make_testcase(u"\u2553", "\xD6"), // ╓ + make_testcase(u"\u256B", "\xD7"), // ╫ + make_testcase(u"\u256A", "\xD8"), // ╪ + make_testcase(u"\u2518", "\xD9"), // ┘ + make_testcase(u"\u250C", "\xDA"), // ┌ + make_testcase(u"\u2588", "\xDB"), // █ + make_testcase(u"\u2584", "\xDC"), // ▄ + make_testcase(u"\u258C", "\xDD"), // ▌ + make_testcase(u"\u2590", "\xDE"), // ▐ + make_testcase(u"\u2580", "\xDF"), // ▀ + make_testcase(u"\u03B1", "\xE0"), // α + make_testcase(u"\u00DF", "\xE1"), // ß + make_testcase(u"\u0393", "\xE2"), // Γ + make_testcase(u"\u03C0", "\xE3"), // π + make_testcase(u"\u03A3", "\xE4"), // Σ + make_testcase(u"\u03C3", "\xE5"), // σ + make_testcase(u"\u00B5", "\xE6"), // µ + make_testcase(u"\u03C4", "\xE7"), // τ + make_testcase(u"\u03A6", "\xE8"), // Φ + make_testcase(u"\u0398", "\xE9"), // Θ + make_testcase(u"\u03A9", "\xEA"), // Ω + make_testcase(u"\u03B4", "\xEB"), // δ + make_testcase(u"\u221E", "\xEC"), // ∞ + make_testcase(u"\u03C6", "\xED"), // φ + make_testcase(u"\u03B5", "\xEE"), // ε + make_testcase(u"\u2229", "\xEF"), // ∩ + make_testcase(u"\u2261", "\xF0"), // ≡ + make_testcase(u"\u00B1", "\xF1"), // ± + make_testcase(u"\u2265", "\xF2"), // ≥ + make_testcase(u"\u2264", "\xF3"), // ≤ + make_testcase(u"\u2320", "\xF4"), // ⌠ + make_testcase(u"\u2321", "\xF5"), // ⌡ + make_testcase(u"\u00F7", "\xF6"), // ÷ + make_testcase(u"\u2248", "\xF7"), // ≈ + make_testcase(u"\u00B0", "\xF8"), // ° + make_testcase(u"\u2219", "\xF9"), // ∙ + make_testcase(u"\u00B7", "\xFA"), // · + make_testcase(u"\u221A", "\xFB"), // √ + make_testcase(u"\u207F", "\xFC"), // ⁿ + make_testcase(u"\u00B2", "\xFD"), // ² + make_testcase(u"\u25A0", "\xFE"), // ■ + make_testcase(u"\u00A0", "\xFF") // r + ); + + char16_t resultStr[2]; + auto result = SUniConvertDosToUTF16(resultStr, testCase.second.c_str(), 2); + + INFO(testCase.second); + CHECK(std::u16string(resultStr) == testCase.first); + CHECK(result == 2); + } +} + +TEST_CASE("SUniConvertMacToUTF16", "[unicode]") { + SECTION("does nothing on empty dest size") { + auto result = SUniConvertMacToUTF16(nullptr, nullptr, 0); + CHECK(result == 0); + } + + SECTION("operates on empty string") { + char16_t resultStr[RESULT_STR_SIZE]; + const char str[] = ""; + + auto result = SUniConvertMacToUTF16(resultStr, str, RESULT_STR_SIZE); + CHECK(std::u16string(resultStr) == u""); + CHECK(result == 1); // wrote 1 null terminator + } + + SECTION("translates ASCII string") { + char16_t resultStr[RESULT_STR_SIZE]; + const char str[] = "Quick lazy brown fox or something"; + + auto result = SUniConvertMacToUTF16(resultStr, str, RESULT_STR_SIZE); + CHECK(std::u16string(resultStr) == u"Quick lazy brown fox or something"); + CHECK(result == 34); + } + + SECTION("fails to write null terminator if string isn't long enough") { + char16_t resultStr[RESULT_STR_SIZE]; + std::fill(std::begin(resultStr), std::end(resultStr), 0xCCCC); + const char str[] = "Quick lazy brown fox or something"; + + auto result = SUniConvertMacToUTF16(resultStr, str, 5); + CHECK(std::u16string(resultStr, 5) == u"Quick"); + CHECK(static_cast(resultStr[5]) == 0xCCCC); + CHECK(result == 5); + } + + SECTION("translates shared ASCII characters") { + for (int i = 1; i < 128; i++) { + char str[2] = { static_cast(i) }; + char16_t resultStr[2]; + + auto result = SUniConvertMacToUTF16(resultStr, str, 2); + INFO(i); + CHECK(resultStr[0] == static_cast(i)); + CHECK(resultStr[1] == L'\0'); + CHECK(result == 2); + } + } + + SECTION("translates special characters") { + auto testCase = GENERATE( + make_testcase(u"\u00C4", "\x80"), // Ä + make_testcase(u"\u00C5", "\x81"), // Å + make_testcase(u"\u00C7", "\x82"), // Ç + make_testcase(u"\u00C9", "\x83"), // É + make_testcase(u"\u00D1", "\x84"), // Ñ + make_testcase(u"\u00D6", "\x85"), // Ö + make_testcase(u"\u00DC", "\x86"), // Ü + make_testcase(u"\u00E1", "\x87"), // á + make_testcase(u"\u00E0", "\x88"), // à + make_testcase(u"\u00E2", "\x89"), // â + make_testcase(u"\u00E4", "\x8A"), // ä + make_testcase(u"\u00E3", "\x8B"), // ã + make_testcase(u"\u00E5", "\x8C"), // å + make_testcase(u"\u00E7", "\x8D"), // ç + make_testcase(u"\u00E9", "\x8E"), // é + make_testcase(u"\u00E8", "\x8F"), // è + make_testcase(u"\u00EA", "\x90"), // ê + make_testcase(u"\u00EB", "\x91"), // ë + make_testcase(u"\u00ED", "\x92"), // í + make_testcase(u"\u00EC", "\x93"), // ì + make_testcase(u"\u00EE", "\x94"), // î + make_testcase(u"\u00EF", "\x95"), // ï + make_testcase(u"\u00F1", "\x96"), // ñ + make_testcase(u"\u00F3", "\x97"), // ó + make_testcase(u"\u00F2", "\x98"), // ò + make_testcase(u"\u00F4", "\x99"), // ô + make_testcase(u"\u00F6", "\x9A"), // ö + make_testcase(u"\u00F5", "\x9B"), // õ + make_testcase(u"\u00FA", "\x9C"), // ú + make_testcase(u"\u00F9", "\x9D"), // ù + make_testcase(u"\u00FB", "\x9E"), // û + make_testcase(u"\u00FC", "\x9F"), // ü + make_testcase(u"\u2020", "\xA0"), // † + make_testcase(u"\u00B0", "\xA1"), // ° + make_testcase(u"\u00A2", "\xA2"), // ¢ + make_testcase(u"\u00A3", "\xA3"), // £ + make_testcase(u"\u00A7", "\xA4"), // § + make_testcase(u"\u2022", "\xA5"), // • + make_testcase(u"\u00B6", "\xA6"), // ¶ + make_testcase(u"\u00DF", "\xA7"), // ß + make_testcase(u"\u00AE", "\xA8"), // ® + make_testcase(u"\u00A9", "\xA9"), // © + make_testcase(u"\u2122", "\xAA"), // ™ + make_testcase(u"\u00B4", "\xAB"), // ´ + make_testcase(u"\u00A8", "\xAC"), // ¨ + make_testcase(u"\u2260", "\xAD"), // ≠ + make_testcase(u"\u00C6", "\xAE"), // Æ + make_testcase(u"\u00D8", "\xAF"), // Ø + make_testcase(u"\u221E", "\xB0"), // ∞ + make_testcase(u"\u00B1", "\xB1"), // ± + make_testcase(u"\u2264", "\xB2"), // ≤ + make_testcase(u"\u2265", "\xB3"), // ≥ + make_testcase(u"\u00A5", "\xB4"), // ¥ + make_testcase(u"\u00B5", "\xB5"), // µ + make_testcase(u"\u2202", "\xB6"), // ∂ + make_testcase(u"\u2211", "\xB7"), // ∑ + make_testcase(u"\u220F", "\xB8"), // ∏ + make_testcase(u"\u03C0", "\xB9"), // π + make_testcase(u"\u222B", "\xBA"), // ∫ + make_testcase(u"\u00AA", "\xBB"), // ª + make_testcase(u"\u00BA", "\xBC"), // º + make_testcase(u"\u2126", "\xBD"), // Ω + make_testcase(u"\u00E6", "\xBE"), // æ + make_testcase(u"\u00F8", "\xBF"), // ø + make_testcase(u"\u00BF", "\xC0"), // ¿ + make_testcase(u"\u00A1", "\xC1"), // ¡ + make_testcase(u"\u00AC", "\xC2"), // ¬ + make_testcase(u"\u221A", "\xC3"), // √ + make_testcase(u"\u0192", "\xC4"), // ƒ + make_testcase(u"\u2248", "\xC5"), // ≈ + make_testcase(u"\u2206", "\xC6"), // ∆ + make_testcase(u"\u00AB", "\xC7"), // « + make_testcase(u"\u00BB", "\xC8"), // » + make_testcase(u"\u2026", "\xC9"), // … + make_testcase(u"\u00A0", "\xCA"), // NBSP + make_testcase(u"\u00C0", "\xCB"), // À + make_testcase(u"\u00C3", "\xCC"), // à + make_testcase(u"\u00D5", "\xCD"), // Õ + make_testcase(u"\u0152", "\xCE"), // Œ + make_testcase(u"\u0153", "\xCF"), // œ + make_testcase(u"\u2013", "\xD0"), // – + make_testcase(u"\u2014", "\xD1"), // — + make_testcase(u"\u201C", "\xD2"), // “ + make_testcase(u"\u201D", "\xD3"), // ” + make_testcase(u"\u2018", "\xD4"), // ‘ + make_testcase(u"\u2019", "\xD5"), // ’ + make_testcase(u"\u00F7", "\xD6"), // ÷ + make_testcase(u"\u25CA", "\xD7"), // ◊ + make_testcase(u"\u00FF", "\xD8"), // ÿ + make_testcase(u"\u0178", "\xD9"), // Ÿ + make_testcase(u"\u2044", "\xDA"), // ⁄ + make_testcase(u"\u00A4", "\xDB"), // ¤ + make_testcase(u"\u2039", "\xDC"), // ‹ + make_testcase(u"\u203A", "\xDD"), // › + make_testcase(u"\uFB01", "\xDE"), // fi + make_testcase(u"\uFB02", "\xDF"), // fl + make_testcase(u"\u2021", "\xE0"), // ‡ + make_testcase(u"\u00B7", "\xE1"), // · + make_testcase(u"\u201A", "\xE2"), // ‚ + make_testcase(u"\u201E", "\xE3"), // „ + make_testcase(u"\u2030", "\xE4"), // ‰ + make_testcase(u"\u00C2", "\xE5"), //  + make_testcase(u"\u00CA", "\xE6"), // Ê + make_testcase(u"\u00C1", "\xE7"), // Á + make_testcase(u"\u00CB", "\xE8"), // Ë + make_testcase(u"\u00C8", "\xE9"), // È + make_testcase(u"\u00CD", "\xEA"), // Í + make_testcase(u"\u00CE", "\xEB"), // Î + make_testcase(u"\u00CF", "\xEC"), // Ï + make_testcase(u"\u00CC", "\xED"), // Ì + make_testcase(u"\u00D3", "\xEE"), // Ó + make_testcase(u"\u00D4", "\xEF"), // Ô + make_testcase(u"\uFFFF", "\xF0"), // invalid (apple logo) + make_testcase(u"\u00D2", "\xF1"), // Ò + make_testcase(u"\u00DA", "\xF2"), // Ú + make_testcase(u"\u00DB", "\xF3"), // Û + make_testcase(u"\u00D9", "\xF4"), // Ù + make_testcase(u"\u0131", "\xF5"), // ı + make_testcase(u"\u02C6", "\xF6"), // ˆ + make_testcase(u"\u02DC", "\xF7"), // ˜ + make_testcase(u"\u00AF", "\xF8"), // ¯ + make_testcase(u"\u02D8", "\xF9"), // ˘ + make_testcase(u"\u02D9", "\xFA"), // ˙ + make_testcase(u"\u02DA", "\xFB"), // ˚ + make_testcase(u"\u00B8", "\xFC"), // ¸ + make_testcase(u"\u02DD", "\xFD"), // ˝ + make_testcase(u"\u02DB", "\xFE"), // ˛ + make_testcase(u"\u02C7", "\xFF") // ˇ + ); + + char16_t resultStr[2]; + auto result = SUniConvertMacToUTF16(resultStr, testCase.second.c_str(), 2); + + INFO(testCase.second); + CHECK(std::u16string(resultStr) == testCase.first); + CHECK(result == 2); + } +} + +TEST_CASE("SUniConvertWinToUTF16", "[unicode]") { + SECTION("does nothing on empty dest size") { + auto result = SUniConvertWinToUTF16(nullptr, nullptr, 0); + CHECK(result == 0); + } + + SECTION("operates on empty string") { + char16_t resultStr[RESULT_STR_SIZE]; + const char str[] = ""; + + auto result = SUniConvertWinToUTF16(resultStr, str, RESULT_STR_SIZE); + CHECK(std::u16string(resultStr) == u""); + CHECK(result == 1); // wrote 1 null terminator + } + + SECTION("translates ASCII string") { + char16_t resultStr[RESULT_STR_SIZE]; + const char str[] = "Quick lazy brown fox or something"; + + auto result = SUniConvertWinToUTF16(resultStr, str, RESULT_STR_SIZE); + CHECK(std::u16string(resultStr) == u"Quick lazy brown fox or something"); + CHECK(result == 34); + } + + SECTION("fails to write null terminator if string isn't long enough") { + char16_t resultStr[RESULT_STR_SIZE]; + std::fill(std::begin(resultStr), std::end(resultStr), 0xCCCC); + const char str[] = "Quick lazy brown fox or something"; + + auto result = SUniConvertWinToUTF16(resultStr, str, 5); + CHECK(std::u16string(resultStr, 5) == u"Quick"); + CHECK(static_cast(resultStr[5]) == 0xCCCC); + CHECK(result == 5); + } + + SECTION("translates shared ASCII characters") { + for (int i = 1; i < 128; i++) { + char str[2] = { static_cast(i) }; + char16_t resultStr[2]; + + auto result = SUniConvertWinToUTF16(resultStr, str, 2); + INFO(i); + CHECK(resultStr[0] == static_cast(i)); + CHECK(resultStr[1] == L'\0'); + CHECK(result == 2); + } + } + + SECTION("translates special characters") { + auto testCase = GENERATE( + make_testcase(u"\u20AC", "\x80"), // € + make_testcase(u"\uFFFF", "\x81"), // invalid + make_testcase(u"\u201A", "\x82"), // ‚ + make_testcase(u"\u0192", "\x83"), // ƒ + make_testcase(u"\u201E", "\x84"), // „ + make_testcase(u"\u2026", "\x85"), // … + make_testcase(u"\u2020", "\x86"), // † + make_testcase(u"\u2021", "\x87"), // ‡ + make_testcase(u"\u02C6", "\x88"), // ˆ + make_testcase(u"\u2030", "\x89"), // ‰ + make_testcase(u"\u0160", "\x8A"), // Š + make_testcase(u"\u2039", "\x8B"), // ‹ + make_testcase(u"\u0152", "\x8C"), // Œ + make_testcase(u"\uFFFF", "\x8D"), // invalid + make_testcase(u"\u017D", "\x8E"), // Ž + make_testcase(u"\uFFFF", "\x8F"), // invalid + make_testcase(u"\uFFFF", "\x90"), // invalid + make_testcase(u"\u2018", "\x91"), // ‘ + make_testcase(u"\u2019", "\x92"), // ’ + make_testcase(u"\u201C", "\x93"), // “ + make_testcase(u"\u201D", "\x94"), // ” + make_testcase(u"\u2022", "\x95"), // • + make_testcase(u"\u2013", "\x96"), // – + make_testcase(u"\u2014", "\x97"), // — + make_testcase(u"\u02DC", "\x98"), // ˜ + make_testcase(u"\u2122", "\x99"), // ™ + make_testcase(u"\u0161", "\x9A"), // š + make_testcase(u"\u203A", "\x9B"), // › + make_testcase(u"\u0153", "\x9C"), // œ + make_testcase(u"\uFFFF", "\x9D"), // invalid + make_testcase(u"\u017E", "\x9E"), // ž + make_testcase(u"\u0178", "\x9F") // Ÿ + ); + + char16_t resultStr[2]; + auto result = SUniConvertWinToUTF16(resultStr, testCase.second.c_str(), 2); + + INFO(testCase.second); + CHECK(std::u16string(resultStr) == testCase.first); + CHECK(result == 2); + } + + SECTION("translates extended ASCII characters") { + for (int i = 0xA0; i < 256; i++) { + char str[2] = { static_cast(i) }; + char16_t resultStr[2]; + + auto result = SUniConvertWinToUTF16(resultStr, str, 2); + INFO(i); + CHECK(resultStr[0] == static_cast(i)); + CHECK(resultStr[1] == u'\0'); + CHECK(result == 2); + } + } + + // TODO: Starcraft flavour Korean codepage +} + +TEST_CASE("SUniFindAfterUTF8Chr", "[unicode]") { + SECTION("returns index+1 if index is negative") { + CHECK(SUniFindAfterUTF8Chr(nullptr, -1) == 0); + } + + SECTION("returns 1 on string with 1 char") { + CHECK(SUniFindAfterUTF8Chr(" ", 0) == 1); + } + + SECTION("returns next char on non-UTF8 string") { + CHECK(SUniFindAfterUTF8Chr("happy cakes", 4) == 5); + } + + SECTION("finds the character after an emoji") { + const char str[] = "Merry 🎄 Christmas"; + CHECK(sizeof(str) == 21); + CHECK(SUniFindAfterUTF8Chr(str, 4) == 5); + CHECK(SUniFindAfterUTF8Chr(str, 5) == 6); + CHECK(SUniFindAfterUTF8Chr(str, 6) == 10); + CHECK(SUniFindAfterUTF8Chr(str, 7) == 10); + CHECK(SUniFindAfterUTF8Chr(str, 8) == 10); + CHECK(SUniFindAfterUTF8Chr(str, 9) == 10); + CHECK(SUniFindAfterUTF8Chr(str, 10) == 11); + CHECK(SUniFindAfterUTF8Chr(str, 11) == 12); + } + + SECTION("finds the character after a Korean char") { + const char str[] = "메리 크리스마스"; + CHECK(sizeof(str) == 23); + CHECK(SUniFindAfterUTF8Chr(str, 3) == 6); + CHECK(SUniFindAfterUTF8Chr(str, 4) == 6); + CHECK(SUniFindAfterUTF8Chr(str, 5) == 6); + CHECK(SUniFindAfterUTF8Chr(str, 6) == 7); // ASCII space + CHECK(SUniFindAfterUTF8Chr(str, 7) == 10); + CHECK(SUniFindAfterUTF8Chr(str, 8) == 10); + CHECK(SUniFindAfterUTF8Chr(str, 9) == 10); + } +} + +TEST_CASE("SUniFindUTF8ChrStart", "[unicode]") { + SECTION("returns index if index is negative") { + CHECK(SUniFindUTF8ChrStart(nullptr, -1) == -1); + } + + SECTION("returns 0 if index is 0") { + CHECK(SUniFindUTF8ChrStart(nullptr, 0) == 0); + } + + SECTION("returns 0 on empty string") { + CHECK(SUniFindUTF8ChrStart("", 0) == 0); + } + + SECTION("returns current char on non-UTF8 string") { + CHECK(SUniFindUTF8ChrStart("happy cakes", 5) == 5); + } + + SECTION("finds the beginning of an emoji") { + const char str[] = "Merry 🎄 Christmas"; + CHECK(sizeof(str) == 21); + CHECK(SUniFindUTF8ChrStart(str, 4) == 4); + CHECK(SUniFindUTF8ChrStart(str, 5) == 5); + CHECK(SUniFindUTF8ChrStart(str, 6) == 6); + CHECK(SUniFindUTF8ChrStart(str, 7) == 6); + CHECK(SUniFindUTF8ChrStart(str, 8) == 6); + CHECK(SUniFindUTF8ChrStart(str, 9) == 6); + CHECK(SUniFindUTF8ChrStart(str, 10) == 10); + CHECK(SUniFindUTF8ChrStart(str, 11) == 11); + } + + SECTION("finds the beginning of a Korean char") { + const char str[] = "메리 크리스마스"; + CHECK(sizeof(str) == 23); + CHECK(SUniFindUTF8ChrStart(str, 3) == 3); + CHECK(SUniFindUTF8ChrStart(str, 4) == 3); + CHECK(SUniFindUTF8ChrStart(str, 5) == 3); + CHECK(SUniFindUTF8ChrStart(str, 6) == 6); // ASCII space + CHECK(SUniFindUTF8ChrStart(str, 7) == 7); + CHECK(SUniFindUTF8ChrStart(str, 8) == 7); + CHECK(SUniFindUTF8ChrStart(str, 9) == 7); + } +} TEST_CASE("SUniSGetUTF8", "[unicode]") { SECTION("returns ascii-range utf-8 first character") { @@ -35,7 +1123,7 @@ TEST_CASE("SUniSGetUTF8", "[unicode]") { TEST_CASE("SUniSPutUTF8", "[unicode]") { SECTION("writes ascii-range utf-8 first character") { auto code = 'f'; - char buffer[100] = { 0 }; + char buffer[RESULT_STR_SIZE] = { 0 }; SUniSPutUTF8(code, buffer); REQUIRE(SStrLen(buffer) == 1); @@ -44,7 +1132,7 @@ TEST_CASE("SUniSPutUTF8", "[unicode]") { SECTION("writes non-ascii-range utf-8 first character") { auto code = 0x1F642; - char buffer[100] = { 0 }; + char buffer[RESULT_STR_SIZE] = { 0 }; SUniSPutUTF8(code, buffer); REQUIRE(SStrLen(buffer) == 4); @@ -53,7 +1141,7 @@ TEST_CASE("SUniSPutUTF8", "[unicode]") { SECTION("writes null first character") { auto code = '\0'; - char buffer[100] = { 0 }; + char buffer[RESULT_STR_SIZE] = { 0 }; SUniSPutUTF8(code, buffer); REQUIRE(SStrLen(buffer) == 0); diff --git a/test/stormdll/storm.def b/test/stormdll/storm.def index 2502209..db023f5 100644 --- a/test/stormdll/storm.def +++ b/test/stormdll/storm.def @@ -1,484 +1,484 @@ -LIBRARY "Storm" - -EXPORTS - ; Networking - ;SNetCreateGame @101 NONAME - ;SNetDestroy @102 NONAME - ;SNetEnumDevices @103 NONAME - ;SNetEnumGames @104 NONAME - ;SNetEnumProviders @105 NONAME - ;SNetDropPlayer @106 NONAME - ;SNetGetGameInfo @107 NONAME - ;SNetGetNetworkLatency @108 NONAME - ;SNetGetNumPlayers @109 NONAME - ;SNetGetOwnerTurnsWaiting @110 NONAME - ;SNetGetPerformanceData @111 NONAME - ;SNetGetPlayerCaps @112 NONAME - ;SNetGetPlayerName @113 NONAME - ;SNetGetProviderCaps @114 NONAME - ;SNetGetTurnsInTransit @115 NONAME - ;SNetInitializeDevice @116 NONAME - ;SNetInitializeProvider @117 NONAME - ;SNetJoinGame @118 NONAME - ;SNetLeaveGame @119 NONAME - ;SNetPerformUpgrade @120 NONAME - ;SNetReceiveMessage @121 NONAME - ;SNetReceiveTurns @122 NONAME - ;SNetRegisterEventHandler @123 NONAME - ;SNetResetLatencyMeasurements @124 NONAME - ;SNetSelectGame @125 NONAME - ;SNetSelectProvider @126 NONAME - ;SNetSendMessage @127 NONAME - ;SNetSendTurn @128 NONAME - ;SNetSetBasePlayer @129 NONAME - ;SNetSetGameMode @130 NONAME - ;SNetUnregisterEventHandler @131 NONAME - ;SErrSetBlizzardErrorFunction @132 ; SNetGetOwnerId in SC beta and Diablo/Hellfire, something else in WC3 1.0.7+ - ;SNetEnumGamesEx @133 NONAME - ;SNetSendServerChatCommand @134 NONAME - ;SNetSendDatagram @135 NONAME - ;SNetReceiveDatagram @136 NONAME - ;SNetDisconnectAll @137 NONAME - ;SNetCreateLadderGame @138 NONAME - ;SNetReportGameResult @139 NONAME - ;SNetCheckDataFile @140 NONAME - - ; Networking (League/Extended) - These are all different in WC3 1.0.7+ - ;SNetSendLeagueCommand @141 NONAME - ;SNetSendReplayPath @142 NONAME - ;SNetGetLeagueId @143 NONAME - ;SNetGetPlayerNames @144 NONAME - ;SNetLeagueLogout @145 NONAME - ;SNetGetReplyName @146 NONAME - ;SNetGetCurrentProviderID @147 NONAME - ;SNetSetCodeSignVerifcationFunction @148 - - ; Dlg - ;SDlgBeginPaint @201 NONAME - ;SDlgBltToWindowI @202 NONAME - ;SDlgCheckTimers @203 NONAME - ;SDlgCreateDialogIndirectParam @204 NONAME - ;SDlgCreateDialogParam @205 NONAME - ;SDlgDefDialogProc @206 NONAME - ;SDlgDestroy @207 NONAME - ;SDlgDialogBoxIndirectParam @208 NONAME - ;SDlgDialogBoxParam @209 NONAME - ;SDlgDrawBitmap @210 NONAME - ;SDlgEndDialog @211 NONAME - ;SDlgEndPaint @212 NONAME - ;SDlgKillTimer @213 NONAME - ;SDlgSetBaseFont @214 NONAME - ;SDlgSetBitmapI @215 NONAME - ;SDlgSetControlBitmaps @216 NONAME - ;SDlgSetCursor @217 NONAME - ;SDlgSetSystemCursor @218 NONAME - ;SDlgSetTimer @219 NONAME - ;SDlgUpdateCursor @220 NONAME - ;SDlgBltToWindowE @221 NONAME - ;SDlgSetBitmapE @222 NONAME - ;SDlgSetLocale @223 NONAME - ;SDlgSetMessageLoopThrottle @224 NONAME - ;SDlgClearWindowMap @225 NONAME - ;SDlgResetWindowPos @226 NONAME - ;SDlgAddWindowToMap @227 NONAME - ;SDlgRemoveWindowFromMap @228 NONAME - ;SDlgAdjustWindowsToParent @229 NONAME - ;SDlgTakeScreenshot @230 NONAME - - ; File - ;SFileAuthenticateArchive @251 NONAME - ;SFileCloseArchive @252 NONAME - ;SFileCloseFile @253 NONAME - ;SFileDdaBegin @254 NONAME - ;SFileDdaBeginEx @255 NONAME - ;SFileDdaDestroy @256 NONAME - ;SFileDdaEnd @257 NONAME - ;SFileDdaGetPos @258 NONAME - ;SFileDdaGetVolume @259 NONAME - ;SFileDdaInitialize @260 NONAME - ;SFileDdaSetVolume @261 NONAME - ;SFileDestroy @262 NONAME - ;SFileEnableDirectAccess @263 NONAME - ;SFileGetFileArchive @264 NONAME - ;SFileGetFileSize @265 NONAME - ;SFileOpenArchive @266 NONAME - ;SFileOpenFile @267 NONAME - ;SFileOpenFileEx @268 NONAME - ;SFileReadFile @269 NONAME - ;SFileSetBasePath @270 NONAME - ;SFileSetFilePointer @271 NONAME - ;SFileSetLocale @272 NONAME - ;SFileGetBasePath @273 NONAME - ;SFileSetIoErrorMode @274 NONAME - ;SFileGetArchiveName @275 NONAME - ;SFileGetFileName @276 NONAME - ;SFileGetArchiveInfo @277 NONAME - ;SFileSetPlatform @278 NONAME - ;SFileLoadFile @279 NONAME - ;SFileUnloadFile @280 NONAME - ;SFileLoadFileEx @281 NONAME - ;SFilePrioritizeRequest @282 NONAME - ;SFileCancelRequest @283 NONAME - ;SFileSetAsyncBudget @284 NONAME - ;SFileSetDataChunkSize @285 NONAME - ;SFileEnableSeekOptimization @286 NONAME - ;SFileReadFileEx @287 NONAME - ;SFileFileExists @288 NONAME - ;SFileFileExistsEx @289 NONAME - ;SFileReadFileEx2 @290 NONAME - ;SFileReadFile2 @291 NONAME - ;SFileLoadFile2 @292 NONAME - ;SFileOpenFileAsArchive @293 NONAME - ;SFileGetLocale @294 NONAME - ;SFileGetInstallPath @295 NONAME ; SFileRegisterLoadNotifyProc in WC3 - ;SFileGetUserDataPath @296 NONAME ; SFileGetFileCompressedSize in WC3 - ;SFileSetUserDataPath @297 NONAME ; different in WC3 - ;SFileAuthenticateArchiveEx @299 NONAME - ;SFileOpenPathAsArchive @300 NONAME - - ; Main - ; This is the only *Destroy function exported, tests will need to use it instead - StormDestroy @301 NONAME - ;StormGetInstance @302 NONAME - ;StormGetOption @303 NONAME - ;StormSetOption @304 NONAME - - ; Blit - ;SBltDestroy @311 NONAME - ;SBltGetSCode @312 NONAME - ;SBltROP3 @313 NONAME - ;SBltROP3Clipped @314 NONAME - ;SBltROP3Tiled @315 NONAME - - ; BMP - ;SBmpDecodeImage @321 NONAME - ;SBmpLoadImage @323 NONAME - ;SBmpSaveImage @324 NONAME - ;SBmpAllocLoadImage @325 NONAME - ;SBmpSaveImageEx @326 NONAME - ;SBmpPadImage @327 NONAME - ;SBmpGetPitchForAlignment @328 NONAME - - ; SCode - ;SCodeCompile @331 NONAME - ;SCodeDelete @332 NONAME - ;SCodeDestroy @333 NONAME - ;SCodeExecute @334 NONAME - ;SCodeGetPseudocode @335 NONAME - - ; Draw - ;SDrawAutoInitialize @341 NONAME - ;SDrawCaptureScreen @342 NONAME - ;SDrawClearSurface @343 NONAME ; SDrawCaptureGDIScreen in SC 1.17 - ;SDrawDestroy @344 NONAME ; SDrawClearSurface in SC 1.17 - ;SDrawFlipPage @345 NONAME ; SDrawDestroy in SC 1.17 - ;SDrawGetFrameWindow @346 NONAME - ;SDrawGetObjects @347 NONAME - ;SDrawGetScreenSize @348 NONAME - ;SDrawGetServiceLevel @349 NONAME ; SDrawFlush in SC 1.17 - ;SDrawLockSurface @350 NONAME - ;SDrawManualInitialize @351 NONAME ; SDrawInitialize in SC 1.17 - ;SDrawMessageBox @352 NONAME - ;SDrawPostClose @353 NONAME - ;SDrawRealizePalette @354 NONAME - ;SDrawSelectGdiSurface @355 NONAME - ;SDrawUnlockSurface @356 NONAME - ;SDrawUpdatePalette @357 NONAME - ;SDrawUpdateScreen @358 NONAME - ;SDrawWaitForVerticalBlank @359 NONAME - - ; Event - ;SEvtDestroy @371 NONAME - SEvtDispatch @372 NONAME - SEvtRegisterHandler @373 NONAME - SEvtUnregisterHandler @374 NONAME - SEvtUnregisterType @375 NONAME - SEvtPopState @376 NONAME - SEvtPushState @377 NONAME - SEvtBreakHandlerChain @378 NONAME - - ; GDI - ;SGdiBitBlt @381 NONAME - ;SGdiCreateFont @382 NONAME - ;SGdiDeleteObject @383 NONAME - ;SGdiDestroy @384 NONAME - ;SGdiExtTextOut @385 NONAME - ;SGdiImportFont @386 NONAME - ;SGdiLoadFont @387 NONAME - ;SGdiRectangle @388 NONAME - ;SGdiSelectObject @389 NONAME - ;SGdiSetPitch @390 NONAME - ;SGdiTextOut @391 NONAME - ;SGdiSetTargetDimensions @392 NONAME - ;SGdiGetTextExtent @393 NONAME - - ; Memory - SMemAlloc @401 NONAME - ;SMemDestroy @402 NONAME - SMemFree @403 NONAME - ;SMemGetSize @404 NONAME - SMemReAlloc @405 NONAME - ;SMemGetAllocated @406 NONAME - - ; Message handling - ;SMsgDestroy @411 NONAME - ;SMsgDispatchMessage @412 NONAME - ;SMsgDoMessageLoop @413 NONAME - ;SMsgRegisterCommand @414 NONAME - ;SMsgRegisterKeyDown @415 NONAME - ;SMsgRegisterKeyUp @416 NONAME - ;SMsgRegisterMessage @417 NONAME - ;SMsgPopRegisterState @418 NONAME - ;SMsgPushRegisterState @419 NONAME - ;SMsgRegisterSysCommand @420 NONAME - - ; Registry - ;SRegLoadData @421 NONAME - ;SRegLoadString @422 NONAME - ;SRegLoadValue @423 NONAME - ;SRegSaveData @424 NONAME - ;SRegSaveString @425 NONAME - ;SRegSaveValue @426 NONAME - ;SRegGetBaseKey @427 NONAME - ;SRegDeleteValue @428 NONAME - ;SRegEnumKey @429 NONAME - ;SRegGetNumSubKeys @430 NONAME - - ; Transparency - ;STransBlt @431 NONAME - ;STransBltUsingMask @432 NONAME - ;STransCreateI @433 NONAME - ;STransDelete @434 NONAME - ;STransDestroy @435 NONAME - ;STransDuplicate @436 NONAME - ;STransIntersectDirtyArray @437 NONAME - ;STransInvertMask @438 NONAME - ;STransLoadI @439 NONAME - ;STransSetDirtyArrayInfo @440 NONAME - ;STransUpdateDirtyArray @441 NONAME - ;STransIsPixelInMask @442 NONAME - ;STransCombineMasks @443 NONAME - ;STransCreateMaskI @444 NONAME - ;STransCreateE @445 NONAME - ;STransCreateMaskE @446 NONAME - ;STransLoadE @447 NONAME - - ; Video - ;SVidDestroy @451 NONAME - ;SVidGetSize @452 NONAME - ;SVidInitialize @453 NONAME - ;SVidPlayBegin @454 NONAME - ;SVidPlayBeginFromMemory @455 NONAME - ;SVidPlayContinue @456 NONAME - ;SVidPlayContinueSingle @457 NONAME - ;SVidPlayEnd @458 NONAME - ;SVidSetVolume @459 NONAME - - ; Error - ;SErrDestroy @460 NONAME - SErrDisplayError @461 NONAME - ;SErrGetErrorStr @462 NONAME - SErrGetLastError @463 NONAME - ;SErrRegisterMessageSource @464 NONAME - ;SErrSetLastError @465 NONAME - ;SErrReportNamedResourceLeak @466 NONAME - ;SErrReportResourceLeak @467 NONAME - SErrSuppressErrors @468 NONAME - ;SErrRegisterHandler @469 NONAME - ;SErrUnregisterHandler @470 NONAME - - ; Command line - ;SCmdGetBool @472 NONAME - ;SCmdGetNum @473 NONAME - ;SCmdGetString @474 NONAME - ;SCmdProcess @475 NONAME - ;SCmdRegisterArgList @476 NONAME - ;SCmdRegisterArgument @477 NONAME - ;SCmdCheckId @478 NONAME - ;SCmdProcessCommandLine @479 NONAME - ;SCmdStringExists @480 NONAME - - ; Memory extended - ;SMemFindNextBlock @481 NONAME - ;SMemFindNextHeap @482 NONAME - ;SMemGetHeapByCaller @483 NONAME - ;SMemGetHeapByPtr @484 NONAME - ;SMemHeapAlloc @485 NONAME - ;SMemHeapCreate @486 NONAME - ;SMemHeapDestroy @487 NONAME - ;SMemHeapFree @488 NONAME - ;SMemHeapRealloc @489 NONAME - ;SMemHeapSize @490 NONAME - SMemCopy @491 NONAME - SMemFill @492 NONAME - SMemMove @493 NONAME - SMemZero @494 NONAME - SMemCmp @495 NONAME - ;SMemSetDebugFlags @496 NONAME - ;SMemDumpState @497 NONAME - - ; Strings - SStrCopy @501 NONAME - SStrHash @502 NONAME - SStrPack @503 NONAME - SStrTokenize @504 NONAME - SStrChrBidir @505 NONAME - SStrLen @506 NONAME - SStrDupA @507 NONAME - SStrCmp @508 NONAME - SStrCmpI @509 NONAME - SStrUpper @510 NONAME - - ; Messages extended - ;SMsgBreakHandlerChain @511 NONAME - ;SMsgUnregisterCommand @512 NONAME - ;SMsgUnregisterKeyDown @513 NONAME - ;SMsgUnregisterKeyUp @514 NONAME - ;SMsgUnregisterMessage @515 NONAME - ;SMsgGetGenericWndProc @516 NONAME - ;SMsgSetDefaultWindow @517 NONAME - ;SMsgGetDefaultWindow @518 NONAME - ;SMsgUnregisterSysCommand @519 NONAME - - ; Regions - SRgnClear @521 NONAME - SRgnCombineRecti @523 NONAME - SRgnCreate @524 NONAME - SRgnDelete @525 NONAME - ;SRgnDestroy @526 NONAME - SRgnDuplicate @527 NONAME - SRgnGetRectParamsi @528 NONAME - SRgnGetRectsi @529 NONAME - SRgnGetBoundingRecti @530 NONAME - SRgnIsPointInRegioni @531 NONAME - SRgnIsRectInRegioni @532 NONAME - SRgnOffseti @533 NONAME - SRgnCombineRectf @534 NONAME - SRgnGetRectParamsf @535 NONAME - SRgnGetRectsf @536 NONAME - SRgnGetBoundingRectf @537 NONAME - SRgnIsPointInRegionf @538 NONAME - SRgnIsRectInRegionf @539 NONAME - SRgnOffsetf @540 NONAME - - ; Logging - ;SLogClose @541 NONAME - ;SLogCreate @542 NONAME - ;SLogSetTimestamp @543 NONAME - ;SLogDump @544 NONAME - ;SLogFlush @545 NONAME - ;SLogFlushAll @546 NONAME - ;SLogPend @547 NONAME - ;SLogWrite @548 NONAME - ;SLogSetAbsIndent @549 NONAME - ;SLogSetIndent @550 NONAME - - ; Compression - ;SCompCompress @551 NONAME - ;SCompDecompress @552 NONAME - - ; Errors extended - ;SLogVWrite @553 NONAME - SErrDisplayAppFatal @561 NONAME - SErrDisplayErrorFmt @562 NONAME - ;SErrIsDisplayingError @563 NONAME - SErrPrepareAppFatal @564 NONAME - ;SErrSetLogTitleString @565 NONAME - ;SErrCheckDebugSymbolLibrary @566 NONAME - ;SErrCatchUnhandledExceptions @567 NONAME - ;SErrSetLogCallback @568 NONAME - - ; Strings extended - ;?SStrChr@@YGPADPADD@Z @569 NONAME ; Not offered in SC 1.17 - ;?SStrChrR@@YGPADPADD@Z @570 NONAME ; Not offered in SC 1.17 - ?SStrChr@@YGPBDPBDD@Z @571 NONAME - ?SStrChrR@@YGPBDPBDD@Z @572 NONAME - SStrToDouble @573 NONAME - SStrToFloat @574 NONAME - SStrToInt @575 NONAME - SStrToUnsigned @576 NONAME - ;SStrToInt64 @577 NONAME - SStrPrintf @578 NONAME - SStrLower @579 NONAME - SStrHash64 @580 NONAME - SStrVPrintf @581 NONAME - - ; More drawing - ;SMsgSetDefaultWindowRect @582 NONAME - ;SMsgGetDefaultWindowRect @583 NONAME - - ; More strings - ?SStrStr@@YGPADPADPBD@Z @584 NONAME - ?SStrStr@@YGPBDPBD0@Z @585 NONAME - ?SStrStrI@@YGPADPADPBD@Z @586 NONAME - ?SStrStrI@@YGPBDPBD0@Z @587 NONAME - - ;SysQueueUserEvent @588 NONAME ; SStrStr in WC3 - ;SStrHashHT @595 NONAME ; Not offered in SC 1.17 - - ; Big numbers - SBigAdd @601 NONAME - SBigAnd @602 NONAME - SBigCompare @603 NONAME - SBigCopy @604 NONAME - SBigDec @605 NONAME - SBigDel @606 NONAME - SBigDiv @607 NONAME - ;SBigFindPrime @608 NONAME - SBigFromBinary @609 NONAME - SBigFromStr @610 NONAME - ;SBigFromStream @611 NONAME - SBigFromUnsigned @612 NONAME - ;SBigGcd @613 NONAME - SBigInc @614 NONAME - ;SBigInvMod @615 NONAME - SBigIsEven @616 NONAME - SBigIsOdd @617 NONAME - SBigIsOne @618 NONAME - ;SBigIsPrime @619 NONAME - SBigIsZero @620 NONAME - SBigMod @621 NONAME - SBigMul @622 NONAME - ;SBigMulMod @623 NONAME - SBigNew @624 NONAME - SBigNot @625 NONAME - SBigOr @626 NONAME - ;SBigPow @627 NONAME - SBigPowMod @628 NONAME - ;SBigRand @629 NONAME - ;SBigSet2Exp @630 NONAME - ;SBigSetOne @631 NONAME - ;SBigSetZero @632 NONAME - SBigShl @633 NONAME - SBigShr @634 NONAME - SBigSquare @635 NONAME - SBigSub @636 NONAME - ;SBigToBinaryArray @637 NONAME - SBigToBinaryBuffer @638 NONAME - ;SBigToBinaryPtr @639 NONAME - ;SBigToStrArray @640 NONAME - ;SBigToStrBuffer @641 NONAME - ;SBigToStrPtr @642 NONAME - ;SBigToStreamArray @643 NONAME - ;SBigToStreamBuffer @644 NONAME - ;SBigToStreamPtr @645 NONAME - SBigToUnsigned @646 NONAME - SBigXor @647 NONAME - - ; Unicode - ;SUniConvertUTF16to8Len @901 NONAME - ;SUniConvertUTF16to8 @902 NONAME - ;SUniConvertUTF8to16Len @903 NONAME - ;SUniConvertUTF8to16 @904 NONAME - SUniSGetUTF8 @905 NONAME - SUniSPutUTF8 @906 NONAME - ;SUniFindAfterUTF8Chr @907 NONAME - ;SUniFindUTF8ChrStart @908 NONAME - ;SUniConvertUTF16ToWin @909 NONAME - ;SUniConvertUTF16ToMac @910 NONAME - ;SUniConvertUTF16ToDos @911 NONAME - ;SUniConvertWinToUTF16 @912 NONAME - ;SUniConvertMacToUTF16 @913 NONAME - ;SUniConvertDosToUTF16 @914 NONAME - ;SUniConvertUTF8ToWin @915 NONAME - +LIBRARY "Storm" + +EXPORTS + ; Networking + ;SNetCreateGame @101 NONAME + ;SNetDestroy @102 NONAME + ;SNetEnumDevices @103 NONAME + ;SNetEnumGames @104 NONAME + ;SNetEnumProviders @105 NONAME + ;SNetDropPlayer @106 NONAME + ;SNetGetGameInfo @107 NONAME + ;SNetGetNetworkLatency @108 NONAME + ;SNetGetNumPlayers @109 NONAME + ;SNetGetOwnerTurnsWaiting @110 NONAME + ;SNetGetPerformanceData @111 NONAME + ;SNetGetPlayerCaps @112 NONAME + ;SNetGetPlayerName @113 NONAME + ;SNetGetProviderCaps @114 NONAME + ;SNetGetTurnsInTransit @115 NONAME + ;SNetInitializeDevice @116 NONAME + ;SNetInitializeProvider @117 NONAME + ;SNetJoinGame @118 NONAME + ;SNetLeaveGame @119 NONAME + ;SNetPerformUpgrade @120 NONAME + ;SNetReceiveMessage @121 NONAME + ;SNetReceiveTurns @122 NONAME + ;SNetRegisterEventHandler @123 NONAME + ;SNetResetLatencyMeasurements @124 NONAME + ;SNetSelectGame @125 NONAME + ;SNetSelectProvider @126 NONAME + ;SNetSendMessage @127 NONAME + ;SNetSendTurn @128 NONAME + ;SNetSetBasePlayer @129 NONAME + ;SNetSetGameMode @130 NONAME + ;SNetUnregisterEventHandler @131 NONAME + ;SErrSetBlizzardErrorFunction @132 ; SNetGetOwnerId in SC beta and Diablo/Hellfire, something else in WC3 1.0.7+ + ;SNetEnumGamesEx @133 NONAME + ;SNetSendServerChatCommand @134 NONAME + ;SNetSendDatagram @135 NONAME + ;SNetReceiveDatagram @136 NONAME + ;SNetDisconnectAll @137 NONAME + ;SNetCreateLadderGame @138 NONAME + ;SNetReportGameResult @139 NONAME + ;SNetCheckDataFile @140 NONAME + + ; Networking (League/Extended) - These are all different in WC3 1.0.7+ + ;SNetSendLeagueCommand @141 NONAME + ;SNetSendReplayPath @142 NONAME + ;SNetGetLeagueId @143 NONAME + ;SNetGetPlayerNames @144 NONAME + ;SNetLeagueLogout @145 NONAME + ;SNetGetReplyName @146 NONAME + ;SNetGetCurrentProviderID @147 NONAME + ;SNetSetCodeSignVerifcationFunction @148 + + ; Dlg + ;SDlgBeginPaint @201 NONAME + ;SDlgBltToWindowI @202 NONAME + ;SDlgCheckTimers @203 NONAME + ;SDlgCreateDialogIndirectParam @204 NONAME + ;SDlgCreateDialogParam @205 NONAME + ;SDlgDefDialogProc @206 NONAME + ;SDlgDestroy @207 NONAME + ;SDlgDialogBoxIndirectParam @208 NONAME + ;SDlgDialogBoxParam @209 NONAME + ;SDlgDrawBitmap @210 NONAME + ;SDlgEndDialog @211 NONAME + ;SDlgEndPaint @212 NONAME + ;SDlgKillTimer @213 NONAME + ;SDlgSetBaseFont @214 NONAME + ;SDlgSetBitmapI @215 NONAME + ;SDlgSetControlBitmaps @216 NONAME + ;SDlgSetCursor @217 NONAME + ;SDlgSetSystemCursor @218 NONAME + ;SDlgSetTimer @219 NONAME + ;SDlgUpdateCursor @220 NONAME + ;SDlgBltToWindowE @221 NONAME + ;SDlgSetBitmapE @222 NONAME + ;SDlgSetLocale @223 NONAME + ;SDlgSetMessageLoopThrottle @224 NONAME + ;SDlgClearWindowMap @225 NONAME + ;SDlgResetWindowPos @226 NONAME + ;SDlgAddWindowToMap @227 NONAME + ;SDlgRemoveWindowFromMap @228 NONAME + ;SDlgAdjustWindowsToParent @229 NONAME + ;SDlgTakeScreenshot @230 NONAME + + ; File + ;SFileAuthenticateArchive @251 NONAME + ;SFileCloseArchive @252 NONAME + ;SFileCloseFile @253 NONAME + ;SFileDdaBegin @254 NONAME + ;SFileDdaBeginEx @255 NONAME + ;SFileDdaDestroy @256 NONAME + ;SFileDdaEnd @257 NONAME + ;SFileDdaGetPos @258 NONAME + ;SFileDdaGetVolume @259 NONAME + ;SFileDdaInitialize @260 NONAME + ;SFileDdaSetVolume @261 NONAME + ;SFileDestroy @262 NONAME + ;SFileEnableDirectAccess @263 NONAME + ;SFileGetFileArchive @264 NONAME + ;SFileGetFileSize @265 NONAME + ;SFileOpenArchive @266 NONAME + ;SFileOpenFile @267 NONAME + ;SFileOpenFileEx @268 NONAME + ;SFileReadFile @269 NONAME + ;SFileSetBasePath @270 NONAME + ;SFileSetFilePointer @271 NONAME + ;SFileSetLocale @272 NONAME + ;SFileGetBasePath @273 NONAME + ;SFileSetIoErrorMode @274 NONAME + ;SFileGetArchiveName @275 NONAME + ;SFileGetFileName @276 NONAME + ;SFileGetArchiveInfo @277 NONAME + ;SFileSetPlatform @278 NONAME + ;SFileLoadFile @279 NONAME + ;SFileUnloadFile @280 NONAME + ;SFileLoadFileEx @281 NONAME + ;SFilePrioritizeRequest @282 NONAME + ;SFileCancelRequest @283 NONAME + ;SFileSetAsyncBudget @284 NONAME + ;SFileSetDataChunkSize @285 NONAME + ;SFileEnableSeekOptimization @286 NONAME + ;SFileReadFileEx @287 NONAME + ;SFileFileExists @288 NONAME + ;SFileFileExistsEx @289 NONAME + ;SFileReadFileEx2 @290 NONAME + ;SFileReadFile2 @291 NONAME + ;SFileLoadFile2 @292 NONAME + ;SFileOpenFileAsArchive @293 NONAME + ;SFileGetLocale @294 NONAME + ;SFileGetInstallPath @295 NONAME ; SFileRegisterLoadNotifyProc in WC3 + ;SFileGetUserDataPath @296 NONAME ; SFileGetFileCompressedSize in WC3 + ;SFileSetUserDataPath @297 NONAME ; different in WC3 + ;SFileAuthenticateArchiveEx @299 NONAME + ;SFileOpenPathAsArchive @300 NONAME + + ; Main + ; This is the only *Destroy function exported, tests will need to use it instead + StormDestroy @301 NONAME + ;StormGetInstance @302 NONAME + ;StormGetOption @303 NONAME + ;StormSetOption @304 NONAME + + ; Blit + ;SBltDestroy @311 NONAME + ;SBltGetSCode @312 NONAME + ;SBltROP3 @313 NONAME + ;SBltROP3Clipped @314 NONAME + ;SBltROP3Tiled @315 NONAME + + ; BMP + ;SBmpDecodeImage @321 NONAME + ;SBmpLoadImage @323 NONAME + ;SBmpSaveImage @324 NONAME + ;SBmpAllocLoadImage @325 NONAME + ;SBmpSaveImageEx @326 NONAME + ;SBmpPadImage @327 NONAME + ;SBmpGetPitchForAlignment @328 NONAME + + ; SCode + ;SCodeCompile @331 NONAME + ;SCodeDelete @332 NONAME + ;SCodeDestroy @333 NONAME + ;SCodeExecute @334 NONAME + ;SCodeGetPseudocode @335 NONAME + + ; Draw + ;SDrawAutoInitialize @341 NONAME + ;SDrawCaptureScreen @342 NONAME + ;SDrawClearSurface @343 NONAME ; SDrawCaptureGDIScreen in SC 1.17 + ;SDrawDestroy @344 NONAME ; SDrawClearSurface in SC 1.17 + ;SDrawFlipPage @345 NONAME ; SDrawDestroy in SC 1.17 + ;SDrawGetFrameWindow @346 NONAME + ;SDrawGetObjects @347 NONAME + ;SDrawGetScreenSize @348 NONAME + ;SDrawGetServiceLevel @349 NONAME ; SDrawFlush in SC 1.17 + ;SDrawLockSurface @350 NONAME + ;SDrawManualInitialize @351 NONAME ; SDrawInitialize in SC 1.17 + ;SDrawMessageBox @352 NONAME + ;SDrawPostClose @353 NONAME + ;SDrawRealizePalette @354 NONAME + ;SDrawSelectGdiSurface @355 NONAME + ;SDrawUnlockSurface @356 NONAME + ;SDrawUpdatePalette @357 NONAME + ;SDrawUpdateScreen @358 NONAME + ;SDrawWaitForVerticalBlank @359 NONAME + + ; Event + ;SEvtDestroy @371 NONAME + SEvtDispatch @372 NONAME + SEvtRegisterHandler @373 NONAME + SEvtUnregisterHandler @374 NONAME + SEvtUnregisterType @375 NONAME + SEvtPopState @376 NONAME + SEvtPushState @377 NONAME + SEvtBreakHandlerChain @378 NONAME + + ; GDI + ;SGdiBitBlt @381 NONAME + ;SGdiCreateFont @382 NONAME + ;SGdiDeleteObject @383 NONAME + ;SGdiDestroy @384 NONAME + ;SGdiExtTextOut @385 NONAME + ;SGdiImportFont @386 NONAME + ;SGdiLoadFont @387 NONAME + ;SGdiRectangle @388 NONAME + ;SGdiSelectObject @389 NONAME + ;SGdiSetPitch @390 NONAME + ;SGdiTextOut @391 NONAME + ;SGdiSetTargetDimensions @392 NONAME + ;SGdiGetTextExtent @393 NONAME + + ; Memory + SMemAlloc @401 NONAME + ;SMemDestroy @402 NONAME + SMemFree @403 NONAME + ;SMemGetSize @404 NONAME + SMemReAlloc @405 NONAME + ;SMemGetAllocated @406 NONAME + + ; Message handling + ;SMsgDestroy @411 NONAME + ;SMsgDispatchMessage @412 NONAME + ;SMsgDoMessageLoop @413 NONAME + ;SMsgRegisterCommand @414 NONAME + ;SMsgRegisterKeyDown @415 NONAME + ;SMsgRegisterKeyUp @416 NONAME + ;SMsgRegisterMessage @417 NONAME + ;SMsgPopRegisterState @418 NONAME + ;SMsgPushRegisterState @419 NONAME + ;SMsgRegisterSysCommand @420 NONAME + + ; Registry + ;SRegLoadData @421 NONAME + ;SRegLoadString @422 NONAME + ;SRegLoadValue @423 NONAME + ;SRegSaveData @424 NONAME + ;SRegSaveString @425 NONAME + ;SRegSaveValue @426 NONAME + ;SRegGetBaseKey @427 NONAME + ;SRegDeleteValue @428 NONAME + ;SRegEnumKey @429 NONAME + ;SRegGetNumSubKeys @430 NONAME + + ; Transparency + ;STransBlt @431 NONAME + ;STransBltUsingMask @432 NONAME + ;STransCreateI @433 NONAME + ;STransDelete @434 NONAME + ;STransDestroy @435 NONAME + ;STransDuplicate @436 NONAME + ;STransIntersectDirtyArray @437 NONAME + ;STransInvertMask @438 NONAME + ;STransLoadI @439 NONAME + ;STransSetDirtyArrayInfo @440 NONAME + ;STransUpdateDirtyArray @441 NONAME + ;STransIsPixelInMask @442 NONAME + ;STransCombineMasks @443 NONAME + ;STransCreateMaskI @444 NONAME + ;STransCreateE @445 NONAME + ;STransCreateMaskE @446 NONAME + ;STransLoadE @447 NONAME + + ; Video + ;SVidDestroy @451 NONAME + ;SVidGetSize @452 NONAME + ;SVidInitialize @453 NONAME + ;SVidPlayBegin @454 NONAME + ;SVidPlayBeginFromMemory @455 NONAME + ;SVidPlayContinue @456 NONAME + ;SVidPlayContinueSingle @457 NONAME + ;SVidPlayEnd @458 NONAME + ;SVidSetVolume @459 NONAME + + ; Error + ;SErrDestroy @460 NONAME + SErrDisplayError @461 NONAME + ;SErrGetErrorStr @462 NONAME + SErrGetLastError @463 NONAME + ;SErrRegisterMessageSource @464 NONAME + ;SErrSetLastError @465 NONAME + ;SErrReportNamedResourceLeak @466 NONAME + ;SErrReportResourceLeak @467 NONAME + SErrSuppressErrors @468 NONAME + ;SErrRegisterHandler @469 NONAME + ;SErrUnregisterHandler @470 NONAME + + ; Command line + ;SCmdGetBool @472 NONAME + ;SCmdGetNum @473 NONAME + ;SCmdGetString @474 NONAME + ;SCmdProcess @475 NONAME + ;SCmdRegisterArgList @476 NONAME + ;SCmdRegisterArgument @477 NONAME + ;SCmdCheckId @478 NONAME + ;SCmdProcessCommandLine @479 NONAME + ;SCmdStringExists @480 NONAME + + ; Memory extended + ;SMemFindNextBlock @481 NONAME + ;SMemFindNextHeap @482 NONAME + ;SMemGetHeapByCaller @483 NONAME + ;SMemGetHeapByPtr @484 NONAME + ;SMemHeapAlloc @485 NONAME + ;SMemHeapCreate @486 NONAME + ;SMemHeapDestroy @487 NONAME + ;SMemHeapFree @488 NONAME + ;SMemHeapRealloc @489 NONAME + ;SMemHeapSize @490 NONAME + SMemCopy @491 NONAME + SMemFill @492 NONAME + SMemMove @493 NONAME + SMemZero @494 NONAME + SMemCmp @495 NONAME + ;SMemSetDebugFlags @496 NONAME + ;SMemDumpState @497 NONAME + + ; Strings + SStrCopy @501 NONAME + SStrHash @502 NONAME + SStrPack @503 NONAME + SStrTokenize @504 NONAME + SStrChrBidir @505 NONAME + SStrLen @506 NONAME + SStrDupA @507 NONAME + SStrCmp @508 NONAME + SStrCmpI @509 NONAME + SStrUpper @510 NONAME + + ; Messages extended + ;SMsgBreakHandlerChain @511 NONAME + ;SMsgUnregisterCommand @512 NONAME + ;SMsgUnregisterKeyDown @513 NONAME + ;SMsgUnregisterKeyUp @514 NONAME + ;SMsgUnregisterMessage @515 NONAME + ;SMsgGetGenericWndProc @516 NONAME + ;SMsgSetDefaultWindow @517 NONAME + ;SMsgGetDefaultWindow @518 NONAME + ;SMsgUnregisterSysCommand @519 NONAME + + ; Regions + SRgnClear @521 NONAME + SRgnCombineRecti @523 NONAME + SRgnCreate @524 NONAME + SRgnDelete @525 NONAME + ;SRgnDestroy @526 NONAME + SRgnDuplicate @527 NONAME + SRgnGetRectParamsi @528 NONAME + SRgnGetRectsi @529 NONAME + SRgnGetBoundingRecti @530 NONAME + SRgnIsPointInRegioni @531 NONAME + SRgnIsRectInRegioni @532 NONAME + SRgnOffseti @533 NONAME + SRgnCombineRectf @534 NONAME + SRgnGetRectParamsf @535 NONAME + SRgnGetRectsf @536 NONAME + SRgnGetBoundingRectf @537 NONAME + SRgnIsPointInRegionf @538 NONAME + SRgnIsRectInRegionf @539 NONAME + SRgnOffsetf @540 NONAME + + ; Logging + ;SLogClose @541 NONAME + ;SLogCreate @542 NONAME + ;SLogSetTimestamp @543 NONAME + ;SLogDump @544 NONAME + ;SLogFlush @545 NONAME + ;SLogFlushAll @546 NONAME + ;SLogPend @547 NONAME + ;SLogWrite @548 NONAME + ;SLogSetAbsIndent @549 NONAME + ;SLogSetIndent @550 NONAME + + ; Compression + ;SCompCompress @551 NONAME + ;SCompDecompress @552 NONAME + + ; Errors extended + ;SLogVWrite @553 NONAME + SErrDisplayAppFatal @561 NONAME + SErrDisplayErrorFmt @562 NONAME + ;SErrIsDisplayingError @563 NONAME + SErrPrepareAppFatal @564 NONAME + ;SErrSetLogTitleString @565 NONAME + ;SErrCheckDebugSymbolLibrary @566 NONAME + ;SErrCatchUnhandledExceptions @567 NONAME + ;SErrSetLogCallback @568 NONAME + + ; Strings extended + ;?SStrChr@@YGPADPADD@Z @569 NONAME ; Not offered in SC 1.17 + ;?SStrChrR@@YGPADPADD@Z @570 NONAME ; Not offered in SC 1.17 + ?SStrChr@@YGPBDPBDD@Z @571 NONAME + ?SStrChrR@@YGPBDPBDD@Z @572 NONAME + SStrToDouble @573 NONAME + SStrToFloat @574 NONAME + SStrToInt @575 NONAME + SStrToUnsigned @576 NONAME + ;SStrToInt64 @577 NONAME + SStrPrintf @578 NONAME + SStrLower @579 NONAME + SStrHash64 @580 NONAME + SStrVPrintf @581 NONAME + + ; More drawing + ;SMsgSetDefaultWindowRect @582 NONAME + ;SMsgGetDefaultWindowRect @583 NONAME + + ; More strings + ?SStrStr@@YGPADPADPBD@Z @584 NONAME + ?SStrStr@@YGPBDPBD0@Z @585 NONAME + ?SStrStrI@@YGPADPADPBD@Z @586 NONAME + ?SStrStrI@@YGPBDPBD0@Z @587 NONAME + + ;SysQueueUserEvent @588 NONAME ; SStrStr in WC3 + ;SStrHashHT @595 NONAME ; Not offered in SC 1.17 + + ; Big numbers + SBigAdd @601 NONAME + SBigAnd @602 NONAME + SBigCompare @603 NONAME + SBigCopy @604 NONAME + SBigDec @605 NONAME + SBigDel @606 NONAME + SBigDiv @607 NONAME + ;SBigFindPrime @608 NONAME + SBigFromBinary @609 NONAME + SBigFromStr @610 NONAME + ;SBigFromStream @611 NONAME + SBigFromUnsigned @612 NONAME + ;SBigGcd @613 NONAME + SBigInc @614 NONAME + ;SBigInvMod @615 NONAME + SBigIsEven @616 NONAME + SBigIsOdd @617 NONAME + SBigIsOne @618 NONAME + ;SBigIsPrime @619 NONAME + SBigIsZero @620 NONAME + SBigMod @621 NONAME + SBigMul @622 NONAME + ;SBigMulMod @623 NONAME + SBigNew @624 NONAME + SBigNot @625 NONAME + SBigOr @626 NONAME + ;SBigPow @627 NONAME + SBigPowMod @628 NONAME + ;SBigRand @629 NONAME + ;SBigSet2Exp @630 NONAME + ;SBigSetOne @631 NONAME + ;SBigSetZero @632 NONAME + SBigShl @633 NONAME + SBigShr @634 NONAME + SBigSquare @635 NONAME + SBigSub @636 NONAME + ;SBigToBinaryArray @637 NONAME + SBigToBinaryBuffer @638 NONAME + ;SBigToBinaryPtr @639 NONAME + ;SBigToStrArray @640 NONAME + ;SBigToStrBuffer @641 NONAME + ;SBigToStrPtr @642 NONAME + ;SBigToStreamArray @643 NONAME + ;SBigToStreamBuffer @644 NONAME + ;SBigToStreamPtr @645 NONAME + SBigToUnsigned @646 NONAME + SBigXor @647 NONAME + + ; Unicode + ;SUniConvertUTF16to8Len @901 NONAME + ;SUniConvertUTF16to8 @902 NONAME + ;SUniConvertUTF8to16Len @903 NONAME + ;SUniConvertUTF8to16 @904 NONAME + SUniSGetUTF8 @905 NONAME + SUniSPutUTF8 @906 NONAME + SUniFindUTF8ChrStart @907 NONAME + SUniFindAfterUTF8Chr @908 NONAME + SUniConvertUTF16ToWin @909 NONAME + SUniConvertUTF16ToMac @910 NONAME + SUniConvertUTF16ToDos @911 NONAME + SUniConvertWinToUTF16 @912 NONAME + SUniConvertMacToUTF16 @913 NONAME + SUniConvertDosToUTF16 @914 NONAME + ;SUniConvertUTF8ToWin @915 NONAME + diff --git a/test/stormdll/stormstubs.cpp b/test/stormdll/stormstubs.cpp index 4da5064..252248a 100644 --- a/test/stormdll/stormstubs.cpp +++ b/test/stormdll/stormstubs.cpp @@ -1,122 +1,130 @@ -#include - -int32_t STORMAPI StormDestroy() { return 0; } - -#include - -void STORMAPI SBigAdd(BigData*, BigData*, BigData*) {} -void STORMAPI SBigAnd(BigData*, BigData*, BigData*) {} -int32_t STORMAPI SBigCompare(BigData*, BigData*) { return 0; } -void STORMAPI SBigCopy(BigData*, BigData*) {} -void STORMAPI SBigDec(BigData*, BigData*) {} -void STORMAPI SBigDel(BigData*) {} -void STORMAPI SBigDiv(BigData*, BigData*, BigData*) {} -void STORMAPI SBigFromBinary(BigData*, const void*, uint32_t) {} -void STORMAPI SBigFromStr(BigData*, const char*) {} -void STORMAPI SBigFromUnsigned(BigData*, uint32_t) {} -void STORMAPI SBigInc(BigData*, BigData*) {} -int32_t STORMAPI SBigIsEven(BigData*) {return 0;} -int32_t STORMAPI SBigIsOdd(BigData*) {return 0;} -int32_t STORMAPI SBigIsOne(BigData*) {return 0;} -int32_t STORMAPI SBigIsZero(BigData*) {return 0;} -void STORMAPI SBigMod(BigData*, BigData*, BigData*) {} -void STORMAPI SBigMul(BigData*, BigData*, BigData*) {} -void STORMAPI SBigNew(BigData**) {} -void STORMAPI SBigNot(BigData*, BigData*) {} -void STORMAPI SBigOr(BigData*, BigData*, BigData*) {} -void STORMAPI SBigPowMod(BigData*, BigData*, BigData*, BigData*) {} -void STORMAPI SBigShl(BigData*, BigData*, uint32_t) {} -void STORMAPI SBigShr(BigData*, BigData*, uint32_t) {} -void STORMAPI SBigSquare(BigData*, BigData*) {} -void STORMAPI SBigSub(BigData*, BigData*, BigData*) {} -void STORMAPI SBigToBinaryBuffer(BigData*, uint8_t*, uint32_t, uint32_t*) {} -void STORMAPI SBigXor(BigData*, BigData*, BigData*) {} -void STORMAPI SBigToUnsigned(BigData*, uint32_t*) {} - -#include - -void STORMCDECL SErrDisplayAppFatal(const char* format, ...) {} -int32_t STORMAPI SErrDisplayError(uint32_t, const char*, int32_t, const char*, int32_t, uint32_t, uint32_t) { return 0; } -int32_t STORMCDECL SErrDisplayErrorFmt(uint32_t, const char*, int32_t, int32_t, uint32_t, const char*, ...) { return 0; } -void STORMAPI SErrPrepareAppFatal(const char*, int32_t) {} -void STORMAPI SErrSetLastError(uint32_t) {} -uint32_t STORMAPI SErrGetLastError() { return 0; } -void STORMAPI SErrSuppressErrors(uint32_t) {} - -#include - -int32_t STORMAPI SEvtBreakHandlerChain(void*) { return 0; } -int32_t STORMAPI SEvtDestroy() { return 0; } -int32_t STORMAPI SEvtDispatch(uint32_t, uint32_t, uint32_t, void*) { return 0; } -int32_t STORMAPI SEvtPopState(uint32_t, uint32_t) { return 0; } -int32_t STORMAPI SEvtPushState(uint32_t, uint32_t) { return 0; } -int32_t STORMAPI SEvtRegisterHandler(uint32_t, uint32_t, uint32_t, uint32_t, SEVTHANDLER) { return 0; } -int32_t STORMAPI SEvtUnregisterHandler(uint32_t, uint32_t, uint32_t, SEVTHANDLER) { return 0; } -int32_t STORMAPI SEvtUnregisterType(uint32_t, uint32_t) { return 0; } - -#include - -void* STORMAPI SMemAlloc(size_t, const char*, int32_t, uint32_t) { return 0; } -int STORMAPI SMemCmp(void*, void*, size_t) { return 0; } -void STORMAPI SMemCopy(void*, void*, size_t) {} -void STORMAPI SMemFill(void*, size_t, uint8_t) {} -void STORMAPI SMemFree(void*, const char*, int32_t, uint32_t) {} -void STORMAPI SMemMove(void*, void*, size_t) {} -void* STORMAPI SMemReAlloc(void*, size_t, const char*, int32_t, uint32_t) { return 0; } -void STORMAPI SMemZero(void*, size_t) {} - -#include - -void STORMAPI SRgnClear(HSRGN) {} -void STORMAPI SRgnCombineRectf(HSRGN, const RECTF*, void*, int32_t) {} -void STORMAPI SRgnCombineRecti(HSRGN, const RECT*, void*, int32_t) {} -void STORMAPI SRgnCreate(HSRGN*, uint32_t) {} -void STORMAPI SRgnDelete(HSRGN) {} -void STORMAPI SRgnDuplicate(HSRGN, HSRGN*, uint32_t) {} -void STORMAPI SRgnGetBoundingRectf(HSRGN, RECTF*) {} -void STORMAPI SRgnGetBoundingRecti(HSRGN, RECT*) {} -void STORMAPI SRgnGetRectParamsf(HSRGN, const RECTF*, uint32_t*, void**) {} -void STORMAPI SRgnGetRectParamsi(HSRGN, const RECT*, uint32_t*, void**) {} -void STORMAPI SRgnGetRectsf(HSRGN, uint32_t*, RECTF*) {} -void STORMAPI SRgnGetRectsi(HSRGN, uint32_t*, RECT*) {} -int32_t STORMAPI SRgnIsPointInRegionf(HSRGN, float, float) { return 0; } -int32_t STORMAPI SRgnIsPointInRegioni(HSRGN, int32_t, int32_t) { return 0; } -int32_t STORMAPI SRgnIsRectInRegionf(HSRGN, const RECTF*) { return 0; } -int32_t STORMAPI SRgnIsRectInRegioni(HSRGN, const RECT*) { return 0; } -void STORMAPI SRgnOffsetf(HSRGN, float, float) {} -void STORMAPI SRgnOffseti(HSRGN, int32_t, int32_t) {} - -#include - -char* STORMAPI SStrChr(char*, char) { return 0; } -const char* STORMAPI SStrChr(const char*, char) { return 0; } -const char* STORMAPI SStrChrBidir(const char*, char, int32_t) { return 0; } -char* STORMAPI SStrChrR(char*, char) { return 0; } -const char* STORMAPI SStrChrR(const char*, char) { return 0; } -int32_t STORMAPI SStrCmp(const char*, const char*, size_t) { return 0; } -int32_t STORMAPI SStrCmpI(const char*, const char*, size_t) { return 0; } -size_t STORMAPI SStrCopy(char*, const char*, size_t) { return 0; } -char* STORMAPI SStrDupA(const char*, const char*, uint32_t) { return 0; } -uint32_t STORMAPI SStrHash(const char*, uint32_t, uint32_t) { return 0; } -uint32_t STORMAPI SStrHashHT(const char*) { return 0; } -int64_t STORMAPI SStrHash64(const char*, uint32_t, int64_t) { return 0; } -size_t STORMAPI SStrLen(const char*) { return 0; } -void STORMAPI SStrLower(char*) {} -uint32_t STORMAPI SStrPack(char*, const char*, uint32_t) { return 0; } -size_t STORMCDECL SStrPrintf(char*, size_t, const char*, ...) { return 0; } -size_t STORMCDECL SStrVPrintf(char*, size_t, const char*, va_list) { return 0; } -char* STORMAPI SStrStr(char*, const char*) { return 0; } -const char* STORMAPI SStrStr(const char*, const char*) { return 0; } -char* STORMAPI SStrStrI(char*, const char*) { return 0; } -const char* STORMAPI SStrStrI(const char*, const char*) { return 0; } -void STORMAPI SStrTokenize(const char**, char*, size_t, const char*, int32_t*) {} -double STORMAPI SStrToDouble(const char*) { return 0; } -float STORMAPI SStrToFloat(const char*) { return 0; } -int32_t STORMAPI SStrToInt(const char*) { return 0; } -uint32_t STORMAPI SStrToUnsigned(const char*) { return 0; } -void STORMAPI SStrUpper(char*) {} - -#include - -uint32_t STORMAPI SUniSGetUTF8(const uint8_t*, int32_t*) {return 0; } -void STORMAPI SUniSPutUTF8(uint32_t, char*) {} +#include + +int32_t STORMAPI StormDestroy() { return 0; } + +#include + +void STORMAPI SBigAdd(BigData*, BigData*, BigData*) {} +void STORMAPI SBigAnd(BigData*, BigData*, BigData*) {} +int32_t STORMAPI SBigCompare(BigData*, BigData*) { return 0; } +void STORMAPI SBigCopy(BigData*, BigData*) {} +void STORMAPI SBigDec(BigData*, BigData*) {} +void STORMAPI SBigDel(BigData*) {} +void STORMAPI SBigDiv(BigData*, BigData*, BigData*) {} +void STORMAPI SBigFromBinary(BigData*, const void*, uint32_t) {} +void STORMAPI SBigFromStr(BigData*, const char*) {} +void STORMAPI SBigFromUnsigned(BigData*, uint32_t) {} +void STORMAPI SBigInc(BigData*, BigData*) {} +int32_t STORMAPI SBigIsEven(BigData*) {return 0;} +int32_t STORMAPI SBigIsOdd(BigData*) {return 0;} +int32_t STORMAPI SBigIsOne(BigData*) {return 0;} +int32_t STORMAPI SBigIsZero(BigData*) {return 0;} +void STORMAPI SBigMod(BigData*, BigData*, BigData*) {} +void STORMAPI SBigMul(BigData*, BigData*, BigData*) {} +void STORMAPI SBigNew(BigData**) {} +void STORMAPI SBigNot(BigData*, BigData*) {} +void STORMAPI SBigOr(BigData*, BigData*, BigData*) {} +void STORMAPI SBigPowMod(BigData*, BigData*, BigData*, BigData*) {} +void STORMAPI SBigShl(BigData*, BigData*, uint32_t) {} +void STORMAPI SBigShr(BigData*, BigData*, uint32_t) {} +void STORMAPI SBigSquare(BigData*, BigData*) {} +void STORMAPI SBigSub(BigData*, BigData*, BigData*) {} +void STORMAPI SBigToBinaryBuffer(BigData*, uint8_t*, uint32_t, uint32_t*) {} +void STORMAPI SBigXor(BigData*, BigData*, BigData*) {} +void STORMAPI SBigToUnsigned(BigData*, uint32_t*) {} + +#include + +void STORMCDECL SErrDisplayAppFatal(const char* format, ...) {} +int32_t STORMAPI SErrDisplayError(uint32_t, const char*, int32_t, const char*, int32_t, uint32_t, uint32_t) { return 0; } +int32_t STORMCDECL SErrDisplayErrorFmt(uint32_t, const char*, int32_t, int32_t, uint32_t, const char*, ...) { return 0; } +void STORMAPI SErrPrepareAppFatal(const char*, int32_t) {} +void STORMAPI SErrSetLastError(uint32_t) {} +uint32_t STORMAPI SErrGetLastError() { return 0; } +void STORMAPI SErrSuppressErrors(uint32_t) {} + +#include + +int32_t STORMAPI SEvtBreakHandlerChain(void*) { return 0; } +int32_t STORMAPI SEvtDestroy() { return 0; } +int32_t STORMAPI SEvtDispatch(uint32_t, uint32_t, uint32_t, void*) { return 0; } +int32_t STORMAPI SEvtPopState(uint32_t, uint32_t) { return 0; } +int32_t STORMAPI SEvtPushState(uint32_t, uint32_t) { return 0; } +int32_t STORMAPI SEvtRegisterHandler(uint32_t, uint32_t, uint32_t, uint32_t, SEVTHANDLER) { return 0; } +int32_t STORMAPI SEvtUnregisterHandler(uint32_t, uint32_t, uint32_t, SEVTHANDLER) { return 0; } +int32_t STORMAPI SEvtUnregisterType(uint32_t, uint32_t) { return 0; } + +#include + +void* STORMAPI SMemAlloc(size_t, const char*, int32_t, uint32_t) { return 0; } +int STORMAPI SMemCmp(void*, void*, size_t) { return 0; } +void STORMAPI SMemCopy(void*, void*, size_t) {} +void STORMAPI SMemFill(void*, size_t, uint8_t) {} +void STORMAPI SMemFree(void*, const char*, int32_t, uint32_t) {} +void STORMAPI SMemMove(void*, void*, size_t) {} +void* STORMAPI SMemReAlloc(void*, size_t, const char*, int32_t, uint32_t) { return 0; } +void STORMAPI SMemZero(void*, size_t) {} + +#include + +void STORMAPI SRgnClear(HSRGN) {} +void STORMAPI SRgnCombineRectf(HSRGN, const RECTF*, void*, int32_t) {} +void STORMAPI SRgnCombineRecti(HSRGN, const RECT*, void*, int32_t) {} +void STORMAPI SRgnCreate(HSRGN*, uint32_t) {} +void STORMAPI SRgnDelete(HSRGN) {} +void STORMAPI SRgnDuplicate(HSRGN, HSRGN*, uint32_t) {} +void STORMAPI SRgnGetBoundingRectf(HSRGN, RECTF*) {} +void STORMAPI SRgnGetBoundingRecti(HSRGN, RECT*) {} +void STORMAPI SRgnGetRectParamsf(HSRGN, const RECTF*, uint32_t*, void**) {} +void STORMAPI SRgnGetRectParamsi(HSRGN, const RECT*, uint32_t*, void**) {} +void STORMAPI SRgnGetRectsf(HSRGN, uint32_t*, RECTF*) {} +void STORMAPI SRgnGetRectsi(HSRGN, uint32_t*, RECT*) {} +int32_t STORMAPI SRgnIsPointInRegionf(HSRGN, float, float) { return 0; } +int32_t STORMAPI SRgnIsPointInRegioni(HSRGN, int32_t, int32_t) { return 0; } +int32_t STORMAPI SRgnIsRectInRegionf(HSRGN, const RECTF*) { return 0; } +int32_t STORMAPI SRgnIsRectInRegioni(HSRGN, const RECT*) { return 0; } +void STORMAPI SRgnOffsetf(HSRGN, float, float) {} +void STORMAPI SRgnOffseti(HSRGN, int32_t, int32_t) {} + +#include + +char* STORMAPI SStrChr(char*, char) { return 0; } +const char* STORMAPI SStrChr(const char*, char) { return 0; } +const char* STORMAPI SStrChrBidir(const char*, char, int32_t) { return 0; } +char* STORMAPI SStrChrR(char*, char) { return 0; } +const char* STORMAPI SStrChrR(const char*, char) { return 0; } +int32_t STORMAPI SStrCmp(const char*, const char*, size_t) { return 0; } +int32_t STORMAPI SStrCmpI(const char*, const char*, size_t) { return 0; } +size_t STORMAPI SStrCopy(char*, const char*, size_t) { return 0; } +char* STORMAPI SStrDupA(const char*, const char*, uint32_t) { return 0; } +uint32_t STORMAPI SStrHash(const char*, uint32_t, uint32_t) { return 0; } +uint32_t STORMAPI SStrHashHT(const char*) { return 0; } +int64_t STORMAPI SStrHash64(const char*, uint32_t, int64_t) { return 0; } +size_t STORMAPI SStrLen(const char*) { return 0; } +void STORMAPI SStrLower(char*) {} +uint32_t STORMAPI SStrPack(char*, const char*, uint32_t) { return 0; } +size_t STORMCDECL SStrPrintf(char*, size_t, const char*, ...) { return 0; } +size_t STORMCDECL SStrVPrintf(char*, size_t, const char*, va_list) { return 0; } +char* STORMAPI SStrStr(char*, const char*) { return 0; } +const char* STORMAPI SStrStr(const char*, const char*) { return 0; } +char* STORMAPI SStrStrI(char*, const char*) { return 0; } +const char* STORMAPI SStrStrI(const char*, const char*) { return 0; } +void STORMAPI SStrTokenize(const char**, char*, size_t, const char*, int32_t*) {} +double STORMAPI SStrToDouble(const char*) { return 0; } +float STORMAPI SStrToFloat(const char*) { return 0; } +int32_t STORMAPI SStrToInt(const char*) { return 0; } +uint32_t STORMAPI SStrToUnsigned(const char*) { return 0; } +void STORMAPI SStrUpper(char*) {} + +#include + +ptrdiff_t STORMAPI SUniConvertUTF16ToDos(char*, const char16_t*, uint32_t) { return 0; }; +ptrdiff_t STORMAPI SUniConvertUTF16ToMac(char*, const char16_t*, uint32_t) { return 0; }; +ptrdiff_t STORMAPI SUniConvertUTF16ToWin(char*, const char16_t*, uint32_t) { return 0; }; +ptrdiff_t STORMAPI SUniConvertDosToUTF16(char16_t*, const char*, uint32_t) { return 0; }; +ptrdiff_t STORMAPI SUniConvertMacToUTF16(char16_t*, const char*, uint32_t) { return 0; }; +ptrdiff_t STORMAPI SUniConvertWinToUTF16(char16_t*, const char*, uint32_t) { return 0; }; +int32_t STORMAPI SUniFindAfterUTF8Chr(const char*, int32_t) { return 0; }; +int32_t STORMAPI SUniFindUTF8ChrStart(const char*, int32_t) { return 0; }; +uint32_t STORMAPI SUniSGetUTF8(const uint8_t*, int32_t*) { return 0; } +void STORMAPI SUniSPutUTF8(uint32_t, char*) {}