summaryrefslogtreecommitdiff
path: root/Build/source/libs/icu/icu-src/source/common/putil.cpp
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2018-01-12 18:35:28 +0000
committerKarl Berry <karl@freefriends.org>2018-01-12 18:35:28 +0000
commit39cc3fec95f3782316910590bb86993918c9dcdf (patch)
tree2315d3b06410f34b2cfd5c73ba6cc53610752030 /Build/source/libs/icu/icu-src/source/common/putil.cpp
parent424a61bc1ceab7381e71b1535c7639f61d2645ba (diff)
icu-60.2
git-svn-id: svn://tug.org/texlive/trunk@46290 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/libs/icu/icu-src/source/common/putil.cpp')
-rw-r--r--Build/source/libs/icu/icu-src/source/common/putil.cpp387
1 files changed, 290 insertions, 97 deletions
diff --git a/Build/source/libs/icu/icu-src/source/common/putil.cpp b/Build/source/libs/icu/icu-src/source/common/putil.cpp
index abf2aac830f..5d2df349295 100644
--- a/Build/source/libs/icu/icu-src/source/common/putil.cpp
+++ b/Build/source/libs/icu/icu-src/source/common/putil.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2016 and later: Unicode, Inc. and others.
+// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
******************************************************************************
@@ -43,7 +43,10 @@
// Must be before any other #includes.
#include "uposixdefs.h"
-#if (U_PF_MINGW <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN) && defined(__STRICT_ANSI__)
+// First, the platform type. Need this for U_PLATFORM.
+#include "unicode/platform.h"
+
+#if (U_PF_CYGWIN <= U_PLATFORM) && defined(__STRICT_ANSI__)
/* tzset isn't defined in strict ANSI on Cygwin and MinGW. */
#undef __STRICT_ANSI__
#endif
@@ -57,8 +60,7 @@
#include <sys/time.h>
#endif
-/* include ICU headers */
-#include "unicode/utypes.h"
+/* include the rest of the ICU headers */
#include "unicode/putil.h"
#include "unicode/ustring.h"
#include "putilimp.h"
@@ -90,14 +92,29 @@
* Should Cygwin be included as well (U_PLATFORM_HAS_WIN32_API)
* to use native APIs as much as possible?
*/
+#ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
+#endif
# define VC_EXTRALEAN
# define NOUSER
# define NOSERVICE
# define NOIME
# define NOMCX
# include <windows.h>
+# include "unicode/uloc.h"
+#if U_PLATFORM_HAS_WINUWP_API == 0
# include "wintz.h"
+#else // U_PLATFORM_HAS_WINUWP_API
+typedef PVOID LPMSG; // TODO: figure out how to get rid of this typedef
+#include <Windows.Globalization.h>
+#include <windows.system.userprofile.h>
+#include <wrl/wrappers/corewrappers.h>
+#include <wrl/client.h>
+
+using namespace ABI::Windows::Foundation;
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+#endif
#elif U_PLATFORM == U_PF_OS400
# include <float.h>
# include <qusec.h> /* error code structure */
@@ -651,13 +668,23 @@ uprv_timezone()
/* Note that U_TZNAME does *not* have to be tzname, but if it is,
some platforms need to have it declared here. */
-#if defined(U_TZNAME) && (U_PLATFORM == U_PF_IRIX || U_PLATFORM_IS_DARWIN_BASED || (U_PLATFORM == U_PF_CYGWIN && !U_PLATFORM_USES_ONLY_WIN32_API))
+#if defined(U_TZNAME) && (U_PLATFORM == U_PF_IRIX || U_PLATFORM_IS_DARWIN_BASED)
/* RS6000 and others reject char **tzname. */
extern U_IMPORT char *U_TZNAME[];
#endif
#if !UCONFIG_NO_FILE_IO && ((U_PLATFORM_IS_DARWIN_BASED && (U_PLATFORM != U_PF_IPHONE || defined(U_TIMEZONE))) || U_PLATFORM_IS_LINUX_BASED || U_PLATFORM == U_PF_BSD || U_PLATFORM == U_PF_SOLARIS)
/* These platforms are likely to use Olson timezone IDs. */
+/* common targets of the symbolic link at TZDEFAULT are:
+ * "/usr/share/zoneinfo/<olsonID>" default, older Linux distros, macOS to 10.12
+ * "../usr/share/zoneinfo/<olsonID>" newer Linux distros: Red Hat Enterprise Linux 7, Ubuntu 16, SuSe Linux 12
+ * "/usr/share/lib/zoneinfo/<olsonID>" Solaris
+ * "../usr/share/lib/zoneinfo/<olsonID>" Solaris
+ * "/var/db/timezone/zoneinfo/<olsonID>" macOS 10.13
+ * To avoid checking lots of paths, just check that the target path
+ * before the <olsonID> ends with "/zoneinfo/", and the <olsonID> is valid.
+ */
+
#define CHECK_LOCALTIME_LINK 1
#if U_PLATFORM_IS_DARWIN_BASED
#include <tzfile.h>
@@ -665,12 +692,12 @@ extern U_IMPORT char *U_TZNAME[];
#elif U_PLATFORM == U_PF_SOLARIS
#define TZDEFAULT "/etc/localtime"
#define TZZONEINFO "/usr/share/lib/zoneinfo/"
-#define TZZONEINFO2 "../usr/share/lib/zoneinfo/"
#define TZ_ENV_CHECK "localtime"
#else
#define TZDEFAULT "/etc/localtime"
#define TZZONEINFO "/usr/share/zoneinfo/"
#endif
+#define TZZONEINFOTAIL "/zoneinfo/"
#if U_HAVE_DIRENT_H
#define TZFILE_SKIP "posixrules" /* tz file to skip when searching. */
/* Some Linux distributions have 'localtime' in /usr/share/zoneinfo
@@ -922,30 +949,30 @@ static CharString *gSearchTZFileResult = NULL;
* This function is not thread safe - it uses a global, gSearchTZFileResult, to hold its results.
*/
static char* searchForTZFile(const char* path, DefaultTZInfo* tzInfo) {
- DIR* dirp = opendir(path);
- DIR* subDirp = NULL;
+ DIR* dirp = NULL;
struct dirent* dirEntry = NULL;
-
char* result = NULL;
+ UErrorCode status = U_ZERO_ERROR;
+
+ /* Save the current path */
+ CharString curpath(path, -1, status);
+ if (U_FAILURE(status)) {
+ goto cleanupAndReturn;
+ }
+
+ dirp = opendir(path);
if (dirp == NULL) {
- return result;
+ goto cleanupAndReturn;
}
if (gSearchTZFileResult == NULL) {
gSearchTZFileResult = new CharString;
if (gSearchTZFileResult == NULL) {
- return NULL;
+ goto cleanupAndReturn;
}
ucln_common_registerCleanup(UCLN_COMMON_PUTIL, putil_cleanup);
}
- /* Save the current path */
- UErrorCode status = U_ZERO_ERROR;
- CharString curpath(path, -1, status);
- if (U_FAILURE(status)) {
- return NULL;
- }
-
/* Check each entry in the directory. */
while((dirEntry = readdir(dirp)) != NULL) {
const char* dirName = dirEntry->d_name;
@@ -954,15 +981,16 @@ static char* searchForTZFile(const char* path, DefaultTZInfo* tzInfo) {
CharString newpath(curpath, status);
newpath.append(dirName, -1, status);
if (U_FAILURE(status)) {
- return NULL;
+ break;
}
+ DIR* subDirp = NULL;
if ((subDirp = opendir(newpath.data())) != NULL) {
/* If this new path is a directory, make a recursive call with the newpath. */
closedir(subDirp);
newpath.append('/', status);
if (U_FAILURE(status)) {
- return NULL;
+ break;
}
result = searchForTZFile(newpath.data(), tzInfo);
/*
@@ -986,7 +1014,7 @@ static char* searchForTZFile(const char* path, DefaultTZInfo* tzInfo) {
gSearchTZFileResult->clear();
gSearchTZFileResult->append(zoneid, -1, status);
if (U_FAILURE(status)) {
- return NULL;
+ break;
}
result = gSearchTZFileResult->data();
/* Get out after the first one found. */
@@ -995,7 +1023,11 @@ static char* searchForTZFile(const char* path, DefaultTZInfo* tzInfo) {
}
}
}
- closedir(dirp);
+
+ cleanupAndReturn:
+ if (dirp) {
+ closedir(dirp);
+ }
return result;
}
#endif
@@ -1008,16 +1040,66 @@ uprv_tzname_clear_cache()
#endif
}
+// With the Universal Windows Platform we can just ask Windows for the name
+#if U_PLATFORM_HAS_WINUWP_API
+U_CAPI const char* U_EXPORT2
+uprv_getWindowsTimeZone()
+{
+ // Get default Windows timezone.
+ ComPtr<IInspectable> calendar;
+ HRESULT hr = RoActivateInstance(
+ HStringReference(RuntimeClass_Windows_Globalization_Calendar).Get(),
+ &calendar);
+ if (SUCCEEDED(hr))
+ {
+ ComPtr<ABI::Windows::Globalization::ITimeZoneOnCalendar> timezone;
+ hr = calendar.As(&timezone);
+ if (SUCCEEDED(hr))
+ {
+ HString timezoneString;
+ hr = timezone->GetTimeZone(timezoneString.GetAddressOf());
+ if (SUCCEEDED(hr))
+ {
+ int32_t length = static_cast<int32_t>(wcslen(timezoneString.GetRawBuffer(NULL)));
+ char* asciiId = (char*)uprv_calloc(length + 1, sizeof(char));
+ if (asciiId != nullptr)
+ {
+ u_UCharsToChars((UChar*)timezoneString.GetRawBuffer(NULL), asciiId, length);
+ return asciiId;
+ }
+ }
+ }
+ }
+
+ // Failed
+ return nullptr;
+}
+#endif
+
U_CAPI const char* U_EXPORT2
uprv_tzname(int n)
{
+ (void)n; // Avoid unreferenced parameter warning.
const char *tzid = NULL;
#if U_PLATFORM_USES_ONLY_WIN32_API
+#if U_PLATFORM_HAS_WINUWP_API > 0
+ tzid = uprv_getWindowsTimeZone();
+#else
tzid = uprv_detectWindowsTimeZone();
+#endif
if (tzid != NULL) {
return tzid;
}
+
+#ifndef U_TZNAME
+ // The return value is free'd in timezone.cpp on Windows because
+ // the other code path returns a pointer to a heap location.
+ // If we don't have a name already, then tzname wouldn't be any
+ // better, so just fall back.
+ return uprv_strdup("Etc/UTC");
+#endif // !U_TZNAME
+
#else
/*#if U_PLATFORM_IS_DARWIN_BASED
@@ -1059,24 +1141,15 @@ uprv_tzname(int n)
*/
int32_t ret = (int32_t)readlink(TZDEFAULT, gTimeZoneBuffer, sizeof(gTimeZoneBuffer)-1);
if (0 < ret) {
- int32_t tzZoneInfoLen = uprv_strlen(TZZONEINFO);
+ int32_t tzZoneInfoTailLen = uprv_strlen(TZZONEINFOTAIL);
gTimeZoneBuffer[ret] = 0;
- if (uprv_strncmp(gTimeZoneBuffer, TZZONEINFO, tzZoneInfoLen) == 0
- && isValidOlsonID(gTimeZoneBuffer + tzZoneInfoLen))
- {
- return (gTimeZoneBufferPtr = gTimeZoneBuffer + tzZoneInfoLen);
- }
-#if U_PLATFORM == U_PF_SOLARIS
- else
+ char * tzZoneInfoTailPtr = uprv_strstr(gTimeZoneBuffer, TZZONEINFOTAIL);
+
+ if (tzZoneInfoTailPtr != NULL
+ && isValidOlsonID(tzZoneInfoTailPtr + tzZoneInfoTailLen))
{
- tzZoneInfoLen = uprv_strlen(TZZONEINFO2);
- if (uprv_strncmp(gTimeZoneBuffer, TZZONEINFO2, tzZoneInfoLen) == 0
- && isValidOlsonID(gTimeZoneBuffer + tzZoneInfoLen))
- {
- return (gTimeZoneBufferPtr = gTimeZoneBuffer + tzZoneInfoLen);
- }
+ return (gTimeZoneBufferPtr = tzZoneInfoTailPtr + tzZoneInfoTailLen);
}
-#endif
} else {
#if defined(SEARCH_TZFILE)
DefaultTZInfo* tzInfo = (DefaultTZInfo*)uprv_malloc(sizeof(DefaultTZInfo));
@@ -1162,7 +1235,8 @@ UInitOnce gTimeZoneFilesInitOnce = U_INITONCE_INITIALIZER;
static CharString *gTimeZoneFilesDirectory = NULL;
#if U_POSIX_LOCALE || U_PLATFORM_USES_ONLY_WIN32_API
- static char *gCorrectedPOSIXLocale = NULL; /* Heap allocated */
+ static const char *gCorrectedPOSIXLocale = NULL; /* Sometimes heap allocated */
+ static bool gCorrectedPOSIXLocaleHeapAllocated = false;
#endif
static UBool U_CALLCONV putil_cleanup(void)
@@ -1183,9 +1257,10 @@ static UBool U_CALLCONV putil_cleanup(void)
#endif
#if U_POSIX_LOCALE || U_PLATFORM_USES_ONLY_WIN32_API
- if (gCorrectedPOSIXLocale) {
- uprv_free(gCorrectedPOSIXLocale);
+ if (gCorrectedPOSIXLocale && gCorrectedPOSIXLocaleHeapAllocated) {
+ uprv_free(const_cast<char *>(gCorrectedPOSIXLocale));
gCorrectedPOSIXLocale = NULL;
+ gCorrectedPOSIXLocaleHeapAllocated = false;
}
#endif
return TRUE;
@@ -1219,7 +1294,7 @@ u_setDataDirectory(const char *directory) {
#if (U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR)
{
char *p;
- while(p = uprv_strchr(newDataDir, U_FILE_ALT_SEP_CHAR)) {
+ while((p = uprv_strchr(newDataDir, U_FILE_ALT_SEP_CHAR)) != NULL) {
*p = U_FILE_SEP_CHAR;
}
}
@@ -1297,7 +1372,9 @@ static void U_CALLCONV dataDirectoryInitFn() {
*/
# if !defined(ICU_NO_USER_DATA_OVERRIDE) && !UCONFIG_NO_FILE_IO
/* First try to get the environment variable */
- path=getenv("ICU_DATA");
+# if U_PLATFORM_HAS_WINUWP_API == 0 // Windows UWP does not support getenv
+ path=getenv("ICU_DATA");
+# endif
# endif
/* ICU_DATA_DIR may be set as a compile option.
@@ -1326,9 +1403,35 @@ static void U_CALLCONV dataDirectoryInitFn() {
}
#endif
+#if defined(ICU_DATA_DIR_WINDOWS) && U_PLATFORM_HAS_WINUWP_API != 0
+ // Use data from the %windir%\globalization\icu directory
+ // This is only available if ICU is built as a system component
+ char datadir_path_buffer[MAX_PATH];
+ UINT length = GetWindowsDirectoryA(datadir_path_buffer, UPRV_LENGTHOF(datadir_path_buffer));
+ if (length > 0 && length < (UPRV_LENGTHOF(datadir_path_buffer) - sizeof(ICU_DATA_DIR_WINDOWS) - 1))
+ {
+ if (datadir_path_buffer[length - 1] != '\\')
+ {
+ datadir_path_buffer[length++] = '\\';
+ datadir_path_buffer[length] = '\0';
+ }
+
+ if ((length + 1 + sizeof(ICU_DATA_DIR_WINDOWS)) < UPRV_LENGTHOF(datadir_path_buffer))
+ {
+ uprv_strcat(datadir_path_buffer, ICU_DATA_DIR_WINDOWS);
+ path = datadir_path_buffer;
+ }
+ }
+#endif
+
if(path==NULL) {
/* It looks really bad, set it to something. */
+#if U_PLATFORM_HAS_WIN32_API
+ // Windows UWP will require icudtl.dat file in same directory as icuuc.dll
+ path = ".\\";
+#else
path = "";
+#endif
}
u_setDataDirectory(path);
@@ -1349,7 +1452,7 @@ static void setTimeZoneFilesDir(const char *path, UErrorCode &status) {
gTimeZoneFilesDirectory->append(path, status);
#if (U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR)
char *p = gTimeZoneFilesDirectory->data();
- while (p = uprv_strchr(p, U_FILE_ALT_SEP_CHAR)) {
+ while ((p = uprv_strchr(p, U_FILE_ALT_SEP_CHAR)) != NULL) {
*p = U_FILE_SEP_CHAR;
}
#endif
@@ -1366,7 +1469,12 @@ static void U_CALLCONV TimeZoneDataDirInitFn(UErrorCode &status) {
status = U_MEMORY_ALLOCATION_ERROR;
return;
}
+#if U_PLATFORM_HAS_WINUWP_API == 0
const char *dir = getenv("ICU_TIMEZONE_FILES_DIR");
+#else
+ // TODO: UWP does not support alternate timezone data directories at this time
+ const char *dir = "";
+#endif // U_PLATFORM_HAS_WINUWP_API
#if defined(U_TIMEZONE_FILES_DIR)
if (dir == NULL) {
dir = TO_STRING(U_TIMEZONE_FILES_DIR);
@@ -1603,6 +1711,7 @@ The leftmost codepage (.xxx) wins.
if (gCorrectedPOSIXLocale == NULL) {
gCorrectedPOSIXLocale = correctedPOSIXLocale;
+ gCorrectedPOSIXLocaleHeapAllocated = true;
ucln_common_registerCleanup(UCLN_COMMON_PUTIL, putil_cleanup);
correctedPOSIXLocale = NULL;
}
@@ -1618,25 +1727,117 @@ The leftmost codepage (.xxx) wins.
UErrorCode status = U_ZERO_ERROR;
char *correctedPOSIXLocale = 0;
+ // If we have already figured this out just use the cached value
if (gCorrectedPOSIXLocale != NULL) {
return gCorrectedPOSIXLocale;
}
- LCID id = GetThreadLocale();
- correctedPOSIXLocale = static_cast<char *>(uprv_malloc(POSIX_LOCALE_CAPACITY + 1));
- if (correctedPOSIXLocale) {
- int32_t posixLen = uprv_convertToPosix(id, correctedPOSIXLocale, POSIX_LOCALE_CAPACITY, &status);
- if (U_SUCCESS(status)) {
- *(correctedPOSIXLocale + posixLen) = 0;
- gCorrectedPOSIXLocale = correctedPOSIXLocale;
- ucln_common_registerCleanup(UCLN_COMMON_PUTIL, putil_cleanup);
- } else {
- uprv_free(correctedPOSIXLocale);
+ // No cached value, need to determine the current value
+ static WCHAR windowsLocale[LOCALE_NAME_MAX_LENGTH];
+#if U_PLATFORM_HAS_WINUWP_API == 0
+ // If not a Universal Windows App, we'll need user default language.
+ // Vista and above should use Locale Names instead of LCIDs
+ int length = GetUserDefaultLocaleName(windowsLocale, UPRV_LENGTHOF(windowsLocale));
+#else
+ // In a UWP app, we want the top language that the application and user agreed upon
+ ComPtr<ABI::Windows::Foundation::Collections::IVectorView<HSTRING>> languageList;
+
+ ComPtr<ABI::Windows::Globalization::IApplicationLanguagesStatics> applicationLanguagesStatics;
+ HRESULT hr = GetActivationFactory(
+ HStringReference(RuntimeClass_Windows_Globalization_ApplicationLanguages).Get(),
+ &applicationLanguagesStatics);
+ if (SUCCEEDED(hr))
+ {
+ hr = applicationLanguagesStatics->get_Languages(&languageList);
+ }
+
+ if (FAILED(hr))
+ {
+ // If there is no application context, then use the top language from the user language profile
+ ComPtr<ABI::Windows::System::UserProfile::IGlobalizationPreferencesStatics> globalizationPreferencesStatics;
+ hr = GetActivationFactory(
+ HStringReference(RuntimeClass_Windows_System_UserProfile_GlobalizationPreferences).Get(),
+ &globalizationPreferencesStatics);
+ if (SUCCEEDED(hr))
+ {
+ hr = globalizationPreferencesStatics->get_Languages(&languageList);
}
}
+ // We have a list of languages, ICU knows one, so use the top one for our locale
+ HString topLanguage;
+ if (SUCCEEDED(hr))
+ {
+ hr = languageList->GetAt(0, topLanguage.GetAddressOf());
+ }
+
+ if (FAILED(hr))
+ {
+ // Unexpected, use en-US by default
+ if (gCorrectedPOSIXLocale == NULL) {
+ gCorrectedPOSIXLocale = "en_US";
+ }
+
+ return gCorrectedPOSIXLocale;
+ }
+
+ // ResolveLocaleName will get a likely subtags form consistent with Windows behavior.
+ int length = ResolveLocaleName(topLanguage.GetRawBuffer(NULL), windowsLocale, UPRV_LENGTHOF(windowsLocale));
+#endif
+ // Now we should have a Windows locale name that needs converted to the POSIX style,
+ if (length > 0)
+ {
+ // First we need to go from UTF-16 to char (and also convert from _ to - while we're at it.)
+ char modifiedWindowsLocale[LOCALE_NAME_MAX_LENGTH];
+
+ int32_t i;
+ for (i = 0; i < UPRV_LENGTHOF(modifiedWindowsLocale); i++)
+ {
+ if (windowsLocale[i] == '_')
+ {
+ modifiedWindowsLocale[i] = '-';
+ }
+ else
+ {
+ modifiedWindowsLocale[i] = static_cast<char>(windowsLocale[i]);
+ }
+
+ if (modifiedWindowsLocale[i] == '\0')
+ {
+ break;
+ }
+ }
+
+ if (i >= UPRV_LENGTHOF(modifiedWindowsLocale))
+ {
+ // Ran out of room, can't really happen, maybe we'll be lucky about a matching
+ // locale when tags are dropped
+ modifiedWindowsLocale[UPRV_LENGTHOF(modifiedWindowsLocale) - 1] = '\0';
+ }
+
+ // Now normalize the resulting name
+ correctedPOSIXLocale = static_cast<char *>(uprv_malloc(POSIX_LOCALE_CAPACITY + 1));
+ /* TODO: Should we just exit on memory allocation failure? */
+ if (correctedPOSIXLocale)
+ {
+ int32_t posixLen = uloc_canonicalize(modifiedWindowsLocale, correctedPOSIXLocale, POSIX_LOCALE_CAPACITY, &status);
+ if (U_SUCCESS(status))
+ {
+ *(correctedPOSIXLocale + posixLen) = 0;
+ gCorrectedPOSIXLocale = correctedPOSIXLocale;
+ gCorrectedPOSIXLocaleHeapAllocated = true;
+ ucln_common_registerCleanup(UCLN_COMMON_PUTIL, putil_cleanup);
+ }
+ else
+ {
+ uprv_free(correctedPOSIXLocale);
+ }
+ }
+ }
+
+ // If unable to find a locale we can agree upon, use en-US by default
if (gCorrectedPOSIXLocale == NULL) {
- return "en_US";
+ gCorrectedPOSIXLocale = "en_US";
}
return gCorrectedPOSIXLocale;
@@ -1923,8 +2124,34 @@ int_getDefaultCodepage()
#elif U_PLATFORM_USES_ONLY_WIN32_API
static char codepage[64];
- sprintf(codepage, "windows-%d", GetACP());
- return codepage;
+ DWORD codepageNumber = 0;
+
+#if U_PLATFORM_HAS_WINUWP_API > 0
+ // UWP doesn't have a direct API to get the default ACP as Microsoft would rather
+ // have folks use Unicode than a "system" code page, however this is the same
+ // codepage as the system default locale codepage. (FWIW, the system locale is
+ // ONLY used for codepage, it should never be used for anything else)
+ GetLocaleInfoEx(LOCALE_NAME_SYSTEM_DEFAULT, LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER,
+ (LPWSTR)&codepageNumber, sizeof(codepageNumber) / sizeof(WCHAR));
+#else
+ // Win32 apps can call GetACP
+ codepageNumber = GetACP();
+#endif
+ // Special case for UTF-8
+ if (codepageNumber == 65001)
+ {
+ return "UTF-8";
+ }
+ // Windows codepages can look like windows-1252, so format the found number
+ // the numbers are eclectic, however all valid system code pages, besides UTF-8
+ // are between 3 and 19999
+ if (codepageNumber > 0 && codepageNumber < 20000)
+ {
+ sprintf(codepage, "windows-%ld", codepageNumber);
+ return codepage;
+ }
+ // If the codepage number call failed then return UTF-8
+ return "UTF-8";
#elif U_POSIX_LOCALE
static char codesetName[100];
@@ -2108,19 +2335,16 @@ u_getVersion(UVersionInfo versionArray) {
* icucfg.h dependent code
*/
-#if U_ENABLE_DYLOAD
-
-#if HAVE_DLOPEN && !U_PLATFORM_USES_ONLY_WIN32_API
+#if U_ENABLE_DYLOAD && HAVE_DLOPEN && !U_PLATFORM_USES_ONLY_WIN32_API
#if HAVE_DLFCN_H
-
#ifdef __MVS__
#ifndef __SUSV3
#define __SUSV3 1
#endif
#endif
#include <dlfcn.h>
-#endif
+#endif /* HAVE_DLFCN_H */
U_INTERNAL void * U_EXPORT2
uprv_dl_open(const char *libName, UErrorCode *status) {
@@ -2160,38 +2384,10 @@ uprv_dlsym_func(void *lib, const char* sym, UErrorCode *status) {
return uret.fp;
}
-#else
-
-/* null (nonexistent) implementation. */
-
-U_INTERNAL void * U_EXPORT2
-uprv_dl_open(const char *libName, UErrorCode *status) {
- if(U_FAILURE(*status)) return NULL;
- *status = U_UNSUPPORTED_ERROR;
- return NULL;
-}
-
-U_INTERNAL void U_EXPORT2
-uprv_dl_close(void *lib, UErrorCode *status) {
- if(U_FAILURE(*status)) return;
- *status = U_UNSUPPORTED_ERROR;
- return;
-}
-
-
-U_INTERNAL UVoidFunction* U_EXPORT2
-uprv_dlsym_func(void *lib, const char* sym, UErrorCode *status) {
- if(U_SUCCESS(*status)) {
- *status = U_UNSUPPORTED_ERROR;
- }
- return (UVoidFunction*)NULL;
-}
-
-
+#elif U_ENABLE_DYLOAD && U_PLATFORM_USES_ONLY_WIN32_API && !U_PLATFORM_HAS_WINUWP_API
-#endif
-
-#elif U_PLATFORM_USES_ONLY_WIN32_API
+/* Windows API implementation. */
+// Note: UWP does not expose/allow these APIs, so the UWP version gets the null implementation. */
U_INTERNAL void * U_EXPORT2
uprv_dl_open(const char *libName, UErrorCode *status) {
@@ -2218,7 +2414,6 @@ uprv_dl_close(void *lib, UErrorCode *status) {
return;
}
-
U_INTERNAL UVoidFunction* U_EXPORT2
uprv_dlsym_func(void *lib, const char* sym, UErrorCode *status) {
HMODULE handle = (HMODULE)lib;
@@ -2240,10 +2435,9 @@ uprv_dlsym_func(void *lib, const char* sym, UErrorCode *status) {
return addr;
}
-
#else
-/* No dynamic loading set. */
+/* No dynamic loading, null (nonexistent) implementation. */
U_INTERNAL void * U_EXPORT2
uprv_dl_open(const char *libName, UErrorCode *status) {
@@ -2261,7 +2455,6 @@ uprv_dl_close(void *lib, UErrorCode *status) {
return;
}
-
U_INTERNAL UVoidFunction* U_EXPORT2
uprv_dlsym_func(void *lib, const char* sym, UErrorCode *status) {
(void)lib;
@@ -2272,7 +2465,7 @@ uprv_dlsym_func(void *lib, const char* sym, UErrorCode *status) {
return (UVoidFunction*)NULL;
}
-#endif /* U_ENABLE_DYLOAD */
+#endif
/*
* Hey, Emacs, please set the following: