UnicodeSymbols.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /*
  2. * Copyright (c) 2021, Tim Flynn <trflynn89@pm.me>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <LibUnicode/UnicodeSymbols.h>
  7. #if ENABLE_UNICODE_DATA
  8. # if defined(__serenity__)
  9. # include <LibDl/dlfcn.h>
  10. # include <LibDl/dlfcn_integration.h>
  11. # else
  12. # include <dlfcn.h>
  13. # endif
  14. #else
  15. # include <AK/Function.h>
  16. # include <LibUnicode/Locale.h>
  17. # include <LibUnicode/NumberFormat.h>
  18. #endif
  19. namespace Unicode::Detail {
  20. #if !ENABLE_UNICODE_DATA
  21. template<typename T>
  22. struct FunctionStub;
  23. template<typename ReturnType, typename... ParameterTypes>
  24. struct FunctionStub<Function<ReturnType(ParameterTypes...)>> {
  25. static constexpr auto make_stub()
  26. {
  27. if constexpr (IsVoid<ReturnType>)
  28. return [](ParameterTypes...) {};
  29. else
  30. return [](ParameterTypes...) -> ReturnType { return {}; };
  31. }
  32. };
  33. #endif
  34. // This loader supports 3 modes:
  35. //
  36. // 1. When the Unicode data generators are enabled, and the target is Serenity, the symbols are
  37. // dynamically loaded from the shared library containing them.
  38. //
  39. // 2. When the Unicode data generators are enabled, and the target is Lagom, the symbols are
  40. // dynamically loaded from the main program.
  41. //
  42. // 3. When the Unicode data generators are disabled, the symbols are stubbed out to empty lambdas.
  43. // This allows callers to remain agnostic as to whether the generators are enabled.
  44. Symbols const& Symbols::ensure_loaded()
  45. {
  46. static Symbols symbols {};
  47. static bool initialized = false;
  48. if (initialized)
  49. return symbols;
  50. #if ENABLE_UNICODE_DATA
  51. # if defined(__serenity__)
  52. static void* libunicodedata = MUST(__dlopen("libunicodedata.so.serenity", RTLD_NOW));
  53. auto load_symbol = [&]<typename T>(T& dest, char const* name) {
  54. dest = reinterpret_cast<T>(MUST(__dlsym(libunicodedata, name)));
  55. };
  56. # else
  57. static void* libunicodedata = dlopen(nullptr, RTLD_NOW);
  58. VERIFY(libunicodedata);
  59. auto load_symbol = [&]<typename T>(T& dest, char const* name) {
  60. dest = reinterpret_cast<T>(dlsym(libunicodedata, name));
  61. VERIFY(dest);
  62. };
  63. # endif
  64. #else
  65. auto load_symbol = []<typename T>(T& dest, char const*) {
  66. dest = +FunctionStub<Function<RemovePointer<T>>>::make_stub();
  67. };
  68. #endif
  69. load_symbol(symbols.code_point_display_name, "unicode_code_point_display_name");
  70. load_symbol(symbols.canonical_combining_class, "unicode_canonical_combining_class");
  71. load_symbol(symbols.simple_uppercase_mapping, "unicode_simple_uppercase_mapping");
  72. load_symbol(symbols.simple_lowercase_mapping, "unicode_simple_lowercase_mapping");
  73. load_symbol(symbols.special_case_mapping, "unicode_special_case_mapping");
  74. load_symbol(symbols.general_category_from_string, "unicode_general_category_from_string");
  75. load_symbol(symbols.code_point_has_general_category, "unicode_code_point_has_general_category");
  76. load_symbol(symbols.property_from_string, "unicode_property_from_string");
  77. load_symbol(symbols.code_point_has_property, "unicode_code_point_has_property");
  78. load_symbol(symbols.script_from_string, "unicode_script_from_string");
  79. load_symbol(symbols.code_point_has_script, "unicode_code_point_has_script");
  80. load_symbol(symbols.code_point_has_script_extension, "unicode_code_point_has_script_extension");
  81. load_symbol(symbols.locale_from_string, "unicode_locale_from_string");
  82. load_symbol(symbols.get_locale_language_mapping, "unicode_get_locale_language_mapping");
  83. load_symbol(symbols.get_locale_territory_mapping, "unicode_get_locale_territory_mapping");
  84. load_symbol(symbols.get_locale_script_tag_mapping, "unicode_get_locale_script_tag_mapping");
  85. load_symbol(symbols.get_locale_long_currency_mapping, "unicode_get_locale_long_currency_mapping");
  86. load_symbol(symbols.get_locale_short_currency_mapping, "unicode_get_locale_short_currency_mapping");
  87. load_symbol(symbols.get_locale_narrow_currency_mapping, "unicode_get_locale_narrow_currency_mapping");
  88. load_symbol(symbols.get_locale_numeric_currency_mapping, "unicode_get_locale_numeric_currency_mapping");
  89. load_symbol(symbols.get_locale_key_mapping, "unicode_get_locale_key_mapping");
  90. load_symbol(symbols.get_locale_list_pattern_mapping, "unicode_get_locale_list_pattern_mapping");
  91. load_symbol(symbols.resolve_language_alias, "unicode_resolve_language_alias");
  92. load_symbol(symbols.resolve_territory_alias, "unicode_resolve_territory_alias");
  93. load_symbol(symbols.resolve_script_tag_alias, "unicode_resolve_script_tag_alias");
  94. load_symbol(symbols.resolve_variant_alias, "unicode_resolve_variant_alias");
  95. load_symbol(symbols.resolve_subdivision_alias, "unicode_resolve_subdivision_alias");
  96. load_symbol(symbols.resolve_complex_language_aliases, "unicode_resolve_complex_language_aliases");
  97. load_symbol(symbols.add_likely_subtags, "unicode_add_likely_subtags");
  98. load_symbol(symbols.resolve_most_likely_territory, "unicode_resolve_most_likely_territory");
  99. load_symbol(symbols.get_number_system_symbol, "unicode_get_number_system_symbol");
  100. load_symbol(symbols.get_number_system_groupings, "unicode_get_number_system_groupings");
  101. load_symbol(symbols.get_standard_number_system_format, "unicode_get_standard_number_system_format");
  102. load_symbol(symbols.get_compact_number_system_formats, "unicode_get_compact_number_system_formats");
  103. load_symbol(symbols.get_unit_formats, "unicode_get_unit_formats");
  104. initialized = true;
  105. return symbols;
  106. }
  107. }