From 505fe43d5a876f02eee58743495a1811e85fac06 Mon Sep 17 00:00:00 2001 From: Chris Thrasher Date: Sun, 2 Feb 2025 23:25:18 -0700 Subject: [PATCH] Use Unicode literals --- cmake/Macros.cmake | 14 ++++++++ test/Audio/InputSoundFile.test.cpp | 16 +++++----- test/Audio/Music.test.cpp | 4 +-- test/Audio/SoundBuffer.test.cpp | 4 +-- test/Graphics/Image.test.cpp | 16 +++++----- test/Graphics/Shader.test.cpp | 6 ++-- test/System/FileInputStream.test.cpp | 4 +-- test/System/String.test.cpp | 48 ++++++++++++++-------------- 8 files changed, 62 insertions(+), 50 deletions(-) diff --git a/cmake/Macros.cmake b/cmake/Macros.cmake index eed932f3f..dc3ca351a 100644 --- a/cmake/Macros.cmake +++ b/cmake/Macros.cmake @@ -274,6 +274,10 @@ macro(sfml_add_library module) target_compile_definitions(${target} PUBLIC "SFML_STATIC") endif() + # Enable support for UTF-8 characters in source code + if(SFML_COMPILER_MSVC) + target_compile_options(${target} PRIVATE /utf-8) + endif() endmacro() # add a new target which is a SFML example @@ -350,6 +354,11 @@ macro(sfml_add_example target) if(SFML_OS_WINDOWS AND SFML_USE_MESA3D) add_dependencies(${target} "install-mesa3d") endif() + + # Enable support for UTF-8 characters in source code + if(SFML_COMPILER_MSVC) + target_compile_options(${target} PRIVATE /utf-8) + endif() endmacro() # add a new target which is a SFML test @@ -407,6 +416,11 @@ function(sfml_add_test target SOURCES DEPENDS) endif() endif() + # Enable support for UTF-8 characters in source code + if(SFML_COMPILER_MSVC) + target_compile_options(${target} PRIVATE /utf-8) + endif() + # Add the test catch_discover_tests(${target} WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}) endfunction() diff --git a/test/Audio/InputSoundFile.test.cpp b/test/Audio/InputSoundFile.test.cpp index aed421565..f13c8d986 100644 --- a/test/Audio/InputSoundFile.test.cpp +++ b/test/Audio/InputSoundFile.test.cpp @@ -171,12 +171,12 @@ TEST_CASE("[Audio] sf::InputSoundFile") SECTION("Polish filename") { - REQUIRE(inputSoundFile.openFromFile(U"Audio/ding-\u0144.flac")); + REQUIRE(inputSoundFile.openFromFile(U"Audio/ding-ń.flac")); } SECTION("Emoji filename") { - REQUIRE(inputSoundFile.openFromFile(U"Audio/ding-\U0001F40C.flac")); + REQUIRE(inputSoundFile.openFromFile(U"Audio/ding-🐌.flac")); } CHECK(inputSoundFile.getSampleCount() == 87'798); @@ -196,12 +196,12 @@ TEST_CASE("[Audio] sf::InputSoundFile") SECTION("Polish filename") { - REQUIRE(inputSoundFile.openFromFile(U"Audio/ding-\u0144.mp3")); + REQUIRE(inputSoundFile.openFromFile(U"Audio/ding-ń.mp3")); } SECTION("Emoji filename") { - REQUIRE(inputSoundFile.openFromFile(U"Audio/ding-\U0001F40C.mp3")); + REQUIRE(inputSoundFile.openFromFile(U"Audio/ding-🐌.mp3")); } CHECK(inputSoundFile.getSampleCount() == 87'798); @@ -221,12 +221,12 @@ TEST_CASE("[Audio] sf::InputSoundFile") SECTION("Polish filename") { - REQUIRE(inputSoundFile.openFromFile(U"Audio/doodle_pop-\u0144.ogg")); + REQUIRE(inputSoundFile.openFromFile(U"Audio/doodle_pop-ń.ogg")); } SECTION("Emoji filename") { - REQUIRE(inputSoundFile.openFromFile(U"Audio/doodle_pop-\U0001F40C.ogg")); + REQUIRE(inputSoundFile.openFromFile(U"Audio/doodle_pop-🐌.ogg")); } CHECK(inputSoundFile.getSampleCount() == 2'116'992); @@ -246,12 +246,12 @@ TEST_CASE("[Audio] sf::InputSoundFile") SECTION("Polish filename") { - REQUIRE(inputSoundFile.openFromFile(U"Audio/killdeer-\u0144.wav")); + REQUIRE(inputSoundFile.openFromFile(U"Audio/killdeer-ń.wav")); } SECTION("Emoji filename") { - REQUIRE(inputSoundFile.openFromFile(U"Audio/killdeer-\U0001F40C.wav")); + REQUIRE(inputSoundFile.openFromFile(U"Audio/killdeer-🐌.wav")); } CHECK(inputSoundFile.getSampleCount() == 112'941); diff --git a/test/Audio/Music.test.cpp b/test/Audio/Music.test.cpp index aab05dfce..ebc086958 100644 --- a/test/Audio/Music.test.cpp +++ b/test/Audio/Music.test.cpp @@ -140,12 +140,12 @@ TEST_CASE("[Audio] sf::Music", runAudioDeviceTests()) SECTION("Polish filename") { - REQUIRE(music.openFromFile(U"Audio/ding-\u0144.mp3")); + REQUIRE(music.openFromFile(U"Audio/ding-ń.mp3")); } SECTION("Emoji filename") { - REQUIRE(music.openFromFile(U"Audio/ding-\U0001F40C.mp3")); + REQUIRE(music.openFromFile(U"Audio/ding-🐌.mp3")); } CHECK(music.getDuration() == sf::microseconds(1990884)); diff --git a/test/Audio/SoundBuffer.test.cpp b/test/Audio/SoundBuffer.test.cpp index 3d24f1601..f0db1c376 100644 --- a/test/Audio/SoundBuffer.test.cpp +++ b/test/Audio/SoundBuffer.test.cpp @@ -129,12 +129,12 @@ TEST_CASE("[Audio] sf::SoundBuffer", runAudioDeviceTests()) SECTION("Polish filename") { - REQUIRE(soundBuffer.loadFromFile(U"Audio/ding-\u0144.flac")); + REQUIRE(soundBuffer.loadFromFile(U"Audio/ding-ń.flac")); } SECTION("Emoji filename") { - REQUIRE(soundBuffer.loadFromFile(U"Audio/ding-\U0001F40C.flac")); + REQUIRE(soundBuffer.loadFromFile(U"Audio/ding-🐌.flac")); } CHECK(soundBuffer.getSamples() != nullptr); diff --git a/test/Graphics/Image.test.cpp b/test/Graphics/Image.test.cpp index 5337c3916..10bcf627b 100644 --- a/test/Graphics/Image.test.cpp +++ b/test/Graphics/Image.test.cpp @@ -266,16 +266,16 @@ TEST_CASE("[Graphics] sf::Image") CHECK(!image.loadFromFile("this/does/not/exist.jpg")); // small n with tilde, from Spanish, outside of ASCII, inside common Latin 1 codepage - CHECK(!image.loadFromFile(std::filesystem::path(U"missing-file-\u00f1.png"))); + CHECK(!image.loadFromFile(std::filesystem::path(U"missing-file-ñ.png"))); // small n with acute accent, from Polish, outside of Latin 1 codepage - CHECK(!image.loadFromFile(std::filesystem::path(U"missing-file-\u0144.png"))); + CHECK(!image.loadFromFile(std::filesystem::path(U"missing-file-ń.png"))); // CJK symbol for Sun, outside of any European language codepage - CHECK(!image.loadFromFile(std::filesystem::path(U"missing-file-\u65E5.png"))); + CHECK(!image.loadFromFile(std::filesystem::path(U"missing-file-日.png"))); // snail emoji, outside of Unicode Basic Multilingual Plane - CHECK(!image.loadFromFile(std::filesystem::path(U"missing-file-\U0001F40C.png"))); + CHECK(!image.loadFromFile(std::filesystem::path(U"missing-file-🐌.png"))); CHECK(image.getSize() == sf::Vector2u(0, 0)); CHECK(image.getPixelsPtr() == nullptr); @@ -472,25 +472,25 @@ TEST_CASE("[Graphics] sf::Image") SECTION("To Spanish Latin1 filename .png") { // small n with tilde, from Spanish, outside of ASCII, inside common Latin 1 codepage - filename /= U"test-\u00f1.png"; + filename /= U"test-ñ.png"; } SECTION("To Polish filename .png") { // small n with acute accent, from Polish, outside of Latin 1 codepage - filename /= U"test-\u0144.png"; + filename /= U"test-ń.png"; } SECTION("To Japanese CJK filename .png") { // CJK symbol for Sun, outside of any European language codepage - filename /= U"test-\u65E5.png"; + filename /= U"test-日.png"; } SECTION("To emoji non-BMP Unicode filename .png") { // snail emoji, outside of Unicode Basic Multilingual Plane - filename /= U"test-\U0001F40C.png"; + filename /= U"test-🐌.png"; } // Cannot test JPEG encoding due to it triggering UB in stbiw__jpg_writeBits diff --git a/test/Graphics/Shader.test.cpp b/test/Graphics/Shader.test.cpp index 194c085fc..a44238911 100644 --- a/test/Graphics/Shader.test.cpp +++ b/test/Graphics/Shader.test.cpp @@ -425,12 +425,10 @@ TEST_CASE("[Graphics] sf::Shader", skipShaderFullTests()) SECTION("One shader with non-ASCII filename") { - CHECK(shader.loadFromFile(U"Graphics/shader-\u0144.vert", sf::Shader::Type::Vertex) == - sf::Shader::isAvailable()); + CHECK(shader.loadFromFile(U"Graphics/shader-ń.vert", sf::Shader::Type::Vertex) == sf::Shader::isAvailable()); CHECK(static_cast(shader.getNativeHandle()) == sf::Shader::isAvailable()); - CHECK(shader.loadFromFile(U"Graphics/shader-\U0001F40C.vert", sf::Shader::Type::Vertex) == - sf::Shader::isAvailable()); + CHECK(shader.loadFromFile(U"Graphics/shader-🐌.vert", sf::Shader::Type::Vertex) == sf::Shader::isAvailable()); CHECK(static_cast(shader.getNativeHandle()) == sf::Shader::isAvailable()); } } diff --git a/test/System/FileInputStream.test.cpp b/test/System/FileInputStream.test.cpp index 0823e7848..96e6c0bf7 100644 --- a/test/System/FileInputStream.test.cpp +++ b/test/System/FileInputStream.test.cpp @@ -102,12 +102,12 @@ TEST_CASE("[System] sf::FileInputStream") SECTION("From Polish filename") { - REQUIRE(fileInputStream.open(U"System/test-\u0144.txt")); + REQUIRE(fileInputStream.open(U"System/test-ń.txt")); } SECTION("From emoji filename") { - REQUIRE(fileInputStream.open(U"System/test-\U0001F40C.txt")); + REQUIRE(fileInputStream.open(U"System/test-🐌.txt")); } CHECK(fileInputStream.read(buffer.data(), 5) == 5); diff --git a/test/System/String.test.cpp b/test/System/String.test.cpp index 7c8f35359..dac24bebe 100644 --- a/test/System/String.test.cpp +++ b/test/System/String.test.cpp @@ -353,14 +353,14 @@ TEST_CASE("[System] sf::String") SECTION("UTF-32 character constructor") { - const sf::String string = U'\U0010AFAF'; + const sf::String string = U'🐌'; CHECK(std::string(string) == "\0"s); - CHECK(std::wstring(string) == select(L""s, L"\U0010AFAF"s)); + CHECK(std::wstring(string) == select(L""s, L"🐌"s)); CHECK(string.toAnsiString() == "\0"s); - CHECK(string.toWideString() == select(L""s, L"\U0010AFAF"s)); - CHECK(string.toUtf8() == sf::U8String{0xF4, 0x8A, 0xBE, 0xAF}); - CHECK(string.toUtf16() == u"\U0010AFAF"s); - CHECK(string.toUtf32() == U"\U0010AFAF"s); + CHECK(string.toWideString() == select(L""s, L"🐌"s)); + CHECK(string.toUtf8() == sf::U8String{0xF0, 0x9F, 0x90, 0x8C}); + CHECK(string.toUtf16() == u"🐌"s); + CHECK(string.toUtf32() == U"🐌"s); CHECK(string.getSize() == 1); CHECK(!string.isEmpty()); CHECK(string.getData() != nullptr); @@ -385,14 +385,14 @@ TEST_CASE("[System] sf::String") SECTION("Non-empty string") { - const sf::String string = U"\U0010ABCDrs"; + const sf::String string = U"🐌rs"; CHECK(std::string(string) == "\0rs"s); - CHECK(std::wstring(string) == select(L"rs"s, L"\U0010ABCDrs"s)); + CHECK(std::wstring(string) == select(L"rs"s, L"🐌rs"s)); CHECK(string.toAnsiString() == "\0rs"s); - CHECK(string.toWideString() == select(L"rs"s, L"\U0010ABCDrs"s)); - CHECK(string.toUtf8() == sf::U8String{0xF4, 0x8A, 0xAF, 0x8D, 'r', 's'}); - CHECK(string.toUtf16() == u"\U0010ABCDrs"s); - CHECK(string.toUtf32() == U"\U0010ABCDrs"s); + CHECK(string.toWideString() == select(L"rs"s, L"🐌rs"s)); + CHECK(string.toUtf8() == sf::U8String{0xF0, 0x9F, 0x90, 0x8C, 'r', 's'}); + CHECK(string.toUtf16() == u"🐌rs"s); + CHECK(string.toUtf32() == U"🐌rs"s); CHECK(string.getSize() == 3); CHECK(!string.isEmpty()); CHECK(string.getData() != nullptr); @@ -401,14 +401,14 @@ TEST_CASE("[System] sf::String") SECTION("UTF-32 string constructor") { - const sf::String string = U"tuv\U00104321"s; + const sf::String string = U"tuv🐌"s; CHECK(std::string(string) == "tuv\0"s); - CHECK(std::wstring(string) == select(L"tuv"s, L"tuv\U00104321"s)); + CHECK(std::wstring(string) == select(L"tuv"s, L"tuv🐌"s)); CHECK(string.toAnsiString() == "tuv\0"s); - CHECK(string.toWideString() == select(L"tuv"s, L"tuv\U00104321"s)); - CHECK(string.toUtf8() == sf::U8String{'t', 'u', 'v', 0xF4, 0x84, 0x8C, 0xA1}); - CHECK(string.toUtf16() == u"tuv\U00104321"s); - CHECK(string.toUtf32() == U"tuv\U00104321"s); + CHECK(string.toWideString() == select(L"tuv"s, L"tuv🐌"s)); + CHECK(string.toUtf8() == sf::U8String{'t', 'u', 'v', 0xF0, 0x9F, 0x90, 0x8C}); + CHECK(string.toUtf16() == u"tuv🐌"s); + CHECK(string.toUtf32() == U"tuv🐌"s); CHECK(string.getSize() == 4); CHECK(!string.isEmpty()); CHECK(string.getData() != nullptr); @@ -461,15 +461,15 @@ TEST_CASE("[System] sf::String") SECTION("fromUtf32()") { - constexpr std::array characters{'w', 0x104321, 'y', 'z'}; + constexpr std::array characters{'w', U'🐌', 'y', 'z'}; const sf::String string = sf::String::fromUtf32(characters.begin(), characters.end()); CHECK(std::string(string) == "w\0yz"s); - CHECK(std::wstring(string) == select(L"wyz"s, L"w\U00104321yz"s)); + CHECK(std::wstring(string) == select(L"wyz"s, L"w🐌yz"s)); CHECK(string.toAnsiString() == "w\0yz"s); - CHECK(string.toWideString() == select(L"wyz"s, L"w\U00104321yz"s)); - CHECK(string.toUtf8() == sf::U8String{'w', 0xF4, 0x84, 0x8C, 0xA1, 'y', 'z'}); - CHECK(string.toUtf16() == u"w\U00104321yz"s); - CHECK(string.toUtf32() == U"w\U00104321yz"s); + CHECK(string.toWideString() == select(L"wyz"s, L"w🐌yz"s)); + CHECK(string.toUtf8() == sf::U8String{'w', 0xF0, 0x9F, 0x90, 0x8C, 'y', 'z'}); + CHECK(string.toUtf16() == u"w🐌yz"s); + CHECK(string.toUtf32() == U"w🐌yz"s); CHECK(string.getSize() == 4); CHECK(!string.isEmpty()); CHECK(string.getData() != nullptr);