Sync with Xcode

Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
2025-03-12 11:14:19 +01:00
parent bfd8aaff65
commit 2694f59d79
3 changed files with 144 additions and 66 deletions

View File

@@ -14,7 +14,9 @@
#include <stdint.h>
#include <stdio.h>
#include <time.h>
#ifdef _WIN32
#include <uchar.h>
#endif
#ifdef __APPLE__
#include <xlocale.h>
#endif
@@ -888,8 +890,9 @@ namespace stdex
{
stdex_assert(str1);
stdex_assert(str2);
size_t i; T1 a; T2 b;
for (i = 0; (a = str1[i]) | (b = str2[i]); ++i) {
size_t i;
unsigned int a, b;
for (i = 0; (a = static_cast<unsigned int>(str1[i])) | (b = static_cast<unsigned int>(str2[i])); ++i) {
if (a > b) return +1;
if (a < b) return -1;
}
@@ -912,8 +915,9 @@ namespace stdex
{
stdex_assert(str1 || !count);
stdex_assert(str2 || !count);
size_t i; T1 a; T2 b;
for (i = 0; i < count && ((a = str1[i]) | (b = str2[i])); ++i) {
size_t i;
unsigned int a, b;
for (i = 0; i < count && ((a = static_cast<unsigned int>(str1[i])) | (b = static_cast<unsigned int>(str2[i]))); ++i) {
if (a > b) return +1;
if (a < b) return -1;
}
@@ -940,9 +944,10 @@ namespace stdex
stdex_assert(str1 || !count1);
stdex_assert(str2 || !count2);
size_t i;
unsigned int a, b;
for (i = 0; i < count1 && i < count2; ++i) {
auto a = str1[i];
auto b = str2[i];
a = static_cast<unsigned int>(str1[i]);
b = static_cast<unsigned int>(str2[i]);
if (!a && !b) return 0;
if (a > b) return +1;
if (a < b) return -1;
@@ -984,7 +989,8 @@ namespace stdex
{
stdex_assert(str1 || !count1);
stdex_assert(str2 || !count2);
size_t i, j, j_next; utf32_t a, b;
size_t i, j, j_next;
utf32_t a, b;
for (i = 0, j = 0; i < count1 && j < count2; ++i, j = j_next) {
a = str1[i];
if (!a)
@@ -1176,9 +1182,10 @@ namespace stdex
stdex_assert(str1);
stdex_assert(str2);
size_t i;
unsigned int a, b;
for (i = 0; ; ++i) {
auto a = tolower(str1[i]);
auto b = tolower(str2[i]);
a = static_cast<unsigned int>(tolower(str1[i]));
b = static_cast<unsigned int>(tolower(str2[i]));
if (!a && !b) return 0;
if (a > b) return +1;
if (a < b) return -1;
@@ -1200,11 +1207,12 @@ namespace stdex
stdex_assert(str1);
stdex_assert(str2);
size_t i;
unsigned int a, b;
const auto& ctype1 = std::use_facet<std::ctype<T1>>(locale);
const auto& ctype2 = std::use_facet<std::ctype<T2>>(locale);
for (i = 0;; ++i) {
auto a = ctype1.tolower(str1[i]);
auto b = ctype2.tolower(str2[i]);
a = static_cast<unsigned int>(ctype1.tolower(str1[i]));
b = static_cast<unsigned int>(ctype2.tolower(str2[i]));
if (!a && !b) return 0;
if (a > b) return +1;
if (a < b) return -1;
@@ -1226,9 +1234,10 @@ namespace stdex
stdex_assert(str1 || !count);
stdex_assert(str2 || !count);
size_t i;
unsigned int a, b;
for (i = 0; i < count; ++i) {
auto a = tolower(str1[i]);
auto b = tolower(str2[i]);
a = static_cast<unsigned int>(tolower(str1[i]));
b = static_cast<unsigned int>(tolower(str2[i]));
if (!a && !b) return 0;
if (a > b) return +1;
if (a < b) return -1;
@@ -1254,11 +1263,12 @@ namespace stdex
stdex_assert(str1 || !count);
stdex_assert(str2 || !count);
size_t i;
unsigned int a, b;
const auto& ctype1 = std::use_facet<std::ctype<T1>>(locale);
const auto& ctype2 = std::use_facet<std::ctype<T2>>(locale);
for (i = 0; i < count; ++i) {
auto a = ctype1.tolower(str1[i]);
auto b = ctype2.tolower(str2[i]);
a = static_cast<unsigned int>(ctype1.tolower(str1[i]));
b = static_cast<unsigned int>(ctype2.tolower(str2[i]));
if (!a && !b) return 0;
if (a > b) return +1;
if (a < b) return -1;
@@ -1286,9 +1296,10 @@ namespace stdex
stdex_assert(str1 || !count1);
stdex_assert(str2 || !count2);
size_t i;
unsigned int a, b;
for (i = 0; i < count1 && i < count2; ++i) {
auto a = tolower(str1[i]);
auto b = tolower(str2[i]);
a = static_cast<unsigned int>(tolower(str1[i]));
b = static_cast<unsigned int>(tolower(str2[i]));
if (!a && !b) return 0;
if (a > b) return +1;
if (a < b) return -1;
@@ -1318,11 +1329,12 @@ namespace stdex
stdex_assert(str1 || !count1);
stdex_assert(str2 || !count2);
size_t i;
unsigned int a, b;
const auto& ctype1 = std::use_facet<std::ctype<T1>>(locale);
const auto& ctype2 = std::use_facet<std::ctype<T2>>(locale);
for (i = 0; i < count1 && i < count2; ++i) {
auto a = ctype1.tolower(str1[i]);
auto b = ctype2.tolower(str2[i]);
a = static_cast<unsigned int>(ctype1.tolower(str1[i]));
b = static_cast<unsigned int>(ctype2.tolower(str2[i]));
if (!a && !b) return 0;
if (a > b) return +1;
if (a < b) return -1;
@@ -1691,7 +1703,9 @@ namespace stdex
for (size_t j = 0, i = 0; ; ++j, ++i) {
// strcpy has no knowledge, how big the dst buffer is, but we know, we won't be writing more than strlen(src) + 1 characters into it.
// Code Analysis somehow doesn't work this out from the code and the dst SAL above, and reports a false-positive warning.
#ifdef _MSC_VER
#pragma warning(suppress: 6386)
#endif
if ((dst[j] = (is_surrogate_pair(&src[i]) ? surrogate_pair_to_ucs4(&src[i++]) : static_cast<utf32_t>(src[i]))) == 0)
return j;
}
@@ -2734,16 +2748,18 @@ namespace stdex
///
/// Formats string using `printf()`.
///
/// \param[out] str Output string
/// \param[out] str Output string. When this function returns <capacity, output string is zero terminated.
/// \param[in ] capacity Number of available code units in str
/// \param[in ] format String template using `printf()` style
/// \param[in ] locale Stdlib locale used to perform formatting. Use `NULL` to use locale globally set by `setlocale()`.
///
/// \return Number of output code units
/// \return Number of output code units not including zero terminator
///
template<class T>
inline size_t snprintf(_Out_z_cap_(capacity) T* str, _In_ size_t capacity, _In_z_ _Printf_format_string_params_(2) const T* format, _In_opt_ locale_t locale, ...)
{
if (!capacity) _Unlikely_
return 0;
va_list arg;
va_start(arg, locale);
int count = vsnprintf(str, capacity, format, locale, arg);
@@ -2763,7 +2779,7 @@ namespace stdex
return capacity;
#else
switch (errno) {
case EOVERFLOW: return capacity;
case EOVERFLOW: return capacity - 1;
case EINVAL: throw std::invalid_argument("invalid snprintf arguments");
case EILSEQ: throw std::runtime_error("encoding error");
default: throw std::runtime_error("failed to format string");