1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru******************************************************************************
3b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*
4fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius*   Copyright (C) 1997-2014, International Business Machines
5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   Corporation and others.  All Rights Reserved.
6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*
7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru******************************************************************************
8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*
9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*  FILE NAME : putil.c (previously putil.cpp and ptypes.cpp)
10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*
11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   Date        Name        Description
12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   04/14/97    aliu        Creation.
13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   04/24/97    aliu        Added getDefaultDataDirectory() and
14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*                            getDefaultLocaleID().
15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   04/28/97    aliu        Rewritten to assume Unix and apply general methods
16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*                            for assumed case.  Non-UNIX platforms must be
17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*                            special-cased.  Rewrote numeric methods dealing
18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*                            with NaN and Infinity to be platform independent
19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*                             over all IEEE 754 platforms.
20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   05/13/97    aliu        Restored sign of timezone
21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*                            (semantics are hours West of GMT)
22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   06/16/98    erm         Added IEEE_754 stuff, cleaned up isInfinite, isNan,
23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*                             nextDouble..
24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   07/22/98    stephen     Added remainder, max, min, trunc
25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   08/13/98    stephen     Added isNegativeInfinity, isPositiveInfinity
26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   08/24/98    stephen     Added longBitsFromDouble
27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   09/08/98    stephen     Minor changes for Mac Port
28b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   03/02/99    stephen     Removed openFile().  Added AS400 support.
29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*                            Fixed EBCDIC tables
30b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   04/15/99    stephen     Converted to C.
31b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   06/28/99    stephen     Removed mutex locking in u_isBigEndian().
32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   08/04/99    jeffrey R.  Added OS/2 changes
33b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   11/15/99    helena      Integrated S/390 IEEE support.
34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   04/26/01    Barry N.    OS/400 support for uprv_getDefaultLocaleID
35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   08/15/01    Steven H.   OS/400 support for uprv_getDefaultCodepage
3685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho*   01/03/08    Steven L.   Fake Time Support
37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru******************************************************************************
38b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/
39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
40103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// Defines _XOPEN_SOURCE for access to POSIX functions.
41103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// Must be before any other #includes.
42103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "uposixdefs.h"
43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
44b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* include ICU headers */
45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/utypes.h"
46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/putil.h"
47b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/ustring.h"
48b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "putilimp.h"
49b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uassert.h"
50b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "umutex.h"
51b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cmemory.h"
52b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cstring.h"
53b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "locmap.h"
54b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ucln_cmn.h"
55b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
56b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Include standard headers. */
57b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <stdio.h>
58b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <stdlib.h>
59b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <string.h>
60b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <math.h>
61b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <locale.h>
62b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <float.h>
63b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
64103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#ifndef U_COMMON_IMPLEMENTATION
65103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#error U_COMMON_IMPLEMENTATION not set - must be set for all ICU source files in common/ - see http://userguide.icu-project.org/howtouseicu
66103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
67103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
68103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
69b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* include system headers */
70103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_PLATFORM_USES_ONLY_WIN32_API
71103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    /*
72103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius     * TODO: U_PLATFORM_USES_ONLY_WIN32_API includes MinGW.
73103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius     * Should Cygwin be included as well (U_PLATFORM_HAS_WIN32_API)
74103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius     * to use native APIs as much as possible?
75103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius     */
76b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#   define WIN32_LEAN_AND_MEAN
77b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#   define VC_EXTRALEAN
78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#   define NOUSER
79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#   define NOSERVICE
80b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#   define NOIME
81b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#   define NOMCX
82b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#   include <windows.h>
83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#   include "wintz.h"
84103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#elif U_PLATFORM == U_PF_OS400
85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#   include <float.h>
86b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#   include <qusec.h>       /* error code structure */
87b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#   include <qusrjobi.h>
88b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#   include <qliept.h>      /* EPT_CALL macro  - this include must be after all other "QSYSINCs" */
89b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#   include <mih/testptr.h> /* For uprv_maximumPtr */
90103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#elif U_PLATFORM == U_PF_CLASSIC_MACOS
91b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#   include <Files.h>
92b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#   include <IntlResources.h>
93b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#   include <Script.h>
94b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#   include <Folders.h>
95b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#   include <MacTypes.h>
96b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#   include <TextUtils.h>
97b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#   define ICU_NO_USER_DATA_OVERRIDE 1
98103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#elif U_PLATFORM == U_PF_OS390
99b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#   include "unicode/ucnv.h"   /* Needed for UCNV_SWAP_LFNL_OPTION_STRING */
1008393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#elif U_PLATFORM_IS_DARWIN_BASED || U_PLATFORM_IS_LINUX_BASED || U_PLATFORM == U_PF_BSD || U_PLATFORM == U_PF_SOLARIS
101b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#   include <limits.h>
102b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#   include <unistd.h>
1038393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#   if U_PLATFORM == U_PF_SOLARIS
1048393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#       ifndef _XPG4_2
1058393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#           define _XPG4_2
1068393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#       endif
1078393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#   endif
108103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#elif U_PLATFORM == U_PF_QNX
109b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#   include <sys/neutrino.h>
11050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif
11150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
112103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if (U_PF_MINGW <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN) && defined(__STRICT_ANSI__)
113b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/* tzset isn't defined in strict ANSI on Cygwin and MinGW. */
114b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#undef __STRICT_ANSI__
115b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#endif
116b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
117b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/*
118b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * Cygwin with GCC requires inclusion of time.h after the above disabling strict asci mode statement.
119b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */
120b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include <time.h>
12150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
122103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if !U_PLATFORM_USES_ONLY_WIN32_API
12385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include <sys/time.h>
124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Only include langinfo.h if we have a way to get the codeset. If we later
128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * depend on more feature, we can test on U_HAVE_NL_LANGINFO.
129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *
130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if U_HAVE_NL_LANGINFO_CODESET
133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <langinfo.h>
134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
13650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/**
13750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Simple things (presence of functions, etc) should just go in configure.in and be added to
13850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * icucfg.h via autoheader.
13950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */
140103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_PLATFORM_IMPLEMENTS_POSIX
141103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#   if U_PLATFORM == U_PF_OS400
142103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#    define HAVE_DLFCN_H 0
143103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#    define HAVE_DLOPEN 0
144103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#   else
145103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#   ifndef HAVE_DLFCN_H
146103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#    define HAVE_DLFCN_H 1
147103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#   endif
148103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#   ifndef HAVE_DLOPEN
149103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#    define HAVE_DLOPEN 1
150103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#   endif
151103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#   endif
152103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#   ifndef HAVE_GETTIMEOFDAY
153103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#    define HAVE_GETTIMEOFDAY 1
154103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#   endif
155103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#else
156103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#   define HAVE_DLFCN_H 0
157103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#   define HAVE_DLOPEN 0
158103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#   define HAVE_GETTIMEOFDAY 0
15950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif
16050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
161103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
162103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Define the extension for data files, again... */
164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define DATA_TYPE "dat"
165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Leave this copyright notice here! */
167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char copyright[] = U_COPYRIGHT_STRING;
168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* floating point implementations ------------------------------------------- */
170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* We return QNAN rather than SNAN*/
172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define SIGN 0x80000000U
173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Make it easy to define certain types of constants */
175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querutypedef union {
176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int64_t i64; /* This must be defined first in order to allow the initialization to work. This is a C89 feature. */
177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    double d64;
178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} BitPatternConversion;
179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const BitPatternConversion gNan = { (int64_t) INT64_C(0x7FF8000000000000) };
180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const BitPatternConversion gInf = { (int64_t) INT64_C(0x7FF0000000000000) };
181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*---------------------------------------------------------------------------
183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  Platform utilities
184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  Our general strategy is to assume we're on a POSIX platform.  Platforms which
185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  are non-POSIX must declare themselves so.  The default POSIX implementation
186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  will sometimes work for non-POSIX platforms as well (e.g., the NaN-related
187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  functions).
188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  ---------------------------------------------------------------------------*/
189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
190103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_PLATFORM_USES_ONLY_WIN32_API || U_PLATFORM == U_PF_CLASSIC_MACOS || U_PLATFORM == U_PF_OS400
191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#   undef U_POSIX_LOCALE
192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else
193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#   define U_POSIX_LOCALE    1
194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    WARNING! u_topNBytesOfDouble and u_bottomNBytesOfDouble
198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    can't be properly optimized by the gcc compiler sometimes (i.e. gcc 3.2).
199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/
200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !IEEE_754
201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic char*
202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruu_topNBytesOfDouble(double* d, int n)
203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if U_IS_BIG_ENDIAN
205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return (char*)d;
206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else
207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return (char*)(d + 1) - n;
208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic char*
212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruu_bottomNBytesOfDouble(double* d, int n)
213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if U_IS_BIG_ENDIAN
215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return (char*)(d + 1) - n;
216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else
217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return (char*)d;
218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
22027f654740f2a26ad62a5c155af9199af9e69b889claireho#endif   /* !IEEE_754 */
22127f654740f2a26ad62a5c155af9199af9e69b889claireho
22227f654740f2a26ad62a5c155af9199af9e69b889claireho#if IEEE_754
22327f654740f2a26ad62a5c155af9199af9e69b889clairehostatic UBool
22427f654740f2a26ad62a5c155af9199af9e69b889clairehou_signBit(double d) {
22527f654740f2a26ad62a5c155af9199af9e69b889claireho    uint8_t hiByte;
22627f654740f2a26ad62a5c155af9199af9e69b889claireho#if U_IS_BIG_ENDIAN
22727f654740f2a26ad62a5c155af9199af9e69b889claireho    hiByte = *(uint8_t *)&d;
22827f654740f2a26ad62a5c155af9199af9e69b889claireho#else
22927f654740f2a26ad62a5c155af9199af9e69b889claireho    hiByte = *(((uint8_t *)&d) + sizeof(double) - 1);
23027f654740f2a26ad62a5c155af9199af9e69b889claireho#endif
23127f654740f2a26ad62a5c155af9199af9e69b889claireho    return (hiByte & 0x80) != 0;
23227f654740f2a26ad62a5c155af9199af9e69b889claireho}
23327f654740f2a26ad62a5c155af9199af9e69b889claireho#endif
23427f654740f2a26ad62a5c155af9199af9e69b889claireho
23527f654740f2a26ad62a5c155af9199af9e69b889claireho
236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
23785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#if defined (U_DEBUG_FAKETIME)
23885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho/* Override the clock to test things without having to move the system clock.
23985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * Assumes POSIX gettimeofday() will function
24085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho */
24185bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoUDate fakeClock_t0 = 0; /** Time to start the clock from **/
24285bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoUDate fakeClock_dt = 0; /** Offset (fake time - real time) **/
24385bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoUBool fakeClock_set = FALSE; /** True if fake clock has spun up **/
24454dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic UMutex fakeClockMutex = U_MUTEX_INTIALIZER;
24585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
24685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic UDate getUTCtime_real() {
24785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    struct timeval posixTime;
24885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    gettimeofday(&posixTime, NULL);
24985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return (UDate)(((int64_t)posixTime.tv_sec * U_MILLIS_PER_SECOND) + (posixTime.tv_usec/1000));
25085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
25185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
25285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic UDate getUTCtime_fake() {
25385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    umtx_lock(&fakeClockMutex);
25485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(!fakeClock_set) {
25585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        UDate real = getUTCtime_real();
25685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        const char *fake_start = getenv("U_FAKETIME_START");
25727f654740f2a26ad62a5c155af9199af9e69b889claireho        if((fake_start!=NULL) && (fake_start[0]!=0)) {
25885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            sscanf(fake_start,"%lf",&fakeClock_t0);
25927f654740f2a26ad62a5c155af9199af9e69b889claireho            fakeClock_dt = fakeClock_t0 - real;
26027f654740f2a26ad62a5c155af9199af9e69b889claireho            fprintf(stderr,"U_DEBUG_FAKETIME was set at compile time, so the ICU clock will start at a preset value\n"
26127f654740f2a26ad62a5c155af9199af9e69b889claireho                    "env variable U_FAKETIME_START=%.0f (%s) for an offset of %.0f ms from the current time %.0f\n",
26227f654740f2a26ad62a5c155af9199af9e69b889claireho                    fakeClock_t0, fake_start, fakeClock_dt, real);
26327f654740f2a26ad62a5c155af9199af9e69b889claireho        } else {
26427f654740f2a26ad62a5c155af9199af9e69b889claireho          fakeClock_dt = 0;
26527f654740f2a26ad62a5c155af9199af9e69b889claireho            fprintf(stderr,"U_DEBUG_FAKETIME was set at compile time, but U_FAKETIME_START was not set.\n"
26627f654740f2a26ad62a5c155af9199af9e69b889claireho                    "Set U_FAKETIME_START to the number of milliseconds since 1/1/1970 to set the ICU clock.\n");
26785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
26885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        fakeClock_set = TRUE;
26985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
27085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    umtx_unlock(&fakeClockMutex);
27185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
27285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return getUTCtime_real() + fakeClock_dt;
27385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
27485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif
27585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
276103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_PLATFORM_USES_ONLY_WIN32_API
277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querutypedef union {
278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int64_t int64;
279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    FILETIME fileTime;
280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} FileTimeConversion;   /* This is like a ULARGE_INTEGER */
281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Number of 100 nanoseconds from 1/1/1601 to 1/1/1970 */
283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define EPOCH_BIAS  INT64_C(116444736000000000)
284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define HECTONANOSECOND_PER_MILLISECOND   10000
285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*---------------------------------------------------------------------------
289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  Universal Implementations
290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  These are designed to work on all platforms.  Try these, and if they
291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  don't work on your platform, then special case your platform with new
292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  implementations.
293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru---------------------------------------------------------------------------*/
294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI UDate U_EXPORT2
296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuprv_getUTCtime()
297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
29885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#if defined(U_DEBUG_FAKETIME)
29985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return getUTCtime_fake(); /* Hook for overriding the clock */
30027f654740f2a26ad62a5c155af9199af9e69b889claireho#else
30127f654740f2a26ad62a5c155af9199af9e69b889claireho    return uprv_getRawUTCtime();
30227f654740f2a26ad62a5c155af9199af9e69b889claireho#endif
30327f654740f2a26ad62a5c155af9199af9e69b889claireho}
30427f654740f2a26ad62a5c155af9199af9e69b889claireho
30527f654740f2a26ad62a5c155af9199af9e69b889claireho/* Return UTC (GMT) time measured in milliseconds since 0:00 on 1/1/70.*/
30627f654740f2a26ad62a5c155af9199af9e69b889clairehoU_CAPI UDate U_EXPORT2
30727f654740f2a26ad62a5c155af9199af9e69b889clairehouprv_getRawUTCtime()
30827f654740f2a26ad62a5c155af9199af9e69b889claireho{
309103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_PLATFORM == U_PF_CLASSIC_MACOS
310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    time_t t, t1, t2;
311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    struct tm tmrec;
312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uprv_memset( &tmrec, 0, sizeof(tmrec) );
314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    tmrec.tm_year = 70;
315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    tmrec.tm_mon = 0;
316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    tmrec.tm_mday = 1;
317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    t1 = mktime(&tmrec);    /* seconds of 1/1/1970*/
318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    time(&t);
320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uprv_memcpy( &tmrec, gmtime(&t), sizeof(tmrec) );
321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    t2 = mktime(&tmrec);    /* seconds of current GMT*/
322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return (UDate)(t2 - t1) * U_MILLIS_PER_SECOND;         /* GMT (or UTC) in seconds since 1970*/
323103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#elif U_PLATFORM_USES_ONLY_WIN32_API
324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    FileTimeConversion winTime;
326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    GetSystemTimeAsFileTime(&winTime.fileTime);
327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return (UDate)((winTime.int64 - EPOCH_BIAS) / HECTONANOSECOND_PER_MILLISECOND);
328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else
32950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
330103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if HAVE_GETTIMEOFDAY
331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    struct timeval posixTime;
332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    gettimeofday(&posixTime, NULL);
333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return (UDate)(((int64_t)posixTime.tv_sec * U_MILLIS_PER_SECOND) + (posixTime.tv_usec/1000));
33450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#else
335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    time_t epochtime;
336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    time(&epochtime);
337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return (UDate)epochtime * U_MILLIS_PER_SECOND;
338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
33950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
34050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif
341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*-----------------------------------------------------------------------------
344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  IEEE 754
345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  These methods detect and return NaN and infinity values for doubles
346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  conforming to IEEE 754.  Platforms which support this standard include X86,
347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  Mac 680x0, Mac PowerPC, AIX RS/6000, and most others.
348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  If this doesn't work on your platform, you have non-IEEE floating-point, and
349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  will need to code your own versions.  A naive implementation is to return 0.0
350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  for getNaN and getInfinity, and false for isNaN and isInfinite.
351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  ---------------------------------------------------------------------------*/
352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI UBool U_EXPORT2
354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuprv_isNaN(double number)
355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if IEEE_754
357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    BitPatternConversion convertedNumber;
358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    convertedNumber.d64 = number;
359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Infinity is 0x7FF0000000000000U. Anything greater than that is a NaN */
360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return (UBool)((convertedNumber.i64 & U_INT64_MAX) > gInf.i64);
361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
362103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#elif U_PLATFORM == U_PF_OS390
363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uint32_t highBits = *(uint32_t*)u_topNBytesOfDouble(&number,
364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        sizeof(uint32_t));
365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uint32_t lowBits  = *(uint32_t*)u_bottomNBytesOfDouble(&number,
366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        sizeof(uint32_t));
367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return ((highBits & 0x7F080000L) == 0x7F080000L) &&
369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      (lowBits == 0x00000000L);
370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else
372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* If your platform doesn't support IEEE 754 but *does* have an NaN value,*/
373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* you'll need to replace this default implementation with what's correct*/
374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* for your platform.*/
375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return number != number;
376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI UBool U_EXPORT2
380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuprv_isInfinite(double number)
381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if IEEE_754
383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    BitPatternConversion convertedNumber;
384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    convertedNumber.d64 = number;
385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Infinity is exactly 0x7FF0000000000000U. */
386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return (UBool)((convertedNumber.i64 & U_INT64_MAX) == gInf.i64);
387103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#elif U_PLATFORM == U_PF_OS390
388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uint32_t highBits = *(uint32_t*)u_topNBytesOfDouble(&number,
389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        sizeof(uint32_t));
390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uint32_t lowBits  = *(uint32_t*)u_bottomNBytesOfDouble(&number,
391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        sizeof(uint32_t));
392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return ((highBits  & ~SIGN) == 0x70FF0000L) && (lowBits == 0x00000000L);
394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else
396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* If your platform doesn't support IEEE 754 but *does* have an infinity*/
397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* value, you'll need to replace this default implementation with what's*/
398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* correct for your platform.*/
399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return number == (2.0 * number);
400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI UBool U_EXPORT2
404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuprv_isPositiveInfinity(double number)
405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
406103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if IEEE_754 || U_PLATFORM == U_PF_OS390
407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return (UBool)(number > 0 && uprv_isInfinite(number));
408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else
409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return uprv_isInfinite(number);
410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI UBool U_EXPORT2
414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuprv_isNegativeInfinity(double number)
415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
416103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if IEEE_754 || U_PLATFORM == U_PF_OS390
417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return (UBool)(number < 0 && uprv_isInfinite(number));
418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else
420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uint32_t highBits = *(uint32_t*)u_topNBytesOfDouble(&number,
421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        sizeof(uint32_t));
422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return((highBits & SIGN) && uprv_isInfinite(number));
423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI double U_EXPORT2
428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuprv_getNaN()
429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
430103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if IEEE_754 || U_PLATFORM == U_PF_OS390
431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return gNan.d64;
432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else
433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* If your platform doesn't support IEEE 754 but *does* have an NaN value,*/
434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* you'll need to replace this default implementation with what's correct*/
435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* for your platform.*/
436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return 0.0;
437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI double U_EXPORT2
441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuprv_getInfinity()
442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
443103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if IEEE_754 || U_PLATFORM == U_PF_OS390
444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return gInf.d64;
445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else
446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* If your platform doesn't support IEEE 754 but *does* have an infinity*/
447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* value, you'll need to replace this default implementation with what's*/
448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* correct for your platform.*/
449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return 0.0;
450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI double U_EXPORT2
454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuprv_floor(double x)
455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return floor(x);
457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI double U_EXPORT2
460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuprv_ceil(double x)
461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return ceil(x);
463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI double U_EXPORT2
466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuprv_round(double x)
467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return uprv_floor(x + 0.5);
469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI double U_EXPORT2
472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuprv_fabs(double x)
473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return fabs(x);
475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI double U_EXPORT2
478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuprv_modf(double x, double* y)
479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return modf(x, y);
481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI double U_EXPORT2
484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuprv_fmod(double x, double y)
485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return fmod(x, y);
487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI double U_EXPORT2
490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuprv_pow(double x, double y)
491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* This is declared as "double pow(double x, double y)" */
493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return pow(x, y);
494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI double U_EXPORT2
497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuprv_pow10(int32_t x)
498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return pow(10.0, (double)x);
500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI double U_EXPORT2
503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuprv_fmax(double x, double y)
504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if IEEE_754
506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* first handle NaN*/
507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(uprv_isNaN(x) || uprv_isNaN(y))
508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return uprv_getNaN();
509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* check for -0 and 0*/
51127f654740f2a26ad62a5c155af9199af9e69b889claireho    if(x == 0.0 && y == 0.0 && u_signBit(x))
512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return y;
513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
51627f654740f2a26ad62a5c155af9199af9e69b889claireho    /* this should work for all flt point w/o NaN and Inf special cases */
517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return (x > y ? x : y);
518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI double U_EXPORT2
521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuprv_fmin(double x, double y)
522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if IEEE_754
524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* first handle NaN*/
525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(uprv_isNaN(x) || uprv_isNaN(y))
526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return uprv_getNaN();
527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* check for -0 and 0*/
52927f654740f2a26ad62a5c155af9199af9e69b889claireho    if(x == 0.0 && y == 0.0 && u_signBit(y))
530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return y;
531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* this should work for all flt point w/o NaN and Inf special cases */
535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return (x > y ? y : x);
536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Truncates the given double.
540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * trunc(3.3) = 3.0, trunc (-3.3) = -3.0
541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This is different than calling floor() or ceil():
542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * floor(3.3) = 3, floor(-3.3) = -4
543b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * ceil(3.3) = 4, ceil(-3.3) = -3
544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI double U_EXPORT2
546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuprv_trunc(double d)
547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if IEEE_754
549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* handle error cases*/
550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(uprv_isNaN(d))
551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return uprv_getNaN();
552b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(uprv_isInfinite(d))
553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return uprv_getInfinity();
554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
55527f654740f2a26ad62a5c155af9199af9e69b889claireho    if(u_signBit(d))    /* Signbit() picks up -0.0;  d<0 does not. */
556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return ceil(d);
557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    else
558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return floor(d);
559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else
561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return d >= 0 ? floor(d) : ceil(d);
562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Return the largest positive number that can be represented by an integer
568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * type of arbitrary bit length.
569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI double U_EXPORT2
571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuprv_maxMantissa(void)
572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return pow(2.0, DBL_MANT_DIG + 1.0) - 1.0;
574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI double U_EXPORT2
577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuprv_log(double d)
578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return log(d);
580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI void * U_EXPORT2
583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuprv_maximumPtr(void * base)
584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
585103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_PLATFORM == U_PF_OS400
586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /*
58785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho     * With the provided function we should never be out of range of a given segment
588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * (a traditional/typical segment that is).  Our segments have 5 bytes for the
589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * id and 3 bytes for the offset.  The key is that the casting takes care of
590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * only retrieving the offset portion minus x1000.  Hence, the smallest offset
591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * seen in a program is x001000 and when casted to an int would be 0.
592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * That's why we can only add 0xffefff.  Otherwise, we would exceed the segment.
593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     *
59485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho     * Currently, 16MB is the current addressing limitation on i5/OS if the activation is
595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * non-TERASPACE.  If it is TERASPACE it is 2GB - 4k(header information).
59685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho     * This function determines the activation based on the pointer that is passed in and
59785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho     * calculates the appropriate maximum available size for
598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * each pointer type (TERASPACE and non-TERASPACE)
599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     *
600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * Unlike other operating systems, the pointer model isn't determined at
601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * compile time on i5/OS.
602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     */
603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if ((base != NULL) && (_TESTPTR(base, _C_TERASPACE_CHECK))) {
604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* if it is a TERASPACE pointer the max is 2GB - 4k */
605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return ((void *)(((char *)base)-((uint32_t)(base))+((uint32_t)0x7fffefff)));
606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* otherwise 16MB since NULL ptr is not checkable or the ptr is not TERASPACE */
608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return ((void *)(((char *)base)-((uint32_t)(base))+((uint32_t)0xffefff)));
609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else
61185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return U_MAX_PTR(base);
612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*---------------------------------------------------------------------------
616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  Platform-specific Implementations
617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  Try these, and if they don't work on your platform, then special case your
618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  platform with new implementations.
619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  ---------------------------------------------------------------------------*/
620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Generic time zone layer -------------------------------------------------- */
622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Time zone utilities */
624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI void U_EXPORT2
625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuprv_tzset()
626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
627b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#if defined(U_TZSET)
628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    U_TZSET();
629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else
630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* no initialization*/
631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2
635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuprv_timezone()
636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef U_TIMEZONE
638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return U_TIMEZONE;
639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else
640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    time_t t, t1, t2;
641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    struct tm tmrec;
642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t tdiff = 0;
643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    time(&t);
645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uprv_memcpy( &tmrec, localtime(&t), sizeof(tmrec) );
64659d709d503bab6e2b61931737e662dd293b40578ccornelius#if U_PLATFORM != U_PF_IPHONE
64759d709d503bab6e2b61931737e662dd293b40578ccornelius    UBool dst_checked = (tmrec.tm_isdst != 0); /* daylight savings time is checked*/
64859d709d503bab6e2b61931737e662dd293b40578ccornelius#endif
649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    t1 = mktime(&tmrec);                 /* local time in seconds*/
650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uprv_memcpy( &tmrec, gmtime(&t), sizeof(tmrec) );
651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    t2 = mktime(&tmrec);                 /* GMT (or UTC) in seconds*/
652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    tdiff = t2 - t1;
65359d709d503bab6e2b61931737e662dd293b40578ccornelius
65459d709d503bab6e2b61931737e662dd293b40578ccornelius#if U_PLATFORM != U_PF_IPHONE
655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* imitate NT behaviour, which returns same timezone offset to GMT for
65654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius       winter and summer.
65754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius       This does not work on all platforms. For instance, on glibc on Linux
65854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius       and on Mac OS 10.5, tdiff calculated above remains the same
65959d709d503bab6e2b61931737e662dd293b40578ccornelius       regardless of whether DST is in effect or not. iOS is another
66059d709d503bab6e2b61931737e662dd293b40578ccornelius       platform where this does not work. Linux + glibc and Mac OS 10.5
66159d709d503bab6e2b61931737e662dd293b40578ccornelius       have U_TIMEZONE defined so that this code is not reached.
66259d709d503bab6e2b61931737e662dd293b40578ccornelius    */
663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (dst_checked)
664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        tdiff += 3600;
66559d709d503bab6e2b61931737e662dd293b40578ccornelius#endif
666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return tdiff;
667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Note that U_TZNAME does *not* have to be tzname, but if it is,
67185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho   some platforms need to have it declared here. */
672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
673103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#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))
674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* RS6000 and others reject char **tzname.  */
675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruextern U_IMPORT char *U_TZNAME[];
676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
67859d709d503bab6e2b61931737e662dd293b40578ccornelius#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)
679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* These platforms are likely to use Olson timezone IDs. */
680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define CHECK_LOCALTIME_LINK 1
681103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_PLATFORM_IS_DARWIN_BASED
682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <tzfile.h>
683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define TZZONEINFO      (TZDIR "/")
6848393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#elif U_PLATFORM == U_PF_SOLARIS
6858393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#define TZDEFAULT       "/etc/localtime"
6868393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#define TZZONEINFO      "/usr/share/lib/zoneinfo/"
68759d709d503bab6e2b61931737e662dd293b40578ccornelius#define TZZONEINFO2     "../usr/share/lib/zoneinfo/"
6888393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#define TZ_ENV_CHECK    "localtime"
68985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#else
69085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#define TZDEFAULT       "/etc/localtime"
69185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#define TZZONEINFO      "/usr/share/zoneinfo/"
69285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif
69385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#if U_HAVE_DIRENT_H
69450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define TZFILE_SKIP     "posixrules" /* tz file to skip when searching. */
69527f654740f2a26ad62a5c155af9199af9e69b889claireho/* Some Linux distributions have 'localtime' in /usr/share/zoneinfo
69627f654740f2a26ad62a5c155af9199af9e69b889claireho   symlinked to /etc/localtime, which makes searchForTZFile return
69727f654740f2a26ad62a5c155af9199af9e69b889claireho   'localtime' when it's the first match. */
69827f654740f2a26ad62a5c155af9199af9e69b889claireho#define TZFILE_SKIP2    "localtime"
69985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#define SEARCH_TZFILE
70085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include <dirent.h>  /* Needed to search through system timezone files */
701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic char gTimeZoneBuffer[PATH_MAX];
703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic char *gTimeZoneBufferPtr = NULL;
704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
706103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if !U_PLATFORM_USES_ONLY_WIN32_API
707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define isNonDigit(ch) (ch < '0' || '9' < ch)
708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UBool isValidOlsonID(const char *id) {
709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t idx = 0;
710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Determine if this is something like Iceland (Olson ID)
712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    or AST4ADT (non-Olson ID) */
713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    while (id[idx] && isNonDigit(id[idx]) && id[idx] != ',') {
714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        idx++;
715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* If we went through the whole string, then it might be okay.
718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    The timezone is sometimes set to "CST-7CDT", "CST6CDT5,J129,J131/19:30",
719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    "GRNLNDST3GRNLNDDT" or similar, so we cannot use it.
720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    The rest of the time it could be an Olson ID. George */
721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return (UBool)(id[idx] == 0
722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        || uprv_strcmp(id, "PST8PDT") == 0
723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        || uprv_strcmp(id, "MST7MDT") == 0
724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        || uprv_strcmp(id, "CST6CDT") == 0
725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        || uprv_strcmp(id, "EST5EDT") == 0);
726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
72727f654740f2a26ad62a5c155af9199af9e69b889claireho
72827f654740f2a26ad62a5c155af9199af9e69b889claireho/* On some Unix-like OS, 'posix' subdirectory in
72927f654740f2a26ad62a5c155af9199af9e69b889claireho   /usr/share/zoneinfo replicates the top-level contents. 'right'
73027f654740f2a26ad62a5c155af9199af9e69b889claireho   subdirectory has the same set of files, but individual files
73127f654740f2a26ad62a5c155af9199af9e69b889claireho   are different from those in the top-level directory or 'posix'
73227f654740f2a26ad62a5c155af9199af9e69b889claireho   because 'right' has files for TAI (Int'l Atomic Time) while 'posix'
73327f654740f2a26ad62a5c155af9199af9e69b889claireho   has files for UTC.
73427f654740f2a26ad62a5c155af9199af9e69b889claireho   When the first match for /etc/localtime is in either of them
73527f654740f2a26ad62a5c155af9199af9e69b889claireho   (usually in posix because 'right' has different file contents),
73627f654740f2a26ad62a5c155af9199af9e69b889claireho   or TZ environment variable points to one of them, createTimeZone
73727f654740f2a26ad62a5c155af9199af9e69b889claireho   fails because, say, 'posix/America/New_York' is not an Olson
73827f654740f2a26ad62a5c155af9199af9e69b889claireho   timezone id ('America/New_York' is). So, we have to skip
73927f654740f2a26ad62a5c155af9199af9e69b889claireho   'posix/' and 'right/' at the beginning. */
74027f654740f2a26ad62a5c155af9199af9e69b889clairehostatic void skipZoneIDPrefix(const char** id) {
74127f654740f2a26ad62a5c155af9199af9e69b889claireho    if (uprv_strncmp(*id, "posix/", 6) == 0
74227f654740f2a26ad62a5c155af9199af9e69b889claireho        || uprv_strncmp(*id, "right/", 6) == 0)
74327f654740f2a26ad62a5c155af9199af9e69b889claireho    {
74427f654740f2a26ad62a5c155af9199af9e69b889claireho        *id += 6;
74527f654740f2a26ad62a5c155af9199af9e69b889claireho    }
74627f654740f2a26ad62a5c155af9199af9e69b889claireho}
747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
749103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if defined(U_TZNAME) && !U_PLATFORM_USES_ONLY_WIN32_API
750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define CONVERT_HOURS_TO_SECONDS(offset) (int32_t)(offset*3600)
752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querutypedef struct OffsetZoneMapping {
753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t offsetSeconds;
754103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    int32_t daylightType; /* 0=U_DAYLIGHT_NONE, 1=daylight in June-U_DAYLIGHT_JUNE, 2=daylight in December=U_DAYLIGHT_DECEMBER*/
755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const char *stdID;
756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const char *dstID;
757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const char *olsonID;
758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} OffsetZoneMapping;
759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
760103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusenum { U_DAYLIGHT_NONE=0,U_DAYLIGHT_JUNE=1,U_DAYLIGHT_DECEMBER=2 };
761103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruThis list tries to disambiguate a set of abbreviated timezone IDs and offsets
764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruand maps it to an Olson ID.
765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruBefore adding anything to this list, take a look at
766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruicu/source/tools/tzcode/tz.alias
767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruSometimes no daylight savings (0) is important to define due to aliases.
768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruThis list can be tested with icu/source/test/compat/tzone.pl
769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruMore values could be added to daylightType to increase precision.
770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/
771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const struct OffsetZoneMapping OFFSET_ZONE_MAPPINGS[] = {
772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {-45900, 2, "CHAST", "CHADT", "Pacific/Chatham"},
773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {-43200, 1, "PETT", "PETST", "Asia/Kamchatka"},
774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {-43200, 2, "NZST", "NZDT", "Pacific/Auckland"},
775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {-43200, 1, "ANAT", "ANAST", "Asia/Anadyr"},
776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {-39600, 1, "MAGT", "MAGST", "Asia/Magadan"},
777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {-37800, 2, "LHST", "LHST", "Australia/Lord_Howe"},
778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {-36000, 2, "EST", "EST", "Australia/Sydney"},
779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {-36000, 1, "SAKT", "SAKST", "Asia/Sakhalin"},
780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {-36000, 1, "VLAT", "VLAST", "Asia/Vladivostok"},
781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {-34200, 2, "CST", "CST", "Australia/South"},
782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {-32400, 1, "YAKT", "YAKST", "Asia/Yakutsk"},
783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {-32400, 1, "CHOT", "CHOST", "Asia/Choibalsan"},
784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {-31500, 2, "CWST", "CWST", "Australia/Eucla"},
785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {-28800, 1, "IRKT", "IRKST", "Asia/Irkutsk"},
786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {-28800, 1, "ULAT", "ULAST", "Asia/Ulaanbaatar"},
787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {-28800, 2, "WST", "WST", "Australia/West"},
788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {-25200, 1, "HOVT", "HOVST", "Asia/Hovd"},
789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {-25200, 1, "KRAT", "KRAST", "Asia/Krasnoyarsk"},
790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {-21600, 1, "NOVT", "NOVST", "Asia/Novosibirsk"},
791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {-21600, 1, "OMST", "OMSST", "Asia/Omsk"},
792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {-18000, 1, "YEKT", "YEKST", "Asia/Yekaterinburg"},
793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {-14400, 1, "SAMT", "SAMST", "Europe/Samara"},
794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {-14400, 1, "AMT", "AMST", "Asia/Yerevan"},
795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {-14400, 1, "AZT", "AZST", "Asia/Baku"},
796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {-10800, 1, "AST", "ADT", "Asia/Baghdad"},
797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {-10800, 1, "MSK", "MSD", "Europe/Moscow"},
798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {-10800, 1, "VOLT", "VOLST", "Europe/Volgograd"},
799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {-7200, 0, "EET", "CEST", "Africa/Tripoli"},
800b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {-7200, 1, "EET", "EEST", "Europe/Athens"}, /* Conflicts with Africa/Cairo */
801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {-7200, 1, "IST", "IDT", "Asia/Jerusalem"},
802b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {-3600, 0, "CET", "WEST", "Africa/Algiers"},
803b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {-3600, 2, "WAT", "WAST", "Africa/Windhoek"},
804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {0, 1, "GMT", "IST", "Europe/Dublin"},
805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {0, 1, "GMT", "BST", "Europe/London"},
806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {0, 0, "WET", "WEST", "Africa/Casablanca"},
807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {0, 0, "WET", "WET", "Africa/El_Aaiun"},
808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {3600, 1, "AZOT", "AZOST", "Atlantic/Azores"},
809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {3600, 1, "EGT", "EGST", "America/Scoresbysund"},
810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {10800, 1, "PMST", "PMDT", "America/Miquelon"},
811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {10800, 2, "UYT", "UYST", "America/Montevideo"},
812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {10800, 1, "WGT", "WGST", "America/Godthab"},
813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {10800, 2, "BRT", "BRST", "Brazil/East"},
814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {12600, 1, "NST", "NDT", "America/St_Johns"},
815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {14400, 1, "AST", "ADT", "Canada/Atlantic"},
816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {14400, 2, "AMT", "AMST", "America/Cuiaba"},
817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {14400, 2, "CLT", "CLST", "Chile/Continental"},
818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {14400, 2, "FKT", "FKST", "Atlantic/Stanley"},
819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {14400, 2, "PYT", "PYST", "America/Asuncion"},
820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {18000, 1, "CST", "CDT", "America/Havana"},
821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {18000, 1, "EST", "EDT", "US/Eastern"}, /* Conflicts with America/Grand_Turk */
822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {21600, 2, "EAST", "EASST", "Chile/EasterIsland"},
823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {21600, 0, "CST", "MDT", "Canada/Saskatchewan"},
824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {21600, 0, "CST", "CDT", "America/Guatemala"},
825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {21600, 1, "CST", "CDT", "US/Central"}, /* Conflicts with Mexico/General */
826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {25200, 1, "MST", "MDT", "US/Mountain"}, /* Conflicts with Mexico/BajaSur */
827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {28800, 0, "PST", "PST", "Pacific/Pitcairn"},
828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {28800, 1, "PST", "PDT", "US/Pacific"}, /* Conflicts with Mexico/BajaNorte */
829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {32400, 1, "AKST", "AKDT", "US/Alaska"},
830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {36000, 1, "HAST", "HADT", "US/Aleutian"}
831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru};
832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*#define DEBUG_TZNAME*/
834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char* remapShortTimeZone(const char *stdID, const char *dstID, int32_t daylightType, int32_t offset)
836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t idx;
838b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef DEBUG_TZNAME
839b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fprintf(stderr, "TZ=%s std=%s dst=%s daylight=%d offset=%d\n", getenv("TZ"), stdID, dstID, daylightType, offset);
840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
841103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    for (idx = 0; idx < LENGTHOF(OFFSET_ZONE_MAPPINGS); idx++)
842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (offset == OFFSET_ZONE_MAPPINGS[idx].offsetSeconds
844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            && daylightType == OFFSET_ZONE_MAPPINGS[idx].daylightType
845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            && strcmp(OFFSET_ZONE_MAPPINGS[idx].stdID, stdID) == 0
846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            && strcmp(OFFSET_ZONE_MAPPINGS[idx].dstID, dstID) == 0)
847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {
848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return OFFSET_ZONE_MAPPINGS[idx].olsonID;
849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
850b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return NULL;
852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
85585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#ifdef SEARCH_TZFILE
85685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#define MAX_PATH_SIZE PATH_MAX /* Set the limit for the size of the path. */
85785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#define MAX_READ_SIZE 512
85885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
85985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hotypedef struct DefaultTZInfo {
86085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    char* defaultTZBuffer;
86185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int64_t defaultTZFileSize;
86285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    FILE* defaultTZFilePtr;
86385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UBool defaultTZstatus;
86485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t defaultTZPosition;
86585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho} DefaultTZInfo;
86685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
86785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho/*
86885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * This method compares the two files given to see if they are a match.
86985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * It is currently use to compare two TZ files.
87085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho */
87185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic UBool compareBinaryFiles(const char* defaultTZFileName, const char* TZFileName, DefaultTZInfo* tzInfo) {
87285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    FILE* file;
87385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int64_t sizeFile;
87485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int64_t sizeFileLeft;
87585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t sizeFileRead;
87685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t sizeFileToRead;
87785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    char bufferFile[MAX_READ_SIZE];
87885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UBool result = TRUE;
87985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
88085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (tzInfo->defaultTZFilePtr == NULL) {
88185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        tzInfo->defaultTZFilePtr = fopen(defaultTZFileName, "r");
88285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
88385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    file = fopen(TZFileName, "r");
88485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
88585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    tzInfo->defaultTZPosition = 0; /* reset position to begin search */
88685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
88785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (file != NULL && tzInfo->defaultTZFilePtr != NULL) {
88885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* First check that the file size are equal. */
88985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (tzInfo->defaultTZFileSize == 0) {
89085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            fseek(tzInfo->defaultTZFilePtr, 0, SEEK_END);
89185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            tzInfo->defaultTZFileSize = ftell(tzInfo->defaultTZFilePtr);
89285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
89385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        fseek(file, 0, SEEK_END);
89485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        sizeFile = ftell(file);
89585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        sizeFileLeft = sizeFile;
89685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
89785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (sizeFile != tzInfo->defaultTZFileSize) {
89885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            result = FALSE;
89985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        } else {
90085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            /* Store the data from the files in seperate buffers and
90185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho             * compare each byte to determine equality.
90285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho             */
90385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if (tzInfo->defaultTZBuffer == NULL) {
90485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                rewind(tzInfo->defaultTZFilePtr);
90585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                tzInfo->defaultTZBuffer = (char*)uprv_malloc(sizeof(char) * tzInfo->defaultTZFileSize);
906b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                sizeFileRead = fread(tzInfo->defaultTZBuffer, 1, tzInfo->defaultTZFileSize, tzInfo->defaultTZFilePtr);
90785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
90885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            rewind(file);
90985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            while(sizeFileLeft > 0) {
91085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                uprv_memset(bufferFile, 0, MAX_READ_SIZE);
91185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                sizeFileToRead = sizeFileLeft < MAX_READ_SIZE ? sizeFileLeft : MAX_READ_SIZE;
91285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
91385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                sizeFileRead = fread(bufferFile, 1, sizeFileToRead, file);
91485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                if (memcmp(tzInfo->defaultTZBuffer + tzInfo->defaultTZPosition, bufferFile, sizeFileRead) != 0) {
91585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    result = FALSE;
91685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    break;
91785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                }
91885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                sizeFileLeft -= sizeFileRead;
91985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                tzInfo->defaultTZPosition += sizeFileRead;
92085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
92185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
92285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    } else {
92385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        result = FALSE;
92485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
92585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
92685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (file != NULL) {
92785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        fclose(file);
92885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
92985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
93085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return result;
93185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
93285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho/*
93385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * This method recursively traverses the directory given for a matching TZ file and returns the first match.
93485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho */
93585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho/* dirent also lists two entries: "." and ".." that we can safely ignore. */
93685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#define SKIP1 "."
93785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#define SKIP2 ".."
93885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic char SEARCH_TZFILE_RESULT[MAX_PATH_SIZE] = "";
93985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic char* searchForTZFile(const char* path, DefaultTZInfo* tzInfo) {
94050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    char curpath[MAX_PATH_SIZE];
94185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    DIR* dirp = opendir(path);
94285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    DIR* subDirp = NULL;
94385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    struct dirent* dirEntry = NULL;
94485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
94585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    char* result = NULL;
94650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (dirp == NULL) {
94750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return result;
94850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
94985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
95085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* Save the current path */
95185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uprv_memset(curpath, 0, MAX_PATH_SIZE);
95285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uprv_strcpy(curpath, path);
95385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
95485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* Check each entry in the directory. */
95585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    while((dirEntry = readdir(dirp)) != NULL) {
95627f654740f2a26ad62a5c155af9199af9e69b889claireho        const char* dirName = dirEntry->d_name;
95727f654740f2a26ad62a5c155af9199af9e69b889claireho        if (uprv_strcmp(dirName, SKIP1) != 0 && uprv_strcmp(dirName, SKIP2) != 0) {
95885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            /* Create a newpath with the new entry to test each entry in the directory. */
95985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            char newpath[MAX_PATH_SIZE];
96085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            uprv_strcpy(newpath, curpath);
96127f654740f2a26ad62a5c155af9199af9e69b889claireho            uprv_strcat(newpath, dirName);
96285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
96385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if ((subDirp = opendir(newpath)) != NULL) {
96485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                /* If this new path is a directory, make a recursive call with the newpath. */
96585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                closedir(subDirp);
96685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                uprv_strcat(newpath, "/");
96785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                result = searchForTZFile(newpath, tzInfo);
96827f654740f2a26ad62a5c155af9199af9e69b889claireho                /*
96927f654740f2a26ad62a5c155af9199af9e69b889claireho                 Have to get out here. Otherwise, we'd keep looking
97027f654740f2a26ad62a5c155af9199af9e69b889claireho                 and return the first match in the top-level directory
97127f654740f2a26ad62a5c155af9199af9e69b889claireho                 if there's a match in the top-level. If not, this function
97227f654740f2a26ad62a5c155af9199af9e69b889claireho                 would return NULL and set gTimeZoneBufferPtr to NULL in initDefault().
97327f654740f2a26ad62a5c155af9199af9e69b889claireho                 It worked without this in most cases because we have a fallback of calling
97427f654740f2a26ad62a5c155af9199af9e69b889claireho                 localtime_r to figure out the default timezone.
97527f654740f2a26ad62a5c155af9199af9e69b889claireho                */
97627f654740f2a26ad62a5c155af9199af9e69b889claireho                if (result != NULL)
97727f654740f2a26ad62a5c155af9199af9e69b889claireho                    break;
97827f654740f2a26ad62a5c155af9199af9e69b889claireho            } else if (uprv_strcmp(TZFILE_SKIP, dirName) != 0 && uprv_strcmp(TZFILE_SKIP2, dirName) != 0) {
97985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                if(compareBinaryFiles(TZDEFAULT, newpath, tzInfo)) {
98027f654740f2a26ad62a5c155af9199af9e69b889claireho                    const char* zoneid = newpath + (sizeof(TZZONEINFO)) - 1;
98127f654740f2a26ad62a5c155af9199af9e69b889claireho                    skipZoneIDPrefix(&zoneid);
98227f654740f2a26ad62a5c155af9199af9e69b889claireho                    uprv_strcpy(SEARCH_TZFILE_RESULT, zoneid);
98385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    result = SEARCH_TZFILE_RESULT;
98485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    /* Get out after the first one found. */
98585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    break;
98685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                }
98785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
98885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
98985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
99085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    closedir(dirp);
99185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return result;
99285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
99385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif
994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI const char* U_EXPORT2
995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuprv_tzname(int n)
996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const char *tzid = NULL;
998103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_PLATFORM_USES_ONLY_WIN32_API
999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    tzid = uprv_detectWindowsTimeZone();
1000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (tzid != NULL) {
1002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return tzid;
1003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else
1005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1006103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius/*#if U_PLATFORM_IS_DARWIN_BASED
1007b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int ret;
1008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1009b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    tzid = getenv("TZFILE");
1010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (tzid != NULL) {
1011b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return tzid;
1012b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif*/
1014b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* This code can be temporarily disabled to test tzname resolution later on. */
1016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifndef DEBUG_TZNAME
1017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    tzid = getenv("TZ");
10188393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    if (tzid != NULL && isValidOlsonID(tzid)
10198393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#if U_PLATFORM == U_PF_SOLARIS
10208393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    /* When TZ equals localtime on Solaris, check the /etc/localtime file. */
10218393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        && uprv_strcmp(tzid, TZ_ENV_CHECK) != 0
10228393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#endif
10238393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    ) {
1024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* This might be a good Olson ID. */
102527f654740f2a26ad62a5c155af9199af9e69b889claireho        skipZoneIDPrefix(&tzid);
1026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return tzid;
1027b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1028b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* else U_TZNAME will give a better result. */
1029b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
1030b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1031103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if defined(CHECK_LOCALTIME_LINK) && !defined(DEBUG_SKIP_LOCALTIME_LINK)
1032b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Caller must handle threading issues */
1033b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (gTimeZoneBufferPtr == NULL) {
1034b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /*
1035b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        This is a trick to look at the name of the link to get the Olson ID
1036b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        because the tzfile contents is underspecified.
1037b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        This isn't guaranteed to work because it may not be a symlink.
1038b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        */
1039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t ret = (int32_t)readlink(TZDEFAULT, gTimeZoneBuffer, sizeof(gTimeZoneBuffer));
1040b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (0 < ret) {
1041b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            int32_t tzZoneInfoLen = uprv_strlen(TZZONEINFO);
1042b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            gTimeZoneBuffer[ret] = 0;
1043b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (uprv_strncmp(gTimeZoneBuffer, TZZONEINFO, tzZoneInfoLen) == 0
1044b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                && isValidOlsonID(gTimeZoneBuffer + tzZoneInfoLen))
1045b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            {
1046b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                return (gTimeZoneBufferPtr = gTimeZoneBuffer + tzZoneInfoLen);
1047b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
104859d709d503bab6e2b61931737e662dd293b40578ccornelius#if U_PLATFORM == U_PF_SOLARIS
104959d709d503bab6e2b61931737e662dd293b40578ccornelius            else
105059d709d503bab6e2b61931737e662dd293b40578ccornelius            {
105159d709d503bab6e2b61931737e662dd293b40578ccornelius                tzZoneInfoLen = uprv_strlen(TZZONEINFO2);
105259d709d503bab6e2b61931737e662dd293b40578ccornelius                if (uprv_strncmp(gTimeZoneBuffer, TZZONEINFO2, tzZoneInfoLen) == 0
105359d709d503bab6e2b61931737e662dd293b40578ccornelius                                && isValidOlsonID(gTimeZoneBuffer + tzZoneInfoLen))
105459d709d503bab6e2b61931737e662dd293b40578ccornelius                {
105559d709d503bab6e2b61931737e662dd293b40578ccornelius                    return (gTimeZoneBufferPtr = gTimeZoneBuffer + tzZoneInfoLen);
105659d709d503bab6e2b61931737e662dd293b40578ccornelius                }
105759d709d503bab6e2b61931737e662dd293b40578ccornelius            }
105859d709d503bab6e2b61931737e662dd293b40578ccornelius#endif
105985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        } else {
106085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#if defined(SEARCH_TZFILE)
106185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            DefaultTZInfo* tzInfo = (DefaultTZInfo*)uprv_malloc(sizeof(DefaultTZInfo));
106285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if (tzInfo != NULL) {
106385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                tzInfo->defaultTZBuffer = NULL;
106485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                tzInfo->defaultTZFileSize = 0;
106585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                tzInfo->defaultTZFilePtr = NULL;
106685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                tzInfo->defaultTZstatus = FALSE;
106785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                tzInfo->defaultTZPosition = 0;
106885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
106985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                gTimeZoneBufferPtr = searchForTZFile(TZZONEINFO, tzInfo);
107085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
107185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                /* Free previously allocated memory */
107285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                if (tzInfo->defaultTZBuffer != NULL) {
107385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    uprv_free(tzInfo->defaultTZBuffer);
107485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                }
107585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                if (tzInfo->defaultTZFilePtr != NULL) {
107685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    fclose(tzInfo->defaultTZFilePtr);
107785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                }
107885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                uprv_free(tzInfo);
107985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
108085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
108185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if (gTimeZoneBufferPtr != NULL && isValidOlsonID(gTimeZoneBufferPtr)) {
108285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                return gTimeZoneBufferPtr;
108385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
108485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif
1085b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1086b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1087b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    else {
1088b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return gTimeZoneBufferPtr;
1089b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1090b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
1091b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
1092b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1093b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef U_TZNAME
1094103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_PLATFORM_USES_ONLY_WIN32_API
109550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /* The return value is free'd in timezone.cpp on Windows because
109650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * the other code path returns a pointer to a heap location. */
109750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return uprv_strdup(U_TZNAME[n]);
109850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#else
1099b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /*
1100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    U_TZNAME is usually a non-unique abbreviation, which isn't normally usable.
1101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    So we remap the abbreviation to an olson ID.
1102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    Since Windows exposes a little more timezone information,
1104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    we normally don't use this code on Windows because
1105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uprv_detectWindowsTimeZone should have already given the correct answer.
1106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    */
1107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
1108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        struct tm juneSol, decemberSol;
1109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int daylightType;
1110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        static const time_t juneSolstice=1182478260; /*2007-06-21 18:11 UT*/
1111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        static const time_t decemberSolstice=1198332540; /*2007-12-22 06:09 UT*/
1112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* This probing will tell us when daylight savings occurs.  */
1114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        localtime_r(&juneSolstice, &juneSol);
1115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        localtime_r(&decemberSolstice, &decemberSol);
1116103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if(decemberSol.tm_isdst > 0) {
1117103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius          daylightType = U_DAYLIGHT_DECEMBER;
1118103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        } else if(juneSol.tm_isdst > 0) {
1119103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius          daylightType = U_DAYLIGHT_JUNE;
1120103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        } else {
1121103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius          daylightType = U_DAYLIGHT_NONE;
1122103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
1123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        tzid = remapShortTimeZone(U_TZNAME[0], U_TZNAME[1], daylightType, uprv_timezone());
1124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (tzid != NULL) {
1125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return tzid;
1126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return U_TZNAME[n];
112950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif
1130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else
1131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return "";
1132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
1133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Get and set the ICU data directory --------------------------------------- */
1136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic char *gDataDirectory = NULL;
113859d709d503bab6e2b61931737e662dd293b40578ccornelius#if U_POSIX_LOCALE || U_PLATFORM_USES_ONLY_WIN32_API
1139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru static char *gCorrectedPOSIXLocale = NULL; /* Heap allocated */
1140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
1141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UBool U_CALLCONV putil_cleanup(void)
1143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
1144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (gDataDirectory && *gDataDirectory) {
1145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_free(gDataDirectory);
1146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    gDataDirectory = NULL;
114859d709d503bab6e2b61931737e662dd293b40578ccornelius#if U_POSIX_LOCALE || U_PLATFORM_USES_ONLY_WIN32_API
1149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (gCorrectedPOSIXLocale) {
1150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_free(gCorrectedPOSIXLocale);
1151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        gCorrectedPOSIXLocale = NULL;
1152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
1154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return TRUE;
1155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
1158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Set the data directory.
1159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *    Make a copy of the passed string, and set the global data dir to point to it.
1160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
1161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI void U_EXPORT2
1162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruu_setDataDirectory(const char *directory) {
1163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    char *newDataDir;
1164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t length;
1165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(directory==NULL || *directory==0) {
1167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* A small optimization to prevent the malloc and copy when the
1168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        shared library is used, and this is a way to make sure that NULL
1169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        is never returned.
1170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        */
1171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        newDataDir = (char *)"";
1172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    else {
1174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        length=(int32_t)uprv_strlen(directory);
1175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        newDataDir = (char *)uprv_malloc(length + 2);
117685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* Exit out if newDataDir could not be created. */
117785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (newDataDir == NULL) {
117885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            return;
117985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
1180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_strcpy(newDataDir, directory);
1181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if (U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR)
1183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {
1184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            char *p;
1185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            while(p = uprv_strchr(newDataDir, U_FILE_ALT_SEP_CHAR)) {
1186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                *p = U_FILE_SEP_CHAR;
1187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
1188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
1190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (gDataDirectory && *gDataDirectory) {
1193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_free(gDataDirectory);
1194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    gDataDirectory = newDataDir;
1196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    ucln_common_registerCleanup(UCLN_COMMON_PUTIL, putil_cleanup);
1197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI UBool U_EXPORT2
120085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Houprv_pathIsAbsolute(const char *path)
1201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
120285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho  if(!path || !*path) {
120385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return FALSE;
1204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  }
1205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  if(*path == U_FILE_SEP_CHAR) {
1207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return TRUE;
1208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  }
1209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if (U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR)
1211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  if(*path == U_FILE_ALT_SEP_CHAR) {
1212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return TRUE;
1213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  }
1214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
1215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1216103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_PLATFORM_USES_ONLY_WIN32_API
1217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  if( (((path[0] >= 'A') && (path[0] <= 'Z')) ||
1218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru       ((path[0] >= 'a') && (path[0] <= 'z'))) &&
1219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      path[1] == ':' ) {
1220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return TRUE;
1221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  }
1222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
1223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  return FALSE;
1225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
122727f654740f2a26ad62a5c155af9199af9e69b889claireho/* Temporary backup setting of ICU_DATA_DIR_PREFIX_ENV_VAR
122827f654740f2a26ad62a5c155af9199af9e69b889claireho   until some client wrapper makefiles are updated */
1229103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_PLATFORM_IS_DARWIN_BASED && TARGET_IPHONE_SIMULATOR
123027f654740f2a26ad62a5c155af9199af9e69b889claireho# if !defined(ICU_DATA_DIR_PREFIX_ENV_VAR)
123127f654740f2a26ad62a5c155af9199af9e69b889claireho#  define ICU_DATA_DIR_PREFIX_ENV_VAR "IPHONE_SIMULATOR_ROOT"
123227f654740f2a26ad62a5c155af9199af9e69b889claireho# endif
123327f654740f2a26ad62a5c155af9199af9e69b889claireho#endif
123427f654740f2a26ad62a5c155af9199af9e69b889claireho
1235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI const char * U_EXPORT2
1236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruu_getDataDirectory(void) {
1237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const char *path = NULL;
123802fdd983fede27bf25bddfbe3b5deb20813df5efElliott Hughes#if defined(ICU_DATA_DIR_PREFIX_ENV_VAR)
123950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    char datadir_path_buffer[PATH_MAX];
124050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif
1241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* if we have the directory, then return it immediately */
124359d709d503bab6e2b61931737e662dd293b40578ccornelius    if(gDataDirectory) {
124459d709d503bab6e2b61931737e662dd293b40578ccornelius        return gDataDirectory;
1245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /*
1248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    When ICU_NO_USER_DATA_OVERRIDE is defined, users aren't allowed to
1249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    override ICU's data with the ICU_DATA environment variable. This prevents
1250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    problems where multiple custom copies of ICU's specific version of data
1251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    are installed on a system. Either the application must define the data
1252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    directory with u_setDataDirectory, define ICU_DATA_DIR when compiling
1253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    ICU, set the data with udata_setCommonData or trust that all of the
1254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    required data is contained in ICU's data library that contains
1255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    the entry point defined by U_ICUDATA_ENTRY_POINT.
1256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    There may also be some platforms where environment variables
1258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    are not allowed.
1259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    */
1260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#   if !defined(ICU_NO_USER_DATA_OVERRIDE) && !UCONFIG_NO_FILE_IO
1261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* First try to get the environment variable */
1262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    path=getenv("ICU_DATA");
1263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#   endif
1264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
126527f654740f2a26ad62a5c155af9199af9e69b889claireho    /* ICU_DATA_DIR may be set as a compile option.
126627f654740f2a26ad62a5c155af9199af9e69b889claireho     * U_ICU_DATA_DEFAULT_DIR is provided and is set by ICU at compile time
126727f654740f2a26ad62a5c155af9199af9e69b889claireho     * and is used only when data is built in archive mode eliminating the need
126827f654740f2a26ad62a5c155af9199af9e69b889claireho     * for ICU_DATA_DIR to be set. U_ICU_DATA_DEFAULT_DIR is set to the installation
126927f654740f2a26ad62a5c155af9199af9e69b889claireho     * directory of the data dat file. Users should use ICU_DATA_DIR if they want to
127027f654740f2a26ad62a5c155af9199af9e69b889claireho     * set their own path.
127127f654740f2a26ad62a5c155af9199af9e69b889claireho     */
127227f654740f2a26ad62a5c155af9199af9e69b889claireho#if defined(ICU_DATA_DIR) || defined(U_ICU_DATA_DEFAULT_DIR)
1273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(path==NULL || *path==0) {
127427f654740f2a26ad62a5c155af9199af9e69b889claireho# if defined(ICU_DATA_DIR_PREFIX_ENV_VAR)
127502fdd983fede27bf25bddfbe3b5deb20813df5efElliott Hughes        const char *prefix = getenv(ICU_DATA_DIR_PREFIX_ENV_VAR);
127627f654740f2a26ad62a5c155af9199af9e69b889claireho# endif
127727f654740f2a26ad62a5c155af9199af9e69b889claireho# ifdef ICU_DATA_DIR
127827f654740f2a26ad62a5c155af9199af9e69b889claireho        path=ICU_DATA_DIR;
127927f654740f2a26ad62a5c155af9199af9e69b889claireho# else
128027f654740f2a26ad62a5c155af9199af9e69b889claireho        path=U_ICU_DATA_DEFAULT_DIR;
128127f654740f2a26ad62a5c155af9199af9e69b889claireho# endif
128227f654740f2a26ad62a5c155af9199af9e69b889claireho# if defined(ICU_DATA_DIR_PREFIX_ENV_VAR)
128302fdd983fede27bf25bddfbe3b5deb20813df5efElliott Hughes        if (prefix != NULL) {
128427f654740f2a26ad62a5c155af9199af9e69b889claireho            snprintf(datadir_path_buffer, PATH_MAX, "%s%s", prefix, path);
128550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            path=datadir_path_buffer;
128650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
128727f654740f2a26ad62a5c155af9199af9e69b889claireho# endif
1288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
128927f654740f2a26ad62a5c155af9199af9e69b889claireho#endif
1290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(path==NULL) {
1292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* It looks really bad, set it to something. */
1293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        path = "";
1294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    u_setDataDirectory(path);
1297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return gDataDirectory;
1298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Macintosh-specific locale information ------------------------------------ */
1305103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_PLATFORM == U_PF_CLASSIC_MACOS
1306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querutypedef struct {
1308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t script;
1309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t region;
1310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t lang;
1311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t date_region;
1312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const char* posixID;
1313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} mac_lc_rec;
1314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Todo: This will be updated with a newer version from www.unicode.org web
1316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru   page when it's available.*/
1317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define MAC_LC_MAGIC_NUMBER -5
1318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define MAC_LC_INIT_NUMBER -9
1319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const mac_lc_rec mac_lc_recs[] = {
1321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 0, "en_US",
1322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* United States*/
1323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 1, "fr_FR",
1324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* France*/
1325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 2, "en_GB",
1326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Great Britain*/
1327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 3, "de_DE",
1328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Germany*/
1329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 4, "it_IT",
1330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Italy*/
1331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 5, "nl_NL",
1332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Metherlands*/
1333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 6, "fr_BE",
1334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* French for Belgium or Lxembourg*/
1335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 7, "sv_SE",
1336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Sweden*/
1337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 9, "da_DK",
1338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Denmark*/
1339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 10, "pt_PT",
1340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Portugal*/
1341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 11, "fr_CA",
1342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* French Canada*/
1343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 13, "is_IS",
1344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Israel*/
1345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 14, "ja_JP",
1346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Japan*/
1347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 15, "en_AU",
1348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Australia*/
1349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 16, "ar_AE",
1350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* the Arabic world (?)*/
1351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 17, "fi_FI",
1352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Finland*/
1353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 18, "fr_CH",
1354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* French for Switzerland*/
1355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 19, "de_CH",
1356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* German for Switzerland*/
1357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 20, "el_GR",
1358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Greece*/
1359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 21, "is_IS",
1360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Iceland ===*/
1361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /*MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 22, "",*/
1362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Malta ===*/
1363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /*MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 23, "",*/
1364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Cyprus ===*/
1365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 24, "tr_TR",
1366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Turkey ===*/
1367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 25, "sh_YU",
1368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Croatian system for Yugoslavia*/
1369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /*MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 33, "",*/
1370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Hindi system for India*/
1371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /*MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 34, "",*/
1372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Pakistan*/
1373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 41, "lt_LT",
1374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Lithuania*/
1375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 42, "pl_PL",
1376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Poland*/
1377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 43, "hu_HU",
1378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Hungary*/
1379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 44, "et_EE",
1380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Estonia*/
1381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 45, "lv_LV",
1382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Latvia*/
1383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /*MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 46, "",*/
1384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Lapland  [Ask Rich for the data. HS]*/
1385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /*MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 47, "",*/
1386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Faeroe Islands*/
1387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 48, "fa_IR",
1388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Iran*/
1389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 49, "ru_RU",
1390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Russia*/
1391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 50, "en_IE",
1392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Ireland*/
1393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 51, "ko_KR",
1394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Korea*/
1395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 52, "zh_CN",
1396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* People's Republic of China*/
1397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 53, "zh_TW",
1398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Taiwan*/
1399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 54, "th_TH",
1400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Thailand*/
1401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* fallback is en_US*/
1403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER,
1404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MAC_LC_MAGIC_NUMBER, "en_US"
1405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru};
1406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
1408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if U_POSIX_LOCALE
141027f654740f2a26ad62a5c155af9199af9e69b889claireho/* A helper function used by uprv_getPOSIXIDForDefaultLocale and
141127f654740f2a26ad62a5c155af9199af9e69b889claireho * uprv_getPOSIXIDForDefaultCodepage. Returns the posix locale id for
141227f654740f2a26ad62a5c155af9199af9e69b889claireho * LC_CTYPE and LC_MESSAGES. It doesn't support other locale categories.
141327f654740f2a26ad62a5c155af9199af9e69b889claireho */
141427f654740f2a26ad62a5c155af9199af9e69b889clairehostatic const char *uprv_getPOSIXIDForCategory(int category)
1415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
141627f654740f2a26ad62a5c155af9199af9e69b889claireho    const char* posixID = NULL;
141727f654740f2a26ad62a5c155af9199af9e69b889claireho    if (category == LC_MESSAGES || category == LC_CTYPE) {
1418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /*
141985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        * On Solaris two different calls to setlocale can result in
1420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        * different values. Only get this value once.
1421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        *
1422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        * We must check this first because an application can set this.
1423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        *
1424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        * LC_ALL can't be used because it's platform dependent. The LANG
1425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        * environment variable seems to affect LC_CTYPE variable by default.
1426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        * Here is what setlocale(LC_ALL, NULL) can return.
1427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        * HPUX can return 'C C C C C C C'
1428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        * Solaris can return /en_US/C/C/C/C/C on the second try.
1429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        * Linux can return LC_CTYPE=C;LC_NUMERIC=C;...
1430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        *
1431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        * The default codepage detection also needs to use LC_CTYPE.
143285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        *
1433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        * Do not call setlocale(LC_*, "")! Using an empty string instead
1434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        * of NULL, will modify the libc behavior.
1435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        */
143627f654740f2a26ad62a5c155af9199af9e69b889claireho        posixID = setlocale(category, NULL);
1437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if ((posixID == 0)
1438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            || (uprv_strcmp("C", posixID) == 0)
1439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            || (uprv_strcmp("POSIX", posixID) == 0))
1440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {
1441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            /* Maybe we got some garbage.  Try something more reasonable */
1442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            posixID = getenv("LC_ALL");
1443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (posixID == 0) {
144427f654740f2a26ad62a5c155af9199af9e69b889claireho                posixID = getenv(category == LC_MESSAGES ? "LC_MESSAGES" : "LC_CTYPE");
1445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (posixID == 0) {
1446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    posixID = getenv("LANG");
1447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
1448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
1449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
145027f654740f2a26ad62a5c155af9199af9e69b889claireho    }
145127f654740f2a26ad62a5c155af9199af9e69b889claireho    if ((posixID==0)
145227f654740f2a26ad62a5c155af9199af9e69b889claireho        || (uprv_strcmp("C", posixID) == 0)
145327f654740f2a26ad62a5c155af9199af9e69b889claireho        || (uprv_strcmp("POSIX", posixID) == 0))
145427f654740f2a26ad62a5c155af9199af9e69b889claireho    {
145527f654740f2a26ad62a5c155af9199af9e69b889claireho        /* Nothing worked.  Give it a nice POSIX default value. */
145627f654740f2a26ad62a5c155af9199af9e69b889claireho        posixID = "en_US_POSIX";
145727f654740f2a26ad62a5c155af9199af9e69b889claireho    }
145827f654740f2a26ad62a5c155af9199af9e69b889claireho    return posixID;
145927f654740f2a26ad62a5c155af9199af9e69b889claireho}
1460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
146127f654740f2a26ad62a5c155af9199af9e69b889claireho/* Return just the POSIX id for the default locale, whatever happens to be in
146227f654740f2a26ad62a5c155af9199af9e69b889claireho * it. It gets the value from LC_MESSAGES and indirectly from LC_ALL and LANG.
146327f654740f2a26ad62a5c155af9199af9e69b889claireho */
146427f654740f2a26ad62a5c155af9199af9e69b889clairehostatic const char *uprv_getPOSIXIDForDefaultLocale(void)
146527f654740f2a26ad62a5c155af9199af9e69b889claireho{
146627f654740f2a26ad62a5c155af9199af9e69b889claireho    static const char* posixID = NULL;
146727f654740f2a26ad62a5c155af9199af9e69b889claireho    if (posixID == 0) {
146827f654740f2a26ad62a5c155af9199af9e69b889claireho        posixID = uprv_getPOSIXIDForCategory(LC_MESSAGES);
1469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
147027f654740f2a26ad62a5c155af9199af9e69b889claireho    return posixID;
147127f654740f2a26ad62a5c155af9199af9e69b889claireho}
1472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
147354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#if !U_CHARSET_IS_UTF8
147427f654740f2a26ad62a5c155af9199af9e69b889claireho/* Return just the POSIX id for the default codepage, whatever happens to be in
147527f654740f2a26ad62a5c155af9199af9e69b889claireho * it. It gets the value from LC_CTYPE and indirectly from LC_ALL and LANG.
147627f654740f2a26ad62a5c155af9199af9e69b889claireho */
147727f654740f2a26ad62a5c155af9199af9e69b889clairehostatic const char *uprv_getPOSIXIDForDefaultCodepage(void)
147827f654740f2a26ad62a5c155af9199af9e69b889claireho{
147927f654740f2a26ad62a5c155af9199af9e69b889claireho    static const char* posixID = NULL;
148027f654740f2a26ad62a5c155af9199af9e69b889claireho    if (posixID == 0) {
148127f654740f2a26ad62a5c155af9199af9e69b889claireho        posixID = uprv_getPOSIXIDForCategory(LC_CTYPE);
148227f654740f2a26ad62a5c155af9199af9e69b889claireho    }
1483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return posixID;
1484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
148654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#endif
1487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* NOTE: The caller should handle thread safety */
1489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI const char* U_EXPORT2
1490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuprv_getDefaultLocaleID()
1491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
1492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if U_POSIX_LOCALE
1493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
1494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  Note that:  (a '!' means the ID is improper somehow)
1495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     LC_ALL  ---->     default_loc          codepage
1496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru--------------------------------------------------------
1497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     ab.CD             ab                   CD
1498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     ab@CD             ab__CD               -
1499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     ab@CD.EF          ab__CD               EF
1500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     ab_CD.EF@GH       ab_CD_GH             EF
1502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruSome 'improper' ways to do the same as above:
1504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  !  ab_CD@GH.EF       ab_CD_GH             EF
1505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  !  ab_CD.EF@GH.IJ    ab_CD_GH             EF
1506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  !  ab_CD@ZZ.EF@GH.IJ ab_CD_GH             EF
1507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     _CD@GH            _CD_GH               -
1509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     _CD.EF@GH         _CD_GH               EF
1510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruThe variant cannot have dots in it.
1512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruThe 'rightmost' variant (@xxx) wins.
1513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruThe leftmost codepage (.xxx) wins.
1514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/
1515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    char *correctedPOSIXLocale = 0;
151627f654740f2a26ad62a5c155af9199af9e69b889claireho    const char* posixID = uprv_getPOSIXIDForDefaultLocale();
1517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const char *p;
1518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const char *q;
1519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t len;
1520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Format: (no spaces)
1522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    ll [ _CC ] [ . MM ] [ @ VV]
1523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      l = lang, C = ctry, M = charmap, V = variant
1525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    */
1526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (gCorrectedPOSIXLocale != NULL) {
152885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return gCorrectedPOSIXLocale;
1529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if ((p = uprv_strchr(posixID, '.')) != NULL) {
1532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* assume new locale can't be larger than old one? */
153354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        correctedPOSIXLocale = static_cast<char *>(uprv_malloc(uprv_strlen(posixID)+1));
153485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* Exit on memory allocation error. */
153585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (correctedPOSIXLocale == NULL) {
153685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            return NULL;
153785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
1538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_strncpy(correctedPOSIXLocale, posixID, p-posixID);
1539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        correctedPOSIXLocale[p-posixID] = 0;
1540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* do not copy after the @ */
1542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if ((p = uprv_strchr(correctedPOSIXLocale, '@')) != NULL) {
1543b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            correctedPOSIXLocale[p-correctedPOSIXLocale] = 0;
1544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Note that we scan the *uncorrected* ID. */
1548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if ((p = uprv_strrchr(posixID, '@')) != NULL) {
1549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (correctedPOSIXLocale == NULL) {
155054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            correctedPOSIXLocale = static_cast<char *>(uprv_malloc(uprv_strlen(posixID)+1));
155185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            /* Exit on memory allocation error. */
155285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if (correctedPOSIXLocale == NULL) {
155385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                return NULL;
155485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
1555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            uprv_strncpy(correctedPOSIXLocale, posixID, p-posixID);
1556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            correctedPOSIXLocale[p-posixID] = 0;
1557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        p++;
1559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* Take care of any special cases here.. */
1561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (!uprv_strcmp(p, "nynorsk")) {
1562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            p = "NY";
1563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            /* Don't worry about no__NY. In practice, it won't appear. */
1564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (uprv_strchr(correctedPOSIXLocale,'_') == NULL) {
1567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            uprv_strcat(correctedPOSIXLocale, "__"); /* aa@b -> aa__b */
1568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        else {
1570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            uprv_strcat(correctedPOSIXLocale, "_"); /* aa_CC@b -> aa_CC_b */
1571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if ((q = uprv_strchr(p, '.')) != NULL) {
1574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            /* How big will the resulting string be? */
1575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            len = (int32_t)(uprv_strlen(correctedPOSIXLocale) + (q-p));
1576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            uprv_strncat(correctedPOSIXLocale, p, q-p);
1577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            correctedPOSIXLocale[len] = 0;
1578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        else {
1580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            /* Anything following the @ sign */
1581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            uprv_strcat(correctedPOSIXLocale, p);
1582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* Should there be a map from 'no@nynorsk' -> no_NO_NY here?
1585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         * How about 'russian' -> 'ru'?
1586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         * Many of the other locales using ISO codes will be handled by the
1587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         * canonicalization functions in uloc_getDefault.
1588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         */
1589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Was a correction made? */
1592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (correctedPOSIXLocale != NULL) {
1593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        posixID = correctedPOSIXLocale;
1594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    else {
1596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* copy it, just in case the original pointer goes away.  See j2395 */
1597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        correctedPOSIXLocale = (char *)uprv_malloc(uprv_strlen(posixID) + 1);
159885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* Exit on memory allocation error. */
159985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (correctedPOSIXLocale == NULL) {
160085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            return NULL;
160185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
1602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        posixID = uprv_strcpy(correctedPOSIXLocale, posixID);
1603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (gCorrectedPOSIXLocale == NULL) {
1606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        gCorrectedPOSIXLocale = correctedPOSIXLocale;
1607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        ucln_common_registerCleanup(UCLN_COMMON_PUTIL, putil_cleanup);
1608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        correctedPOSIXLocale = NULL;
1609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (correctedPOSIXLocale != NULL) {  /* Was already set - clean up. */
161285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        uprv_free(correctedPOSIXLocale);
1613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return posixID;
1616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1617103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#elif U_PLATFORM_USES_ONLY_WIN32_API
161859d709d503bab6e2b61931737e662dd293b40578ccornelius#define POSIX_LOCALE_CAPACITY 64
1619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
162059d709d503bab6e2b61931737e662dd293b40578ccornelius    char *correctedPOSIXLocale = 0;
162159d709d503bab6e2b61931737e662dd293b40578ccornelius
162259d709d503bab6e2b61931737e662dd293b40578ccornelius    if (gCorrectedPOSIXLocale != NULL) {
162359d709d503bab6e2b61931737e662dd293b40578ccornelius        return gCorrectedPOSIXLocale;
162459d709d503bab6e2b61931737e662dd293b40578ccornelius    }
162559d709d503bab6e2b61931737e662dd293b40578ccornelius
1626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    LCID id = GetThreadLocale();
162759d709d503bab6e2b61931737e662dd293b40578ccornelius    correctedPOSIXLocale = static_cast<char *>(uprv_malloc(POSIX_LOCALE_CAPACITY + 1));
162859d709d503bab6e2b61931737e662dd293b40578ccornelius    if (correctedPOSIXLocale) {
162959d709d503bab6e2b61931737e662dd293b40578ccornelius        int32_t posixLen = uprv_convertToPosix(id, correctedPOSIXLocale, POSIX_LOCALE_CAPACITY, &status);
163059d709d503bab6e2b61931737e662dd293b40578ccornelius        if (U_SUCCESS(status)) {
163159d709d503bab6e2b61931737e662dd293b40578ccornelius            *(correctedPOSIXLocale + posixLen) = 0;
163259d709d503bab6e2b61931737e662dd293b40578ccornelius            gCorrectedPOSIXLocale = correctedPOSIXLocale;
163359d709d503bab6e2b61931737e662dd293b40578ccornelius            ucln_common_registerCleanup(UCLN_COMMON_PUTIL, putil_cleanup);
163459d709d503bab6e2b61931737e662dd293b40578ccornelius        } else {
163559d709d503bab6e2b61931737e662dd293b40578ccornelius            uprv_free(correctedPOSIXLocale);
163659d709d503bab6e2b61931737e662dd293b40578ccornelius        }
163759d709d503bab6e2b61931737e662dd293b40578ccornelius    }
1638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
163959d709d503bab6e2b61931737e662dd293b40578ccornelius    if (gCorrectedPOSIXLocale == NULL) {
164059d709d503bab6e2b61931737e662dd293b40578ccornelius        return "en_US";
1641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
164259d709d503bab6e2b61931737e662dd293b40578ccornelius    return gCorrectedPOSIXLocale;
1643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1644103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#elif U_PLATFORM == U_PF_CLASSIC_MACOS
1645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t script = MAC_LC_INIT_NUMBER;
1646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* = IntlScript(); or GetScriptManagerVariable(smSysScript);*/
1647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t region = MAC_LC_INIT_NUMBER;
1648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* = GetScriptManagerVariable(smRegionCode);*/
1649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t lang = MAC_LC_INIT_NUMBER;
1650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* = GetScriptManagerVariable(smScriptLang);*/
1651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t date_region = MAC_LC_INIT_NUMBER;
1652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const char* posixID = 0;
1653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t count = sizeof(mac_lc_recs) / sizeof(mac_lc_rec);
1654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t i;
1655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    Intl1Hndl ih;
1656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    ih = (Intl1Hndl) GetIntlResource(1);
1658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (ih)
1659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        date_region = ((uint16_t)(*ih)->intl1Vers) >> 8;
1660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    for (i = 0; i < count; i++) {
1662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (   ((mac_lc_recs[i].script == MAC_LC_MAGIC_NUMBER)
1663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru             || (mac_lc_recs[i].script == script))
1664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            && ((mac_lc_recs[i].region == MAC_LC_MAGIC_NUMBER)
1665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru             || (mac_lc_recs[i].region == region))
1666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            && ((mac_lc_recs[i].lang == MAC_LC_MAGIC_NUMBER)
1667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru             || (mac_lc_recs[i].lang == lang))
1668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            && ((mac_lc_recs[i].date_region == MAC_LC_MAGIC_NUMBER)
1669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru             || (mac_lc_recs[i].date_region == date_region))
1670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            )
1671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {
1672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            posixID = mac_lc_recs[i].posixID;
1673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
1674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return posixID;
1678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1679103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#elif U_PLATFORM == U_PF_OS400
1680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* locales are process scoped and are by definition thread safe */
1681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    static char correctedLocale[64];
1682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const  char *localeID = getenv("LC_ALL");
1683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru           char *p;
1684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (localeID == NULL)
1686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        localeID = getenv("LANG");
1687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (localeID == NULL)
1688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        localeID = setlocale(LC_ALL, NULL);
1689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Make sure we have something... */
1690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (localeID == NULL)
1691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return "en_US_POSIX";
1692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Extract the locale name from the path. */
1694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if((p = uprv_strrchr(localeID, '/')) != NULL)
1695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
1696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* Increment p to start of locale name. */
1697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        p++;
1698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        localeID = p;
1699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Copy to work location. */
1702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uprv_strcpy(correctedLocale, localeID);
1703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Strip off the '.locale' extension. */
1705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if((p = uprv_strchr(correctedLocale, '.')) != NULL) {
1706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        *p = 0;
1707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Upper case the locale name. */
1710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    T_CString_toUpperCase(correctedLocale);
1711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* See if we are using the POSIX locale.  Any of the
1713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    * following are equivalent and use the same QLGPGCMA
1714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    * (POSIX) locale.
1715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    * QLGPGCMA2 means UCS2
1716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    * QLGPGCMA_4 means UTF-32
1717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    * QLGPGCMA_8 means UTF-8
1718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    */
1719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if ((uprv_strcmp("C", correctedLocale) == 0) ||
1720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        (uprv_strcmp("POSIX", correctedLocale) == 0) ||
1721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        (uprv_strncmp("QLGPGCMA", correctedLocale, 8) == 0))
1722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
1723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_strcpy(correctedLocale, "en_US_POSIX");
1724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    else
1726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
1727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int16_t LocaleLen;
1728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* Lower case the lang portion. */
1730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        for(p = correctedLocale; *p != 0 && *p != '_'; p++)
1731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {
1732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            *p = uprv_tolower(*p);
1733b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* Adjust for Euro.  After '_E' add 'URO'. */
1736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        LocaleLen = uprv_strlen(correctedLocale);
1737b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (correctedLocale[LocaleLen - 2] == '_' &&
1738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            correctedLocale[LocaleLen - 1] == 'E')
1739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {
1740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            uprv_strcat(correctedLocale, "URO");
1741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* If using Lotus-based locale then convert to
1744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         * equivalent non Lotus.
1745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         */
1746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        else if (correctedLocale[LocaleLen - 2] == '_' &&
1747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            correctedLocale[LocaleLen - 1] == 'L')
1748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {
1749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            correctedLocale[LocaleLen - 2] = 0;
1750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* There are separate simplified and traditional
1753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         * locales called zh_HK_S and zh_HK_T.
1754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         */
1755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        else if (uprv_strncmp(correctedLocale, "zh_HK", 5) == 0)
1756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {
1757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            uprv_strcpy(correctedLocale, "zh_HK");
1758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* A special zh_CN_GBK locale...
1761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        */
1762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        else if (uprv_strcmp(correctedLocale, "zh_CN_GBK") == 0)
1763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {
1764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            uprv_strcpy(correctedLocale, "zh_CN");
1765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return correctedLocale;
1770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
1771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
177485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#if !U_CHARSET_IS_UTF8
1775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if U_POSIX_LOCALE
1776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
1777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDue to various platform differences, one platform may specify a charset,
1778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruwhen they really mean a different charset. Remap the names so that they are
1779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querucompatible with ICU. Only conflicting/ambiguous aliases should be resolved
1780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruhere. Before adding anything to this function, please consider adding unique
1781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querunames to the ICU alias table in the data directory.
1782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/
1783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char*
1784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruremapPlatformDependentCodepage(const char *locale, const char *name) {
1785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (locale != NULL && *locale == 0) {
1786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* Make sure that an empty locale is handled the same way. */
1787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        locale = NULL;
1788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (name == NULL) {
1790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return NULL;
1791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1792103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_PLATFORM == U_PF_AIX
1793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (uprv_strcmp(name, "IBM-943") == 0) {
1794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* Use the ASCII compatible ibm-943 */
1795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        name = "Shift-JIS";
1796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    else if (uprv_strcmp(name, "IBM-1252") == 0) {
1798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* Use the windows-1252 that contains the Euro */
1799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        name = "IBM-5348";
1800b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1801103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#elif U_PLATFORM == U_PF_SOLARIS
1802b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (locale != NULL && uprv_strcmp(name, "EUC") == 0) {
1803b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* Solaris underspecifies the "EUC" name. */
1804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (uprv_strcmp(locale, "zh_CN") == 0) {
1805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            name = "EUC-CN";
1806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        else if (uprv_strcmp(locale, "zh_TW") == 0) {
1808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            name = "EUC-TW";
1809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        else if (uprv_strcmp(locale, "ko_KR") == 0) {
1811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            name = "EUC-KR";
1812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    else if (uprv_strcmp(name, "eucJP") == 0) {
1815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /*
1816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        ibm-954 is the best match.
1817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        ibm-33722 is the default for eucJP (similar to Windows).
1818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        */
1819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        name = "eucjis";
1820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
182185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    else if (uprv_strcmp(name, "646") == 0) {
182285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /*
182385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho         * The default codepage given by Solaris is 646 but the C library routines treat it as if it was
182485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho         * ISO-8859-1 instead of US-ASCII(646).
182585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho         */
182685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        name = "ISO-8859-1";
182785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
1828103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#elif U_PLATFORM_IS_DARWIN_BASED
1829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (locale == NULL && *name == 0) {
1830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /*
1831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        No locale was specified, and an empty name was passed in.
1832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        This usually indicates that nl_langinfo didn't return valid information.
1833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        Mac OS X uses UTF-8 by default (especially the locale data and console).
1834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        */
1835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        name = "UTF-8";
1836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
183785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    else if (uprv_strcmp(name, "CP949") == 0) {
183885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* Remap CP949 to a similar codepage to avoid issues with backslash and won symbol. */
183985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        name = "EUC-KR";
184085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
184150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    else if (locale != NULL && uprv_strcmp(locale, "en_US_POSIX") != 0 && uprv_strcmp(name, "US-ASCII") == 0) {
184250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        /*
184350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         * For non C/POSIX locale, default the code page to UTF-8 instead of US-ASCII.
184450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         */
184550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        name = "UTF-8";
184650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
1847103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#elif U_PLATFORM == U_PF_BSD
184885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (uprv_strcmp(name, "CP949") == 0) {
184985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* Remap CP949 to a similar codepage to avoid issues with backslash and won symbol. */
185085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        name = "EUC-KR";
185185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
1852103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#elif U_PLATFORM == U_PF_HPUX
185385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (locale != NULL && uprv_strcmp(locale, "zh_HK") == 0 && uprv_strcmp(name, "big5") == 0) {
185485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* HP decided to extend big5 as hkbig5 even though it's not compatible :-( */
185585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* zh_TW.big5 is not the same charset as zh_HK.big5! */
185685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        name = "hkbig5";
185785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
185885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    else if (uprv_strcmp(name, "eucJP") == 0) {
1859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /*
1860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        ibm-1350 is the best match, but unavailable.
1861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        ibm-954 is mostly a superset of ibm-1350.
1862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        ibm-33722 is the default for eucJP (similar to Windows).
1863b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        */
1864b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        name = "eucjis";
1865b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1866103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#elif U_PLATFORM == U_PF_LINUX
1867b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (locale != NULL && uprv_strcmp(name, "euc") == 0) {
1868b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* Linux underspecifies the "EUC" name. */
1869b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (uprv_strcmp(locale, "korean") == 0) {
1870b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            name = "EUC-KR";
1871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        else if (uprv_strcmp(locale, "japanese") == 0) {
1873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            /* See comment below about eucJP */
1874b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            name = "eucjis";
1875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1876b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    else if (uprv_strcmp(name, "eucjp") == 0) {
1878b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /*
1879b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        ibm-1350 is the best match, but unavailable.
1880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        ibm-954 is mostly a superset of ibm-1350.
1881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        ibm-33722 is the default for eucJP (similar to Windows).
1882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        */
1883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        name = "eucjis";
1884b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
188550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    else if (locale != NULL && uprv_strcmp(locale, "en_US_POSIX") != 0 &&
188650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            (uprv_strcmp(name, "ANSI_X3.4-1968") == 0 || uprv_strcmp(name, "US-ASCII") == 0)) {
188750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        /*
188850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         * For non C/POSIX locale, default the code page to UTF-8 instead of US-ASCII.
188950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         */
189050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        name = "UTF-8";
189150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
189227f654740f2a26ad62a5c155af9199af9e69b889claireho    /*
189327f654740f2a26ad62a5c155af9199af9e69b889claireho     * Linux returns ANSI_X3.4-1968 for C/POSIX, but the call site takes care of
189427f654740f2a26ad62a5c155af9199af9e69b889claireho     * it by falling back to 'US-ASCII' when NULL is returned from this
189527f654740f2a26ad62a5c155af9199af9e69b889claireho     * function. So, we don't have to worry about it here.
189627f654740f2a26ad62a5c155af9199af9e69b889claireho     */
1897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
1898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* return NULL when "" is passed in */
1899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (*name == 0) {
1900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        name = NULL;
1901b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1902b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return name;
1903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
190585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic const char*
1906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerugetCodepageFromPOSIXID(const char *localeName, char * buffer, int32_t buffCapacity)
1907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
1908b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    char localeBuf[100];
1909b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const char *name = NULL;
1910b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    char *variant = NULL;
1911b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1912b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (localeName != NULL && (name = (uprv_strchr(localeName, '.'))) != NULL) {
1913b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        size_t localeCapacity = uprv_min(sizeof(localeBuf), (name-localeName)+1);
1914b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_strncpy(localeBuf, localeName, localeCapacity);
1915b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        localeBuf[localeCapacity-1] = 0; /* ensure NULL termination */
1916b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        name = uprv_strncpy(buffer, name+1, buffCapacity);
1917b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        buffer[buffCapacity-1] = 0; /* ensure NULL termination */
1918103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if ((variant = const_cast<char *>(uprv_strchr(name, '@'))) != NULL) {
1919b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            *variant = 0;
1920b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1921b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        name = remapPlatformDependentCodepage(localeBuf, name);
1922b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1923b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return name;
1924b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1925b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
1926b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
192785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic const char*
1928b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint_getDefaultCodepage()
1929b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
1930103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_PLATFORM == U_PF_OS400
1931b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uint32_t ccsid = 37; /* Default to ibm-37 */
1932b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    static char codepage[64];
1933b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    Qwc_JOBI0400_t jobinfo;
1934b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    Qus_EC_t error = { sizeof(Qus_EC_t) }; /* SPI error code */
1935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    EPT_CALL(QUSRJOBI)(&jobinfo, sizeof(jobinfo), "JOBI0400",
1937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        "*                         ", "                ", &error);
1938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (error.Bytes_Available == 0) {
1940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (jobinfo.Coded_Char_Set_ID != 0xFFFF) {
1941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            ccsid = (uint32_t)jobinfo.Coded_Char_Set_ID;
1942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        else if (jobinfo.Default_Coded_Char_Set_Id != 0xFFFF) {
1944b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            ccsid = (uint32_t)jobinfo.Default_Coded_Char_Set_Id;
1945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1946b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* else use the default */
1947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1948b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    sprintf(codepage,"ibm-%d", ccsid);
1949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return codepage;
1950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1951103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#elif U_PLATFORM == U_PF_OS390
1952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    static char codepage[64];
195385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
195485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    strncpy(codepage, nl_langinfo(CODESET),63-strlen(UCNV_SWAP_LFNL_OPTION_STRING));
195585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    strcat(codepage,UCNV_SWAP_LFNL_OPTION_STRING);
1956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    codepage[63] = 0; /* NULL terminate */
195785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
1958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return codepage;
1959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1960103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#elif U_PLATFORM == U_PF_CLASSIC_MACOS
1961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return "macintosh"; /* TODO: Macintosh Roman. There must be a better way. fixme! */
1962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1963103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#elif U_PLATFORM_USES_ONLY_WIN32_API
1964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    static char codepage[64];
1965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    sprintf(codepage, "windows-%d", GetACP());
1966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return codepage;
1967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#elif U_POSIX_LOCALE
1969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    static char codesetName[100];
1970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const char *localeName = NULL;
1971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const char *name = NULL;
1972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
197327f654740f2a26ad62a5c155af9199af9e69b889claireho    localeName = uprv_getPOSIXIDForDefaultCodepage();
1974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uprv_memset(codesetName, 0, sizeof(codesetName));
1975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if U_HAVE_NL_LANGINFO_CODESET
197627f654740f2a26ad62a5c155af9199af9e69b889claireho    /* When available, check nl_langinfo first because it usually gives more
197727f654740f2a26ad62a5c155af9199af9e69b889claireho       useful names. It depends on LC_CTYPE.
1978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru       nl_langinfo may use the same buffer as setlocale. */
1979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
1980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        const char *codeset = nl_langinfo(U_NL_LANGINFO_CODESET);
1981103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_PLATFORM_IS_DARWIN_BASED || U_PLATFORM_IS_LINUX_BASED
198250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        /*
198350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         * On Linux and MacOSX, ensure that default codepage for non C/POSIX locale is UTF-8
198450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         * instead of ASCII.
198550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         */
198650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (uprv_strcmp(localeName, "en_US_POSIX") != 0) {
198750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            codeset = remapPlatformDependentCodepage(localeName, codeset);
198850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        } else
198950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif
199050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        {
199150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            codeset = remapPlatformDependentCodepage(NULL, codeset);
199250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
199350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
1994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (codeset != NULL) {
1995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            uprv_strncpy(codesetName, codeset, sizeof(codesetName));
1996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            codesetName[sizeof(codesetName)-1] = 0;
1997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return codesetName;
1998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
2001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
200227f654740f2a26ad62a5c155af9199af9e69b889claireho    /* Use setlocale in a nice way, and then check some environment variables.
200327f654740f2a26ad62a5c155af9199af9e69b889claireho       Maybe the application used setlocale already.
200427f654740f2a26ad62a5c155af9199af9e69b889claireho    */
200527f654740f2a26ad62a5c155af9199af9e69b889claireho    uprv_memset(codesetName, 0, sizeof(codesetName));
200627f654740f2a26ad62a5c155af9199af9e69b889claireho    name = getCodepageFromPOSIXID(localeName, codesetName, sizeof(codesetName));
200727f654740f2a26ad62a5c155af9199af9e69b889claireho    if (name) {
200827f654740f2a26ad62a5c155af9199af9e69b889claireho        /* if we can find the codeset name from setlocale, return that. */
200927f654740f2a26ad62a5c155af9199af9e69b889claireho        return name;
201027f654740f2a26ad62a5c155af9199af9e69b889claireho    }
201127f654740f2a26ad62a5c155af9199af9e69b889claireho
2012b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (*codesetName == 0)
2013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
2014b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* Everything failed. Return US ASCII (ISO 646). */
2015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        (void)uprv_strcpy(codesetName, "US-ASCII");
2016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return codesetName;
2018b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else
2019b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return "US-ASCII";
2020b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
2021b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
2022b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2023b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI const char*  U_EXPORT2
2025b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuprv_getDefaultCodepage()
2026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
2027b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    static char const  *name = NULL;
2028b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    umtx_lock(NULL);
2029b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (name == NULL) {
2030b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        name = int_getDefaultCodepage();
2031b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2032b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    umtx_unlock(NULL);
2033b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return name;
2034b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
203585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif  /* !U_CHARSET_IS_UTF8 */
2036b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2037b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2038b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* end of platform-specific implementation -------------- */
2039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2040b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* version handling --------------------------------------------------------- */
2041b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2042b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI void U_EXPORT2
2043b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruu_versionFromString(UVersionInfo versionArray, const char *versionString) {
2044b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    char *end;
2045b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uint16_t part=0;
2046b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2047b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(versionArray==NULL) {
2048b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return;
2049b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2050b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2051b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(versionString!=NULL) {
2052b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        for(;;) {
2053b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            versionArray[part]=(uint8_t)uprv_strtoul(versionString, &end, 10);
2054b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if(end==versionString || ++part==U_MAX_VERSION_LENGTH || *end!=U_VERSION_DELIMITER) {
2055b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                break;
2056b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
2057b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            versionString=end+1;
2058b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2059b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2060b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2061b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    while(part<U_MAX_VERSION_LENGTH) {
2062b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        versionArray[part++]=0;
2063b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2064b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
2065b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2066b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI void U_EXPORT2
206785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hou_versionFromUString(UVersionInfo versionArray, const UChar *versionString) {
206885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(versionArray!=NULL && versionString!=NULL) {
206985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        char versionChars[U_MAX_VERSION_STRING_LENGTH+1];
207085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        int32_t len = u_strlen(versionString);
207185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(len>U_MAX_VERSION_STRING_LENGTH) {
207285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            len = U_MAX_VERSION_STRING_LENGTH;
207385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
207485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        u_UCharsToChars(versionString, versionChars, len);
207550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        versionChars[len]=0;
207685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        u_versionFromString(versionArray, versionChars);
207785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
207885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
207985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
208085bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoU_CAPI void U_EXPORT2
2081103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusu_versionToString(const UVersionInfo versionArray, char *versionString) {
2082b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uint16_t count, part;
2083b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uint8_t field;
2084b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2085b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(versionString==NULL) {
2086b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return;
2087b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2088b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2089b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(versionArray==NULL) {
2090b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        versionString[0]=0;
2091b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return;
2092b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2093b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2094b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* count how many fields need to be written */
2095b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    for(count=4; count>0 && versionArray[count-1]==0; --count) {
2096b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2097b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2098b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(count <= 1) {
2099b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        count = 2;
2100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* write the first part */
2103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* write the decimal field value */
2104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    field=versionArray[0];
2105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(field>=100) {
2106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        *versionString++=(char)('0'+field/100);
2107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        field%=100;
2108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(field>=10) {
2110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        *versionString++=(char)('0'+field/10);
2111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        field%=10;
2112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    *versionString++=(char)('0'+field);
2114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* write the following parts */
2116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    for(part=1; part<count; ++part) {
2117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* write a dot first */
2118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        *versionString++=U_VERSION_DELIMITER;
2119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* write the decimal field value */
2121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        field=versionArray[part];
2122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(field>=100) {
2123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            *versionString++=(char)('0'+field/100);
2124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            field%=100;
2125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(field>=10) {
2127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            *versionString++=(char)('0'+field/10);
2128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            field%=10;
2129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        *versionString++=(char)('0'+field);
2131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* NUL-terminate */
2134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    *versionString=0;
2135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
2136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI void U_EXPORT2
2138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruu_getVersion(UVersionInfo versionArray) {
2139fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    (void)copyright;   // Suppress unused variable warning from clang.
2140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    u_versionFromString(versionArray, U_ICU_VERSION);
2141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
2142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
214350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/**
214450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * icucfg.h dependent code
214550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */
214650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
214750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#if U_ENABLE_DYLOAD
214850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
214954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#if HAVE_DLOPEN && !U_PLATFORM_USES_ONLY_WIN32_API
215050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
2151103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if HAVE_DLFCN_H
215250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
215350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#ifdef __MVS__
215450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#ifndef __SUSV3
215550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define __SUSV3 1
215650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif
215750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif
215850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include <dlfcn.h>
215950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif
216050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
216150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_INTERNAL void * U_EXPORT2
216250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehouprv_dl_open(const char *libName, UErrorCode *status) {
216327f654740f2a26ad62a5c155af9199af9e69b889claireho  void *ret = NULL;
216427f654740f2a26ad62a5c155af9199af9e69b889claireho  if(U_FAILURE(*status)) return ret;
216527f654740f2a26ad62a5c155af9199af9e69b889claireho  ret =  dlopen(libName, RTLD_NOW|RTLD_GLOBAL);
216627f654740f2a26ad62a5c155af9199af9e69b889claireho  if(ret==NULL) {
2167103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#ifdef U_TRACE_DYLOAD
2168103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    printf("dlerror on dlopen(%s): %s\n", libName, dlerror());
216927f654740f2a26ad62a5c155af9199af9e69b889claireho#endif
217027f654740f2a26ad62a5c155af9199af9e69b889claireho    *status = U_MISSING_RESOURCE_ERROR;
217127f654740f2a26ad62a5c155af9199af9e69b889claireho  }
217227f654740f2a26ad62a5c155af9199af9e69b889claireho  return ret;
217350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
217450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
217550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_INTERNAL void U_EXPORT2
217650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehouprv_dl_close(void *lib, UErrorCode *status) {
217727f654740f2a26ad62a5c155af9199af9e69b889claireho  if(U_FAILURE(*status)) return;
217827f654740f2a26ad62a5c155af9199af9e69b889claireho  dlclose(lib);
217950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
218050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
2181b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoU_INTERNAL UVoidFunction* U_EXPORT2
2182b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehouprv_dlsym_func(void *lib, const char* sym, UErrorCode *status) {
2183b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  union {
2184103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      UVoidFunction *fp;
2185103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      void *vp;
2186103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  } uret;
2187103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  uret.fp = NULL;
2188103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  if(U_FAILURE(*status)) return uret.fp;
2189103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  uret.vp = dlsym(lib, sym);
2190103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  if(uret.vp == NULL) {
2191103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#ifdef U_TRACE_DYLOAD
2192103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    printf("dlerror on dlsym(%p,%s): %s\n", lib,sym, dlerror());
2193103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
219427f654740f2a26ad62a5c155af9199af9e69b889claireho    *status = U_MISSING_RESOURCE_ERROR;
219527f654740f2a26ad62a5c155af9199af9e69b889claireho  }
2196103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius  return uret.fp;
219750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
219850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
219950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#else
220050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
220150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/* null (nonexistent) implementation. */
220250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
220350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_INTERNAL void * U_EXPORT2
220450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehouprv_dl_open(const char *libName, UErrorCode *status) {
220527f654740f2a26ad62a5c155af9199af9e69b889claireho  if(U_FAILURE(*status)) return NULL;
220627f654740f2a26ad62a5c155af9199af9e69b889claireho  *status = U_UNSUPPORTED_ERROR;
220727f654740f2a26ad62a5c155af9199af9e69b889claireho  return NULL;
220850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
220950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
221050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_INTERNAL void U_EXPORT2
221150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehouprv_dl_close(void *lib, UErrorCode *status) {
221227f654740f2a26ad62a5c155af9199af9e69b889claireho  if(U_FAILURE(*status)) return;
221327f654740f2a26ad62a5c155af9199af9e69b889claireho  *status = U_UNSUPPORTED_ERROR;
221427f654740f2a26ad62a5c155af9199af9e69b889claireho  return;
221550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
221650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
221750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
2218b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoU_INTERNAL UVoidFunction* U_EXPORT2
2219b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehouprv_dlsym_func(void *lib, const char* sym, UErrorCode *status) {
2220b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  if(U_SUCCESS(*status)) {
2221b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    *status = U_UNSUPPORTED_ERROR;
2222b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  }
2223b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  return (UVoidFunction*)NULL;
222450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
222550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
222650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
222750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
222850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif
222950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
223054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#elif U_PLATFORM_USES_ONLY_WIN32_API
223150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
223250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_INTERNAL void * U_EXPORT2
223350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehouprv_dl_open(const char *libName, UErrorCode *status) {
223427f654740f2a26ad62a5c155af9199af9e69b889claireho  HMODULE lib = NULL;
223527f654740f2a26ad62a5c155af9199af9e69b889claireho
223627f654740f2a26ad62a5c155af9199af9e69b889claireho  if(U_FAILURE(*status)) return NULL;
223727f654740f2a26ad62a5c155af9199af9e69b889claireho
2238b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  lib = LoadLibraryA(libName);
223927f654740f2a26ad62a5c155af9199af9e69b889claireho
224027f654740f2a26ad62a5c155af9199af9e69b889claireho  if(lib==NULL) {
224127f654740f2a26ad62a5c155af9199af9e69b889claireho    *status = U_MISSING_RESOURCE_ERROR;
224227f654740f2a26ad62a5c155af9199af9e69b889claireho  }
224327f654740f2a26ad62a5c155af9199af9e69b889claireho
224427f654740f2a26ad62a5c155af9199af9e69b889claireho  return (void*)lib;
224550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
224650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
224750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_INTERNAL void U_EXPORT2
224850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehouprv_dl_close(void *lib, UErrorCode *status) {
224927f654740f2a26ad62a5c155af9199af9e69b889claireho  HMODULE handle = (HMODULE)lib;
225027f654740f2a26ad62a5c155af9199af9e69b889claireho  if(U_FAILURE(*status)) return;
225127f654740f2a26ad62a5c155af9199af9e69b889claireho
225227f654740f2a26ad62a5c155af9199af9e69b889claireho  FreeLibrary(handle);
225327f654740f2a26ad62a5c155af9199af9e69b889claireho
225427f654740f2a26ad62a5c155af9199af9e69b889claireho  return;
225550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
225650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
225750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
2258b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoU_INTERNAL UVoidFunction* U_EXPORT2
2259b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehouprv_dlsym_func(void *lib, const char* sym, UErrorCode *status) {
226027f654740f2a26ad62a5c155af9199af9e69b889claireho  HMODULE handle = (HMODULE)lib;
2261b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  UVoidFunction* addr = NULL;
226227f654740f2a26ad62a5c155af9199af9e69b889claireho
226327f654740f2a26ad62a5c155af9199af9e69b889claireho  if(U_FAILURE(*status) || lib==NULL) return NULL;
226427f654740f2a26ad62a5c155af9199af9e69b889claireho
2265b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  addr = (UVoidFunction*)GetProcAddress(handle, sym);
226627f654740f2a26ad62a5c155af9199af9e69b889claireho
226727f654740f2a26ad62a5c155af9199af9e69b889claireho  if(addr==NULL) {
226827f654740f2a26ad62a5c155af9199af9e69b889claireho    DWORD lastError = GetLastError();
226927f654740f2a26ad62a5c155af9199af9e69b889claireho    if(lastError == ERROR_PROC_NOT_FOUND) {
227027f654740f2a26ad62a5c155af9199af9e69b889claireho      *status = U_MISSING_RESOURCE_ERROR;
227127f654740f2a26ad62a5c155af9199af9e69b889claireho    } else {
227227f654740f2a26ad62a5c155af9199af9e69b889claireho      *status = U_UNSUPPORTED_ERROR; /* other unknown error. */
227327f654740f2a26ad62a5c155af9199af9e69b889claireho    }
227427f654740f2a26ad62a5c155af9199af9e69b889claireho  }
227527f654740f2a26ad62a5c155af9199af9e69b889claireho
227627f654740f2a26ad62a5c155af9199af9e69b889claireho  return addr;
227750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
227850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
227950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
228050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#else
228150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
228250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/* No dynamic loading set. */
228350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
228450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_INTERNAL void * U_EXPORT2
228550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehouprv_dl_open(const char *libName, UErrorCode *status) {
228650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(U_FAILURE(*status)) return NULL;
228750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    *status = U_UNSUPPORTED_ERROR;
228850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return NULL;
228950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
229050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
229150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_INTERNAL void U_EXPORT2
229250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehouprv_dl_close(void *lib, UErrorCode *status) {
229350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(U_FAILURE(*status)) return;
229450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    *status = U_UNSUPPORTED_ERROR;
229550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return;
229650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
229750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
229850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
2299b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoU_INTERNAL UVoidFunction* U_EXPORT2
2300b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehouprv_dlsym_func(void *lib, const char* sym, UErrorCode *status) {
2301b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  if(U_SUCCESS(*status)) {
230250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    *status = U_UNSUPPORTED_ERROR;
2303b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  }
2304b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  return (UVoidFunction*)NULL;
230550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
230650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
230750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif /* U_ENABLE_DYLOAD */
230850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
2309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
2310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Hey, Emacs, please set the following:
2311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *
2312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Local Variables:
2313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * indent-tabs-mode: nil
2314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * End:
2315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *
2316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
2317