aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/restricted/boost/locale/src/std/std_backend.cpp
diff options
context:
space:
mode:
authorthegeorg <thegeorg@yandex-team.com>2025-05-07 11:09:12 +0300
committerthegeorg <thegeorg@yandex-team.com>2025-05-07 11:25:22 +0300
commit4c98f14a2491da2bc1a9d40fed1d1682c7ec5dd6 (patch)
tree8142081775c27c8780fa0282a0273ee268e13b98 /contrib/restricted/boost/locale/src/std/std_backend.cpp
parent40b86c68b431bb65d67bba51ef9159066a833b68 (diff)
downloadydb-4c98f14a2491da2bc1a9d40fed1d1682c7ec5dd6.tar.gz
Update contrib/restricted/boost/locale to 1.88.0
commit_hash:87b595328ea79c6ba38cb973580804486ca4a3ff
Diffstat (limited to 'contrib/restricted/boost/locale/src/std/std_backend.cpp')
-rw-r--r--contrib/restricted/boost/locale/src/std/std_backend.cpp206
1 files changed, 206 insertions, 0 deletions
diff --git a/contrib/restricted/boost/locale/src/std/std_backend.cpp b/contrib/restricted/boost/locale/src/std/std_backend.cpp
new file mode 100644
index 00000000000..1eadfd2491c
--- /dev/null
+++ b/contrib/restricted/boost/locale/src/std/std_backend.cpp
@@ -0,0 +1,206 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+// Copyright (c) 2022-2023 Alexander Grund
+//
+// Distributed under the Boost Software License, Version 1.0.
+// https://www.boost.org/LICENSE_1_0.txt
+
+#include "std_backend.hpp"
+#include <boost/locale/gnu_gettext.hpp>
+#include <boost/locale/localization_backend.hpp>
+#include <boost/locale/util.hpp>
+#include <boost/locale/util/locale_data.hpp>
+#include <boost/assert.hpp>
+#include <boost/core/ignore_unused.hpp>
+#include <algorithm>
+#include <iterator>
+#include <vector>
+
+#if BOOST_LOCALE_USE_WIN32_API
+# ifndef NOMINMAX
+# define NOMINMAX
+# endif
+# include "../win32/lcid.hpp"
+# include <windows.h>
+#endif
+#include "../shared/message.hpp"
+#include "../util/encoding.hpp"
+#include "../util/gregorian.hpp"
+#include "../util/make_std_unique.hpp"
+#include "../util/numeric_conversion.hpp"
+#include "all_generator.hpp"
+
+namespace {
+struct windows_name {
+ std::string name, codepage;
+ explicit operator bool() const { return !name.empty() && !codepage.empty(); }
+};
+
+windows_name to_windows_name(const std::string& l)
+{
+#if BOOST_LOCALE_USE_WIN32_API
+ windows_name res;
+ const unsigned lcid = boost::locale::impl_win::locale_to_lcid(l);
+ char win_lang[256]{};
+ if(lcid == 0 || GetLocaleInfoA(lcid, LOCALE_SENGLANGUAGE, win_lang, sizeof(win_lang)) == 0)
+ return res;
+ res.name = win_lang;
+ char win_country[256]{};
+ if(GetLocaleInfoA(lcid, LOCALE_SENGCOUNTRY, win_country, sizeof(win_country)) != 0) {
+ res.name += "_";
+ res.name += win_country;
+ }
+
+ char win_codepage[10]{};
+ if(GetLocaleInfoA(lcid, LOCALE_IDEFAULTANSICODEPAGE, win_codepage, sizeof(win_codepage)) != 0)
+ res.codepage = win_codepage;
+ return res;
+#else
+ boost::ignore_unused(l);
+ return {};
+#endif
+}
+
+bool loadable(const std::string& name)
+{
+ try {
+ std::locale l(name);
+ return true;
+ } catch(const std::exception&) {
+ return false;
+ }
+}
+} // namespace
+
+namespace boost { namespace locale { namespace impl_std {
+
+ class std_localization_backend : public localization_backend {
+ public:
+ std_localization_backend() : invalid_(true), use_ansi_encoding_(false) {}
+ std_localization_backend(const std_localization_backend& other) :
+ localization_backend(), paths_(other.paths_), domains_(other.domains_), locale_id_(other.locale_id_),
+ invalid_(true), use_ansi_encoding_(other.use_ansi_encoding_)
+ {}
+ std_localization_backend* clone() const override { return new std_localization_backend(*this); }
+
+ void set_option(const std::string& name, const std::string& value) override
+ {
+ invalid_ = true;
+ if(name == "locale")
+ locale_id_ = value;
+ else if(name == "message_path")
+ paths_.push_back(value);
+ else if(name == "message_application")
+ domains_.push_back(value);
+ else if(name == "use_ansi_encoding")
+ use_ansi_encoding_ = value == "true";
+ }
+ void clear_options() override
+ {
+ invalid_ = true;
+ use_ansi_encoding_ = false;
+ locale_id_.clear();
+ paths_.clear();
+ domains_.clear();
+ }
+
+ void prepare_data()
+ {
+ if(!invalid_)
+ return;
+ invalid_ = false;
+ std::string lid = locale_id_;
+ if(lid.empty()) {
+ bool use_utf8 = !use_ansi_encoding_;
+ lid = util::get_system_locale(use_utf8);
+ }
+ in_use_id_ = lid;
+ data_.parse(lid);
+
+ const auto l_win = to_windows_name(lid);
+
+ if(!data_.is_utf8()) {
+ utf_mode_ = utf8_support::none;
+ if(loadable(lid))
+ name_ = lid;
+ else if(l_win && loadable(l_win.name)) {
+ if(util::are_encodings_equal(l_win.codepage, data_.encoding()))
+ name_ = l_win.name;
+ else {
+ int codepage_int;
+ if(util::try_to_int(l_win.codepage, codepage_int)
+ && codepage_int == util::encoding_to_windows_codepage(data_.encoding()))
+ {
+ name_ = l_win.name;
+ } else
+ name_ = "C";
+ }
+ } else
+ name_ = "C";
+ } else {
+ if(loadable(lid)) {
+ name_ = lid;
+ utf_mode_ = utf8_support::native;
+ } else {
+ std::vector<std::string> alt_names;
+ if(l_win)
+ alt_names.push_back(l_win.name);
+ // Try different spellings
+ alt_names.push_back(util::locale_data(data_).encoding("UTF-8").to_string());
+ alt_names.push_back(util::locale_data(data_).encoding("utf8", false).to_string());
+ // Without encoding, let from_wide classes handle it
+ alt_names.push_back(util::locale_data(data_).encoding("").to_string());
+ // Final try: Classic locale, but enable Unicode (if supported)
+ alt_names.push_back("C.UTF-8");
+ alt_names.push_back("C.utf8");
+ // If everything fails rely on the classic locale
+ alt_names.push_back("C");
+ for(const std::string& name : alt_names) {
+ if(loadable(name)) {
+ name_ = name;
+ break;
+ }
+ }
+ BOOST_ASSERT(!name_.empty());
+ utf_mode_ = utf8_support::from_wide;
+ }
+ }
+ }
+
+ std::locale install(const std::locale& base, category_t category, char_facet_t type) override
+ {
+ prepare_data();
+
+ switch(category) {
+ case category_t::convert: return create_convert(base, name_, type, utf_mode_);
+ case category_t::collation: return create_collate(base, name_, type, utf_mode_);
+ case category_t::formatting: return create_formatting(base, name_, type, utf_mode_);
+ case category_t::parsing: return create_parsing(base, name_, type, utf_mode_);
+ case category_t::codepage: return create_codecvt(base, name_, type, utf_mode_);
+ case category_t::calendar: return util::install_gregorian_calendar(base, data_.country());
+ case category_t::message: return detail::install_message_facet(base, type, data_, domains_, paths_);
+ case category_t::information: return util::create_info(base, in_use_id_);
+ case category_t::boundary: break; // Not implemented
+ }
+ return base;
+ }
+
+ private:
+ std::vector<std::string> paths_;
+ std::vector<std::string> domains_;
+ std::string locale_id_;
+
+ util::locale_data data_;
+ std::string name_;
+ std::string in_use_id_;
+ utf8_support utf_mode_;
+ bool invalid_;
+ bool use_ansi_encoding_;
+ };
+
+ std::unique_ptr<localization_backend> create_localization_backend()
+ {
+ return make_std_unique<std_localization_backend>();
+ }
+
+}}} // namespace boost::locale::impl_std