mirror of
https://github.com/luanti-org/luanti.git
synced 2025-10-05 19:31:04 +00:00
Implement language code parsing
This commit is contained in:
parent
56bc7814de
commit
2c91ba2513
6 changed files with 85 additions and 3 deletions
|
@ -19,6 +19,7 @@ set (UNITTEST_SRCS
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/test_irrptr.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test_irr_matrix4.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test_irr_rotation.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test_langcode.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test_logging.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test_lbmmanager.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test_lua.cpp
|
||||
|
|
16
src/unittest/test_langcode.cpp
Normal file
16
src/unittest/test_langcode.cpp
Normal file
|
@ -0,0 +1,16 @@
|
|||
// Luanti
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
#include "util/langcode.h"
|
||||
#include "catch.h"
|
||||
|
||||
TEST_CASE("test langcode")
|
||||
{
|
||||
SECTION("test language list")
|
||||
{
|
||||
CHECK(expand_language_list(L"de_DE@euro.UTF-8:fr") == L"de_DE@euro:de_DE:de:fr");
|
||||
CHECK(expand_language_list(L"zh_HK:yue_HK:zh_TW") == L"zh_HK:yue_HK:yue:zh_TW:zh");
|
||||
CHECK(expand_language_list(L"de_DE:fr:de_CH:en:de:de_AT") == L"de_DE:fr:de_CH:en:de:de_AT");
|
||||
CHECK(expand_language_list(L".UTF-8:de:.ISO-8859-1:fr:.GB2312") == L"de:fr");
|
||||
}
|
||||
}
|
|
@ -11,6 +11,7 @@ set(util_SRCS
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/guid.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hashing.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ieee_float.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/langcode.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/metricsbackend.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/numeric.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/pointedthing.cpp
|
||||
|
|
47
src/util/langcode.cpp
Normal file
47
src/util/langcode.cpp
Normal file
|
@ -0,0 +1,47 @@
|
|||
// Luanti
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
#include <unordered_map>
|
||||
#include "util/string.h"
|
||||
|
||||
std::vector<std::wstring> parse_language_list(const std::wstring &lang)
|
||||
{
|
||||
std::unordered_map<std::wstring, std::wstring> added_by;
|
||||
std::vector<std::vector<std::wstring>> expanded;
|
||||
|
||||
for (const auto &name: str_split(lang, L':')) {
|
||||
auto pos = name.find(L'.'); // strip encoding information
|
||||
const auto realname = pos == name.npos ? name : name.substr(0, pos);
|
||||
if (realname.empty())
|
||||
continue;
|
||||
|
||||
std::vector<std::wstring> basenames = {};
|
||||
auto base = realname;
|
||||
do {
|
||||
if (added_by[base] == base)
|
||||
break;
|
||||
added_by[base] = realname;
|
||||
basenames.push_back(base);
|
||||
|
||||
pos = base.find_last_of(L"_@");
|
||||
base = base.substr(0, pos);
|
||||
} while (pos != base.npos);
|
||||
if (!basenames.empty())
|
||||
expanded.push_back(std::move(basenames));
|
||||
}
|
||||
|
||||
std::vector<std::wstring> langlist;
|
||||
for (auto &basenames: expanded)
|
||||
{
|
||||
auto first = basenames.front();
|
||||
for (auto &&name: basenames)
|
||||
if (added_by[name] == first)
|
||||
langlist.push_back(std::move(name));
|
||||
}
|
||||
return langlist;
|
||||
}
|
||||
|
||||
std::wstring expand_language_list(const std::wstring &lang)
|
||||
{
|
||||
return str_join(parse_language_list(lang), L":");
|
||||
}
|
9
src/util/langcode.h
Normal file
9
src/util/langcode.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
// Luanti
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
std::vector<std::wstring> parse_language_list(const std::wstring &lang);
|
||||
std::wstring expand_language_list(const std::wstring &lang);
|
|
@ -746,11 +746,12 @@ inline const std::string duration_to_string(int sec)
|
|||
*
|
||||
* @return A std::string
|
||||
*/
|
||||
template<typename T>
|
||||
[[nodiscard]]
|
||||
inline std::string str_join(const std::vector<std::string> &list,
|
||||
std::string_view delimiter)
|
||||
inline std::basic_string<T> str_join(const std::vector<std::basic_string<T>> &list,
|
||||
std::basic_string_view<T> delimiter)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
std::basic_ostringstream<T> oss;
|
||||
bool first = true;
|
||||
for (const auto &part : list) {
|
||||
if (!first)
|
||||
|
@ -761,6 +762,13 @@ inline std::string str_join(const std::vector<std::string> &list,
|
|||
return oss.str();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline std::basic_string<T> str_join(const std::vector<std::basic_string<T>> &list,
|
||||
const T *delimiter)
|
||||
{
|
||||
return str_join(list, std::basic_string_view<T>(delimiter));
|
||||
}
|
||||
|
||||
#if IS_CLIENT_BUILD
|
||||
/**
|
||||
* Create a UTF8 std::string from an core::stringw.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue