chromium/ui/base/l10n/l10n_util.cc

// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

#include "ui/base/l10n/l10n_util.h"

#include <cstdlib>
#include <iterator>
#include <memory>
#include <string>
#include <string_view>

#include "base/check_op.h"
#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/containers/fixed_flat_set.h"
#include "base/files/file_util.h"
#include "base/i18n/file_util_icu.h"
#include "base/i18n/message_formatter.h"
#include "base/i18n/number_formatting.h"
#include "base/i18n/rtl.h"
#include "base/i18n/string_compare.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/no_destructor.h"
#include "base/notreached.h"
#include "base/ranges/algorithm.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "third_party/icu/source/common/unicode/rbbi.h"
#include "third_party/icu/source/common/unicode/uloc.h"
#include "ui/base/l10n/l10n_util_collator.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_paths.h"

#if BUILDFLAG(IS_ANDROID)
#include "base/android/locale_utils.h"
#include "ui/base/l10n/l10n_util_android.h"
#endif

#if BUILDFLAG(IS_IOS)
#include "ui/base/l10n/l10n_util_ios.h"
#endif

#if defined(USE_GLIB)
#include <glib.h>
#endif

#if BUILDFLAG(IS_WIN)
#include "base/logging.h"
#include "ui/base/l10n/l10n_util_win.h"
#endif  // BUILDFLAG(IS_WIN)

namespace {

constexpr auto kAcceptLanguageList =;

// The list of locales that expected on the current platform, generated from the
// |locales| variable in GN (defined in build/config/locales.gni). This is
// equivalently the list of locales that we expect to have translation strings
// for on the current platform. Guaranteed to be in sorted order and guaranteed
// to have no duplicates.
//
// Note that this could have false positives at runtime on Android and iOS:
// - On Android, locale files are dynamically shipped in app bundles which are
//   only downloaded when needed - so the |locales| variable does not accurately
//   reflect the UI strings that are currently available on disk.
//   See the comment at the top of |LoadLocaleResources| in
//   ui/base/resource/resource_bundle_android.cc for more information.
// - On iOS, some locales aren't shipped (|ios_unsupported_locales|) as they are
//   not supported by the operating system. These locales are included in this
//   variable.
//
// To avoid false positives on these platforms, use
// ui::ResourceBundle::LocaleDataPakExists() to check whether the locales exist
// on disk instead (requires I/O).
static const char* const kPlatformLocales[] =;

// Returns true if |locale_name| has an alias in the ICU data file.
bool IsDuplicateName(const std::string& locale_name) {}

// We added 30+ minimally populated locales with only a few entries
// (exemplar character set, script, writing direction and its own
// lanaguage name). These locales have to be distinguished from the
// fully populated locales to which Chrome is localized.
bool IsLocalePartiallyPopulated(const std::string& locale_name) {}

// If |perform_io| is false, this will not perform any I/O but may return false
// positives on Android and iOS. See the |kPlatformLocales| documentation for
// more information.
bool HasStringsForLocale(const std::string& locale,
                         const bool perform_io = true) {}

// On Linux, the text layout engine Pango determines paragraph directionality
// by looking at the first strongly-directional character in the text. This
// means text such as "Google Chrome foo bar..." will be layed out LTR even
// if "foo bar" is RTL. So this function prepends the necessary RLM in such
// cases.
void AdjustParagraphDirectionality(std::u16string* paragraph) {}

struct AvailableLocalesTraits
    : base::internal::DestructorAtExitLazyInstanceTraits<
          std::vector<std::string>> {};

base::LazyInstance<std::vector<std::string>, AvailableLocalesTraits>
    g_available_locales =;

}  // namespace

namespace l10n_util {

std::string GetLanguage(std::string_view locale) {}

std::string GetCountry(std::string_view locale) {}

// TODO(jshin): revamp this function completely to use a more systematic
// and generic locale fallback based on ICU/CLDR.
bool CheckAndResolveLocale(const std::string& locale,
                           std::string* resolved_locale,
                           const bool perform_io) {}

bool CheckAndResolveLocale(const std::string& locale,
                           std::string* resolved_locale) {}

#if BUILDFLAG(IS_APPLE)
std::string GetApplicationLocaleInternalMac(const std::string& pref_locale) {
  // Use any override (Cocoa for the browser), otherwise use the preference
  // passed to the function.
  std::string app_locale = l10n_util::GetLocaleOverride();
  if (app_locale.empty())
    app_locale = pref_locale;

  // The above should handle all of the cases Chrome normally hits, but for some
  // unit tests, we need something to fall back too.
  if (app_locale.empty())
    app_locale = "en-US";

  return app_locale;
}
#endif

#if !BUILDFLAG(IS_APPLE)
std::string GetApplicationLocaleInternalNonMac(const std::string& pref_locale) {}
#endif  // !BUILDFLAG(IS_APPLE)

std::string GetApplicationLocaleInternal(const std::string& pref_locale) {}

std::string GetApplicationLocale(const std::string& pref_locale,
                                 bool set_icu_locale) {}

std::string GetApplicationLocale(const std::string& pref_locale) {}

bool IsLocaleNameTranslated(std::string_view locale,
                            std::string_view display_locale) {}

std::u16string GetDisplayNameForLocaleWithoutCountry(
    std::string_view locale,
    std::string_view display_locale,
    bool is_for_ui,
    bool disallow_default) {}

std::u16string GetDisplayNameForLocale(std::string_view locale,
                                       std::string_view display_locale,
                                       bool is_for_ui,
                                       bool disallow_default) {}

std::u16string GetDisplayNameForCountry(const std::string& country_code,
                                        const std::string& display_locale) {}

std::string NormalizeLocale(const std::string& locale) {}

void GetParentLocales(const std::string& current_locale,
                      std::vector<std::string>* parent_locales) {}

bool IsValidLocaleSyntax(const std::string& locale) {}

std::string GetStringUTF8(int message_id) {}

std::u16string GetStringUTF16(int message_id) {}

std::u16string FormatString(const std::u16string& format_string,
                            const std::vector<std::u16string>& replacements,
                            std::vector<size_t>* offsets) {}

std::u16string GetStringFUTF16(int message_id,
                               const std::vector<std::u16string>& replacements,
                               std::vector<size_t>* offsets) {}

std::string GetStringFUTF8(int message_id, const std::u16string& a) {}

std::string GetStringFUTF8(int message_id,
                           const std::u16string& a,
                           const std::u16string& b) {}

std::string GetStringFUTF8(int message_id,
                           const std::u16string& a,
                           const std::u16string& b,
                           const std::u16string& c) {}

std::string GetStringFUTF8(int message_id,
                           const std::u16string& a,
                           const std::u16string& b,
                           const std::u16string& c,
                           const std::u16string& d) {}

std::u16string GetStringFUTF16(int message_id, const std::u16string& a) {}

std::u16string GetStringFUTF16(int message_id,
                               const std::u16string& a,
                               const std::u16string& b) {}

std::u16string GetStringFUTF16(int message_id,
                               const std::u16string& a,
                               const std::u16string& b,
                               const std::u16string& c) {}

std::u16string GetStringFUTF16(int message_id,
                               const std::u16string& a,
                               const std::u16string& b,
                               const std::u16string& c,
                               const std::u16string& d) {}

std::u16string GetStringFUTF16(int message_id,
                               const std::u16string& a,
                               const std::u16string& b,
                               const std::u16string& c,
                               const std::u16string& d,
                               const std::u16string& e) {}

std::u16string GetStringFUTF16(int message_id,
                               const std::u16string& a,
                               size_t* offset) {}

std::u16string GetStringFUTF16(int message_id,
                               const std::u16string& a,
                               const std::u16string& b,
                               std::vector<size_t>* offsets) {}

std::u16string GetStringFUTF16Int(int message_id, int a) {}

std::u16string GetStringFUTF16Int(int message_id, int64_t a) {}

std::u16string GetPluralStringFUTF16(int message_id, int number) {}

std::string GetPluralStringFUTF8(int message_id, int number) {}

std::u16string GetSingleOrMultipleStringUTF16(int message_id,
                                              bool is_multiple) {}

void SortStrings16(const std::string& locale,
                   std::vector<std::u16string>* strings) {}

const std::vector<std::string>& GetAvailableICULocales() {}

bool IsUserFacingUILocale(const std::string& locale) {}

const std::vector<std::string>& GetUserFacingUILocaleList() {}

void GetAcceptLanguagesForLocale(const std::string& display_locale,
                                 std::vector<std::string>* locale_codes) {}

void GetAcceptLanguages(std::vector<std::string>* locale_codes) {}

bool IsPossibleAcceptLanguage(std::string_view locale) {}

bool IsAcceptLanguageDisplayable(const std::string& display_locale,
                                 const std::string& locale) {}

std::vector<std::string> KeepAcceptedLanguages(
    base::span<const std::string> languages) {}

int GetLocalizedContentsWidthInPixels(int pixel_resource_id) {}

std::vector<std::string_view> GetAcceptLanguageListForTesting() {}

const char* const* GetPlatformLocalesForTesting() {}

size_t GetPlatformLocalesSizeForTesting() {}

}  // namespace l10n_util