From b5984ea8f2c4b988dcbab5a026f69c5d29e9ab55 Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Tue, 19 Sep 2023 18:02:18 +0200 Subject: [PATCH] Port to macOS Signed-off-by: Simon Rozman --- UnitTests/compat.hpp | 8 ++++++ UnitTests/parser.cpp | 30 +++++++++++++--------- include/stdex/parser.hpp | 39 ++++++++++++++-------------- include/stdex/stream.hpp | 2 ++ include/stdex/string.hpp | 53 ++++++++++++++++++++++++++++++++++++++- include/stdex/system.hpp | 2 +- include/stdex/unicode.hpp | 2 +- 7 files changed, 101 insertions(+), 35 deletions(-) diff --git a/UnitTests/compat.hpp b/UnitTests/compat.hpp index c9c642a0a..2585dcb90 100644 --- a/UnitTests/compat.hpp +++ b/UnitTests/compat.hpp @@ -34,6 +34,14 @@ namespace Assert throw std::runtime_error("not equal"); } + template + inline void AreEqual(const T (&a)[N], const T (&b)[N]) + { + for (size_t i = 0; i < N; ++i) + if (!(a[i] == b[i])) + throw std::runtime_error("not equal"); + } + inline void AreEqual(const char* a, const char* b) { if (strcmp(a, b) != 0) diff --git a/UnitTests/parser.cpp b/UnitTests/parser.cpp index f990821f8..1c21fa042 100644 --- a/UnitTests/parser.cpp +++ b/UnitTests/parser.cpp @@ -187,8 +187,9 @@ namespace UnitTests } { - wspace_cu space; - wiban p(make_shared_no_delete(&space)); + std::locale locale_slSI("sl_SI"); + wspace_cu space(false, locale_slSI); + wiban p(make_shared_no_delete(&space), locale_slSI); Assert::IsTrue(p.match(L"SI56023120015226972", 0, SIZE_MAX)); Assert::IsTrue(p.is_valid); Assert::AreEqual(L"SI", p.country); @@ -212,8 +213,9 @@ namespace UnitTests } { - wspace_cu space; - wcreditor_reference p(make_shared_no_delete(&space)); + std::locale locale_slSI("sl_SI"); + wspace_cu space(false, locale_slSI); + wcreditor_reference p(make_shared_no_delete(&space), locale_slSI); Assert::IsTrue(p.match(L"RF18539007547034", 0, SIZE_MAX)); Assert::IsTrue(p.is_valid); Assert::AreEqual(L"18", p.check_digits); @@ -235,8 +237,9 @@ namespace UnitTests } { - wspace_cu space; - wsi_reference p(make_shared_no_delete(&space)); + std::locale locale_slSI("sl_SI"); + wspace_cu space(false, locale_slSI); + wsi_reference p(make_shared_no_delete(&space), locale_slSI); Assert::IsTrue(p.match(L"SI121234567890120", 0, SIZE_MAX)); Assert::IsTrue(p.is_valid); Assert::AreEqual(L"12", p.model); @@ -301,8 +304,9 @@ namespace UnitTests } { - sgml_space_cp space; - sgml_iban p(make_shared_no_delete(&space)); + std::locale locale_slSI("sl_SI"); + sgml_space_cp space(false, locale_slSI); + sgml_iban p(make_shared_no_delete(&space), locale_slSI); Assert::IsTrue(p.match("SI56023120015226972", 0, SIZE_MAX)); Assert::IsTrue(p.is_valid); Assert::AreEqual("SI", p.country); @@ -326,8 +330,9 @@ namespace UnitTests } { - sgml_space_cp space; - sgml_creditor_reference p(make_shared_no_delete(&space)); + std::locale locale_slSI("sl_SI"); + sgml_space_cp space(false, locale_slSI); + sgml_creditor_reference p(make_shared_no_delete(&space), locale_slSI); Assert::IsTrue(p.match("RF18539007547034", 0, SIZE_MAX)); Assert::IsTrue(p.is_valid); Assert::AreEqual("18", p.check_digits); @@ -349,8 +354,9 @@ namespace UnitTests } { - sgml_space_cp space; - sgml_si_reference p(make_shared_no_delete(&space)); + std::locale locale_slSI("sl_SI"); + sgml_space_cp space(false, locale_slSI); + sgml_si_reference p(make_shared_no_delete(&space), locale_slSI); Assert::IsTrue(p.match("SI121234567890120", 0, SIZE_MAX)); Assert::IsTrue(p.is_valid); Assert::AreEqual("12", p.model); diff --git a/include/stdex/parser.hpp b/include/stdex/parser.hpp index 54eef6504..edc4dedd3 100644 --- a/include/stdex/parser.hpp +++ b/include/stdex/parser.hpp @@ -414,7 +414,7 @@ namespace stdex }; using space_cu = basic_space_cu; - using wspace_cu = basic_space_cu; + using wspace_cu = basic_space_cu; #ifdef _UNICODE using tspace_cu = wspace_cu; #else @@ -4692,18 +4692,6 @@ namespace stdex assert(text || start >= end); const auto& ctype = std::use_facet>(this->m_locale); const bool case_insensitive = flags & match_case_insensitive ? true : false; - - this->interval.end = start; - for (size_t i = 0; i < 2; ++i, ++this->interval.end) { - if (this->interval.end >= end || !text[this->interval.end]) - goto error; // incomplete country code - T chr = case_insensitive ? ctype.toupper(text[this->interval.end]) : text[this->interval.end]; - if (chr < 'A' || 'Z' < chr) - goto error; // invalid country code - this->country[i] = chr; - } - this->country[2] = 0; - struct country_t { T country[2]; T check_digits[2]; @@ -4818,6 +4806,17 @@ namespace stdex { { 'X', 'K' }, {}, 20 }, // Kosovo }; const country_t* country_desc = nullptr; + size_t n; + + this->interval.end = start; + for (size_t i = 0; i < 2; ++i, ++this->interval.end) { + if (this->interval.end >= end || !text[this->interval.end]) + goto error; // incomplete country code + T chr = case_insensitive ? ctype.toupper(text[this->interval.end]) : text[this->interval.end]; + if (chr < 'A' || 'Z' < chr) + goto error; // invalid country code + this->country[i] = chr; + } for (size_t l = 0, r = _countof(s_countries);;) { if (l >= r) goto error; // unknown country @@ -4832,6 +4831,7 @@ namespace stdex break; } } + this->country[2] = 0; for (size_t i = 0; i < 2; ++i, ++this->interval.end) { if (this->interval.end >= end || text[this->interval.end] < '0' || '9' < text[this->interval.end]) @@ -4844,8 +4844,7 @@ namespace stdex (country_desc->check_digits[1] && this->check_digits[1] != country_desc->check_digits[1])) goto error; // unexpected check digits - size_t n = 0; - for (; ;) { + for (n = 0; ;) { if (m_space && m_space->match(text, this->interval.end, end, flags)) this->interval.end = m_space->interval.end; for (size_t j = 0; j < 4; ++j) { @@ -4994,6 +4993,8 @@ namespace stdex assert(text || start >= end); const auto& ctype = std::use_facet>(this->m_locale); const bool case_insensitive = flags & match_case_insensitive ? true : false; + size_t n, available, next; + uint32_t nominator; this->interval.end = start; if (this->interval.end + 1 >= end || @@ -5009,8 +5010,7 @@ namespace stdex } this->check_digits[2] = 0; - size_t n = 0; - for (;;) { + for (n = 0;;) { if (m_space && m_space->match(text, this->interval.end, end, flags)) this->interval.end = m_space->interval.end; for (size_t j = 0; j < 4; ++j) { @@ -5038,7 +5038,7 @@ namespace stdex // Normalize creditor reference. T normalized[47]; - size_t available = 0; + available = 0; for (size_t i = 0; ; ++i) { if (!this->reference[i]) { normalized[available++] = '2'; // R @@ -5067,8 +5067,7 @@ namespace stdex } // Calculate modulo 97. - size_t next; - uint32_t nominator = stdex::strtou32(normalized, 9, &next, 10); + nominator = stdex::strtou32(normalized, 9, &next, 10); for (;;) { nominator %= 97; if (!normalized[next]) { diff --git a/include/stdex/stream.hpp b/include/stdex/stream.hpp index 71d0a17ae..39ea8163f 100644 --- a/include/stdex/stream.hpp +++ b/include/stdex/stream.hpp @@ -77,6 +77,8 @@ namespace stdex public: basic(_In_ state_t state = state_t::ok) : m_state(state) {} + virtual ~basic() noexcept(false) {} + /// /// Reads block of data from the stream /// diff --git a/include/stdex/string.hpp b/include/stdex/string.hpp index d7d17b3ff..1ab6e4f5f 100644 --- a/include/stdex/string.hpp +++ b/include/stdex/string.hpp @@ -1,4 +1,4 @@ -/* +/* SPDX-License-Identifier: MIT Copyright © 2016-2023 Amebis */ @@ -401,6 +401,57 @@ namespace stdex return collate.compare(str1, str1 + count1, str2, str2 + count2); } + /// + /// Binary compare two strings case-insensitive + /// + /// \param[in] str1 String 1 + /// \param[in] str2 String 2 + /// + /// \return Negative if str1str2; zero if str1==str2 + /// + template + inline int stricmp(_In_z_ const T1* str1, _In_z_ const T2* str2, _In_ const std::locale& locale) + { + assert(str1); + assert(str2); + size_t i; T1 a; T2 b; + const auto& ctype1 = std::use_facet>(locale); + const auto& ctype2 = std::use_facet>(locale); + for (i = 0; (a = ctype1.tolower(str1[i])) | (b = ctype2.tolower(str2[i])); i++) { + if (a > b) return +1; + if (a < b) return -1; + } + if (str1[i]) return +1; + if (str2[i]) return -1; + return 0; + } + + /// + /// Binary compare two strings case-insensitive + /// + /// \param[in] str1 String 1 + /// \param[in] str2 String 2 + /// \param[in] count Code unit count limit + /// + /// \return Negative if str1str2; zero if str1==str2 + /// + template + inline int strnicmp(_In_reads_or_z_opt_(count) const T1* str1, _In_reads_or_z_opt_(count) const T2* str2, _In_ size_t count, _In_ const std::locale& locale) + { + assert(str1 || !count); + assert(str2 || !count); + size_t i; T1 a; T2 b; + const auto& ctype1 = std::use_facet>(locale); + const auto& ctype2 = std::use_facet>(locale); + for (i = 0; i < count && ((a = ctype1.tolower(str1[i])) | (b = ctype2.tolower(str2[i]))); i++) { + if (a > b) return +1; + if (a < b) return -1; + } + if (i < count && str1[i]) return +1; + if (i < count && str2[i]) return -1; + return 0; + } + /// /// Binary compare two strings case-insensitive /// diff --git a/include/stdex/system.hpp b/include/stdex/system.hpp index dac29d3aa..0ed54ed10 100644 --- a/include/stdex/system.hpp +++ b/include/stdex/system.hpp @@ -117,7 +117,7 @@ namespace stdex return *this; } - virtual ~sys_object() + virtual ~sys_object() noexcept(false) { if (m_h != invalid_handle) close(m_h); diff --git a/include/stdex/unicode.hpp b/include/stdex/unicode.hpp index bec5fe1d5..ba208239b 100644 --- a/include/stdex/unicode.hpp +++ b/include/stdex/unicode.hpp @@ -1,4 +1,4 @@ -/* +/* SPDX-License-Identifier: MIT Copyright © 2023 Amebis */