summaryrefslogtreecommitdiff
path: root/Build/source/libs/icu/icu-50.1/common
diff options
context:
space:
mode:
authorPeter Breitenlohner <peb@mppmu.mpg.de>2012-10-26 09:04:38 +0000
committerPeter Breitenlohner <peb@mppmu.mpg.de>2012-10-26 09:04:38 +0000
commiteffd22637d8ee3d67c2ad86c64ac942f24fef362 (patch)
tree46653b040c3dcab9dddf2395715d229808b5e0e9 /Build/source/libs/icu/icu-50.1/common
parent74cc05c672add53f566ac385f117008e8c4b3eda (diff)
icu 50.1 (50_rc): Add the missing new files
git-svn-id: svn://tug.org/texlive/trunk@28088 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/libs/icu/icu-50.1/common')
-rw-r--r--Build/source/libs/icu/icu-50.1/common/dictionarydata.cpp228
-rw-r--r--Build/source/libs/icu/icu-50.1/common/dictionarydata.h165
-rw-r--r--Build/source/libs/icu/icu-50.1/common/listformatter.cpp325
-rw-r--r--Build/source/libs/icu/icu-50.1/common/umutex.cpp483
-rw-r--r--Build/source/libs/icu/icu-50.1/common/unicode/listformatter.h134
-rw-r--r--Build/source/libs/icu/icu-50.1/common/utypeinfo.h27
6 files changed, 1362 insertions, 0 deletions
diff --git a/Build/source/libs/icu/icu-50.1/common/dictionarydata.cpp b/Build/source/libs/icu/icu-50.1/common/dictionarydata.cpp
new file mode 100644
index 00000000000..cc845425c33
--- /dev/null
+++ b/Build/source/libs/icu/icu-50.1/common/dictionarydata.cpp
@@ -0,0 +1,228 @@
+/*
+*******************************************************************************
+* Copyright (C) 2012, International Business Machines
+* Corporation and others. All Rights Reserved.
+*******************************************************************************
+* dictionarydata.h
+*
+* created on: 2012may31
+* created by: Markus W. Scherer & Maxime Serrano
+*/
+
+#include "dictionarydata.h"
+#include "unicode/ucharstrie.h"
+#include "unicode/bytestrie.h"
+#include "unicode/udata.h"
+#include "cmemory.h"
+
+#if !UCONFIG_NO_BREAK_ITERATION
+
+U_NAMESPACE_BEGIN
+
+#ifndef CYGWINMSVC /* On Cygwin/MSVC, the error redefinition of symbols occurs.*/
+const int32_t DictionaryData::TRIE_TYPE_BYTES;
+const int32_t DictionaryData::TRIE_TYPE_UCHARS;
+#endif
+
+DictionaryMatcher::~DictionaryMatcher() {
+}
+
+UCharsDictionaryMatcher::~UCharsDictionaryMatcher() {
+ udata_close(file);
+}
+
+int32_t UCharsDictionaryMatcher::getType() const {
+ return DictionaryData::TRIE_TYPE_UCHARS;
+}
+
+int32_t UCharsDictionaryMatcher::matches(UText *text, int32_t maxLength, int *lengths, int &count, int limit, int32_t *values) const {
+ UCharsTrie uct(characters);
+ UChar32 c = utext_next32(text);
+ if (c < 0) {
+ return 0;
+ }
+ UStringTrieResult result = uct.first(c);
+ int32_t numChars = 1;
+ count = 0;
+ for (;;) {
+ if (USTRINGTRIE_HAS_VALUE(result)) {
+ if (count < limit) {
+ if (values != NULL) {
+ values[count] = uct.getValue();
+ }
+ lengths[count++] = numChars;
+ }
+ if (result == USTRINGTRIE_FINAL_VALUE) {
+ break;
+ }
+ }
+ else if (result == USTRINGTRIE_NO_MATCH) {
+ break;
+ }
+
+ // TODO: why do we have a text limit if the UText knows its length?
+ if (numChars >= maxLength) {
+ break;
+ }
+
+ c = utext_next32(text);
+ if (c < 0) {
+ break;
+ }
+ ++numChars;
+ result = uct.next(c);
+ }
+ return numChars;
+}
+
+BytesDictionaryMatcher::~BytesDictionaryMatcher() {
+ udata_close(file);
+}
+
+UChar32 BytesDictionaryMatcher::transform(UChar32 c) const {
+ if ((transformConstant & DictionaryData::TRANSFORM_TYPE_MASK) == DictionaryData::TRANSFORM_TYPE_OFFSET) {
+ if (c == 0x200D) {
+ return 0xFF;
+ } else if (c == 0x200C) {
+ return 0xFE;
+ }
+ int32_t delta = c - (transformConstant & DictionaryData::TRANSFORM_OFFSET_MASK);
+ if (delta < 0 || 0xFD < delta) {
+ return U_SENTINEL;
+ }
+ return (UChar32)delta;
+ }
+ return c;
+}
+
+int32_t BytesDictionaryMatcher::getType() const {
+ return DictionaryData::TRIE_TYPE_BYTES;
+}
+
+int32_t BytesDictionaryMatcher::matches(UText *text, int32_t maxLength, int *lengths, int &count, int limit, int32_t *values) const {
+ BytesTrie bt(characters);
+ UChar32 c = utext_next32(text);
+ if (c < 0) {
+ return 0;
+ }
+ UStringTrieResult result = bt.first(transform(c));
+ int32_t numChars = 1;
+ count = 0;
+ for (;;) {
+ if (USTRINGTRIE_HAS_VALUE(result)) {
+ if (count < limit) {
+ if (values != NULL) {
+ values[count] = bt.getValue();
+ }
+ lengths[count++] = numChars;
+ }
+ if (result == USTRINGTRIE_FINAL_VALUE) {
+ break;
+ }
+ }
+ else if (result == USTRINGTRIE_NO_MATCH) {
+ break;
+ }
+
+ // TODO: why do we have a text limit if the UText knows its length?
+ if (numChars >= maxLength) {
+ break;
+ }
+
+ c = utext_next32(text);
+ if (c < 0) {
+ break;
+ }
+ ++numChars;
+ result = bt.next(transform(c));
+ }
+ return numChars;
+}
+
+
+U_NAMESPACE_END
+
+U_NAMESPACE_USE
+
+U_CAPI int32_t U_EXPORT2
+udict_swap(const UDataSwapper *ds, const void *inData, int32_t length,
+ void *outData, UErrorCode *pErrorCode) {
+ const UDataInfo *pInfo;
+ int32_t headerSize;
+ const uint8_t *inBytes;
+ uint8_t *outBytes;
+ const int32_t *inIndexes;
+ int32_t indexes[DictionaryData::IX_COUNT];
+ int32_t i, offset, size;
+
+ headerSize = udata_swapDataHeader(ds, inData, length, outData, pErrorCode);
+ if (pErrorCode == NULL || U_FAILURE(*pErrorCode)) return 0;
+ pInfo = (const UDataInfo *)((const char *)inData + 4);
+ if (!(pInfo->dataFormat[0] == 0x44 &&
+ pInfo->dataFormat[1] == 0x69 &&
+ pInfo->dataFormat[2] == 0x63 &&
+ pInfo->dataFormat[3] == 0x74 &&
+ pInfo->formatVersion[0] == 1)) {
+ udata_printError(ds, "udict_swap(): data format %02x.%02x.%02x.%02x (format version %02x) is not recognized as dictionary data\n",
+ pInfo->dataFormat[0], pInfo->dataFormat[1], pInfo->dataFormat[2], pInfo->dataFormat[3], pInfo->formatVersion[0]);
+ *pErrorCode = U_UNSUPPORTED_ERROR;
+ return 0;
+ }
+
+ inBytes = (const uint8_t *)inData + headerSize;
+ outBytes = (uint8_t *)outData + headerSize;
+
+ inIndexes = (const int32_t *)inBytes;
+ if (length >= 0) {
+ length -= headerSize;
+ if (length < (int32_t)(sizeof(indexes))) {
+ udata_printError(ds, "udict_swap(): too few bytes (%d after header) for dictionary data\n", length);
+ *pErrorCode = U_INDEX_OUTOFBOUNDS_ERROR;
+ return 0;
+ }
+ }
+
+ for (i = 0; i < DictionaryData::IX_COUNT; i++) {
+ indexes[i] = udata_readInt32(ds, inIndexes[i]);
+ }
+
+ size = indexes[DictionaryData::IX_TOTAL_SIZE];
+
+ if (length >= 0) {
+ if (length < size) {
+ udata_printError(ds, "udict_swap(): too few bytes (%d after header) for all of dictionary data\n", length);
+ *pErrorCode = U_INDEX_OUTOFBOUNDS_ERROR;
+ return 0;
+ }
+
+ if (inBytes != outBytes) {
+ uprv_memcpy(outBytes, inBytes, size);
+ }
+
+ offset = 0;
+ ds->swapArray32(ds, inBytes, sizeof(indexes), outBytes, pErrorCode);
+ offset = (int32_t)sizeof(indexes);
+ int32_t trieType = indexes[DictionaryData::IX_TRIE_TYPE] & DictionaryData::TRIE_TYPE_MASK;
+ int32_t nextOffset = indexes[DictionaryData::IX_RESERVED1_OFFSET];
+
+ if (trieType == DictionaryData::TRIE_TYPE_UCHARS) {
+ ds->swapArray16(ds, inBytes + offset, nextOffset - offset, outBytes + offset, pErrorCode);
+ } else if (trieType == DictionaryData::TRIE_TYPE_BYTES) {
+ // nothing to do
+ } else {
+ udata_printError(ds, "udict_swap(): unknown trie type!\n");
+ *pErrorCode = U_UNSUPPORTED_ERROR;
+ return 0;
+ }
+
+ // these next two sections are empty in the current format,
+ // but may be used later.
+ offset = nextOffset;
+ nextOffset = indexes[DictionaryData::IX_RESERVED2_OFFSET];
+ offset = nextOffset;
+ nextOffset = indexes[DictionaryData::IX_TOTAL_SIZE];
+ offset = nextOffset;
+ }
+ return headerSize + size;
+}
+#endif
diff --git a/Build/source/libs/icu/icu-50.1/common/dictionarydata.h b/Build/source/libs/icu/icu-50.1/common/dictionarydata.h
new file mode 100644
index 00000000000..eedc926fa09
--- /dev/null
+++ b/Build/source/libs/icu/icu-50.1/common/dictionarydata.h
@@ -0,0 +1,165 @@
+/*
+*******************************************************************************
+* Copyright (C) 2012, International Business Machines
+* Corporation and others. All Rights Reserved.
+*******************************************************************************
+* dictionarydata.h
+*
+* created on: 2012may31
+* created by: Markus W. Scherer & Maxime Serrano
+*/
+
+#ifndef __DICTIONARYDATA_H__
+#define __DICTIONARYDATA_H__
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_BREAK_ITERATION
+
+#include "unicode/utext.h"
+#include "unicode/udata.h"
+#include "udataswp.h"
+#include "unicode/uobject.h"
+#include "unicode/ustringtrie.h"
+
+U_NAMESPACE_BEGIN
+
+class UCharsTrie;
+class BytesTrie;
+
+class U_COMMON_API DictionaryData : public UMemory {
+public:
+ static const int32_t TRIE_TYPE_BYTES = 0;
+ static const int32_t TRIE_TYPE_UCHARS = 1;
+ static const int32_t TRIE_TYPE_MASK = 7;
+ static const int32_t TRIE_HAS_VALUES = 8;
+
+ static const int32_t TRANSFORM_NONE = 0;
+ static const int32_t TRANSFORM_TYPE_OFFSET = 0x1000000;
+ static const int32_t TRANSFORM_TYPE_MASK = 0x7f000000;
+ static const int32_t TRANSFORM_OFFSET_MASK = 0x1fffff;
+
+ enum {
+ // Byte offsets from the start of the data, after the generic header.
+ IX_STRING_TRIE_OFFSET,
+ IX_RESERVED1_OFFSET,
+ IX_RESERVED2_OFFSET,
+ IX_TOTAL_SIZE,
+
+ // Trie type: TRIE_HAS_VALUES | TRIE_TYPE_BYTES etc.
+ IX_TRIE_TYPE,
+ // Transform specification: TRANSFORM_TYPE_OFFSET | 0xe00 etc.
+ IX_TRANSFORM,
+
+ IX_RESERVED6,
+ IX_RESERVED7,
+ IX_COUNT
+ };
+};
+
+/**
+ * Wrapper class around generic dictionaries, implementing matches().
+ * getType() should return a TRIE_TYPE_??? constant from DictionaryData.
+ *
+ * All implementations of this interface must be thread-safe if they are to be used inside of the
+ * dictionary-based break iteration code.
+ */
+class U_COMMON_API DictionaryMatcher : public UMemory {
+public:
+ virtual ~DictionaryMatcher();
+ // this should emulate CompactTrieDictionary::matches()
+ virtual int32_t matches(UText *text, int32_t maxLength, int32_t *lengths, int &count,
+ int limit, int32_t *values = NULL) const = 0;
+ /** @return DictionaryData::TRIE_TYPE_XYZ */
+ virtual int32_t getType() const = 0;
+};
+
+// Implementation of the DictionaryMatcher interface for a UCharsTrie dictionary
+class U_COMMON_API UCharsDictionaryMatcher : public DictionaryMatcher {
+public:
+ // constructs a new UCharsDictionaryMatcher.
+ // The UDataMemory * will be closed on this object's destruction.
+ UCharsDictionaryMatcher(const UChar *c, UDataMemory *f) : characters(c), file(f) { }
+ virtual ~UCharsDictionaryMatcher();
+ virtual int32_t matches(UText *text, int32_t maxLength, int32_t *lengths, int &count,
+ int limit, int32_t *values = NULL) const;
+ virtual int32_t getType() const;
+private:
+ const UChar *characters;
+ UDataMemory *file;
+};
+
+// Implementation of the DictionaryMatcher interface for a BytesTrie dictionary
+class U_COMMON_API BytesDictionaryMatcher : public DictionaryMatcher {
+public:
+ // constructs a new BytesTrieDictionaryMatcher
+ // the transform constant should be the constant read from the file, not a masked version!
+ // the UDataMemory * fed in here will be closed on this object's destruction
+ BytesDictionaryMatcher(const char *c, int32_t t, UDataMemory *f)
+ : characters(c), transformConstant(t), file(f) { }
+ virtual ~BytesDictionaryMatcher();
+ virtual int32_t matches(UText *text, int32_t maxLength, int32_t *lengths, int &count,
+ int limit, int32_t *values = NULL) const;
+ virtual int32_t getType() const;
+private:
+ UChar32 transform(UChar32 c) const;
+
+ const char *characters;
+ int32_t transformConstant;
+ UDataMemory *file;
+};
+
+U_NAMESPACE_END
+
+U_CAPI int32_t U_EXPORT2
+udict_swap(const UDataSwapper *ds, const void *inData, int32_t length, void *outData, UErrorCode *pErrorCode);
+
+/**
+ * Format of dictionary .dict data files.
+ * Format version 1.0.
+ *
+ * A dictionary .dict data file contains a byte-serialized BytesTrie or
+ * a UChars-serialized UCharsTrie.
+ * Such files are used in dictionary-based break iteration (DBBI).
+ *
+ * For a BytesTrie, a transformation type is specified for
+ * transforming Unicode strings into byte sequences.
+ *
+ * A .dict file begins with a standard ICU data file header
+ * (DataHeader, see ucmndata.h and unicode/udata.h).
+ * The UDataInfo.dataVersion field is currently unused (set to 0.0.0.0).
+ *
+ * After the header, the file contains the following parts.
+ * Constants are defined in the DictionaryData class.
+ *
+ * For the data structure of BytesTrie & UCharsTrie see
+ * http://site.icu-project.org/design/struct/tries
+ * and the bytestrie.h and ucharstrie.h header files.
+ *
+ * int32_t indexes[indexesLength]; -- indexesLength=indexes[IX_STRING_TRIE_OFFSET]/4;
+ *
+ * The first four indexes are byte offsets in ascending order.
+ * Each byte offset marks the start of the next part in the data file,
+ * and the end of the previous one.
+ * When two consecutive byte offsets are the same, then the corresponding part is empty.
+ * Byte offsets are offsets from after the header,
+ * that is, from the beginning of the indexes[].
+ * Each part starts at an offset with proper alignment for its data.
+ * If necessary, the previous part may include padding bytes to achieve this alignment.
+ *
+ * trieType=indexes[IX_TRIE_TYPE] defines the trie type.
+ * transform=indexes[IX_TRANSFORM] defines the Unicode-to-bytes transformation.
+ * If the transformation type is TRANSFORM_TYPE_OFFSET,
+ * then the lower 21 bits contain the offset code point.
+ * Each code point c is mapped to byte b = (c - offset).
+ * Code points outside the range offset..(offset+0xff) cannot be mapped
+ * and do not occur in the dictionary.
+ *
+ * stringTrie; -- a serialized BytesTrie or UCharsTrie
+ *
+ * The dictionary maps strings to specific values (TRIE_HAS_VALUES bit set in trieType),
+ * or it maps all strings to 0 (TRIE_HAS_VALUES bit not set).
+ */
+
+#endif /* !UCONFIG_NO_BREAK_ITERATION */
+#endif /* __DICTIONARYDATA_H__ */
diff --git a/Build/source/libs/icu/icu-50.1/common/listformatter.cpp b/Build/source/libs/icu/icu-50.1/common/listformatter.cpp
new file mode 100644
index 00000000000..6a6e986377d
--- /dev/null
+++ b/Build/source/libs/icu/icu-50.1/common/listformatter.cpp
@@ -0,0 +1,325 @@
+/*
+*******************************************************************************
+*
+* Copyright (C) 2012, International Business Machines
+* Corporation and others. All Rights Reserved.
+*
+*******************************************************************************
+* file name: listformatter.cpp
+* encoding: US-ASCII
+* tab size: 8 (not used)
+* indentation:4
+*
+* created on: 2012aug27
+* created by: Umesh P. Nair
+*/
+
+#include "unicode/listformatter.h"
+#include "mutex.h"
+#include "hash.h"
+#include "cstring.h"
+#include "ulocimp.h"
+#include "charstr.h"
+#include "ucln_cmn.h"
+
+U_NAMESPACE_BEGIN
+
+static Hashtable* listPatternHash = NULL;
+static UMutex listFormatterMutex = U_MUTEX_INITIALIZER;
+static UChar FIRST_PARAMETER[] = { 0x7b, 0x30, 0x7d }; // "{0}"
+static UChar SECOND_PARAMETER[] = { 0x7b, 0x31, 0x7d }; // "{0}"
+
+U_CDECL_BEGIN
+static UBool U_CALLCONV uprv_listformatter_cleanup() {
+ delete listPatternHash;
+ listPatternHash = NULL;
+ return TRUE;
+}
+
+static void U_CALLCONV
+uprv_deleteListFormatData(void *obj) {
+ delete static_cast<ListFormatData *>(obj);
+}
+
+U_CDECL_END
+
+void ListFormatter::initializeHash(UErrorCode& errorCode) {
+ if (U_FAILURE(errorCode)) {
+ return;
+ }
+
+ listPatternHash = new Hashtable();
+ if (listPatternHash == NULL) {
+ errorCode = U_MEMORY_ALLOCATION_ERROR;
+ return;
+ }
+
+ listPatternHash->setValueDeleter(uprv_deleteListFormatData);
+ ucln_common_registerCleanup(UCLN_COMMON_LIST_FORMATTER, uprv_listformatter_cleanup);
+
+ addDataToHash("af", "{0} en {1}", "{0}, {1}", "{0}, {1}", "{0} en {1}", errorCode);
+ addDataToHash("am", "{0} \\u12a5\\u1293 {1}", "{0}, {1}", "{0}, {1}", "{0}, \\u12a5\\u1293 {1}", errorCode);
+ addDataToHash("ar", "{0} \\u0648 {1}", "{0}\\u060c {1}", "{0}\\u060c {1}", "{0}\\u060c \\u0648 {1}", errorCode);
+ addDataToHash("bg", "{0} \\u0438 {1}", "{0}, {1}", "{0}, {1}", "{0} \\u0438 {1}", errorCode);
+ addDataToHash("bn", "{0} \\u098f\\u09ac\\u0982 {1}", "{0}, {1}", "{0}, {1}", "{0}, \\u098f\\u09ac\\u0982 {1}", errorCode);
+ addDataToHash("bs", "{0} i {1}", "{0}, {1}", "{0}, {1}", "{0} i {1}", errorCode);
+ addDataToHash("ca", "{0} i {1}", "{0}, {1}", "{0}, {1}", "{0} i {1}", errorCode);
+ addDataToHash("cs", "{0} a {1}", "{0}, {1}", "{0}, {1}", "{0} a {1}", errorCode);
+ addDataToHash("da", "{0} og {1}", "{0}, {1}", "{0}, {1}", "{0} og {1}", errorCode);
+ addDataToHash("de", "{0} und {1}", "{0}, {1}", "{0}, {1}", "{0} und {1}", errorCode);
+ addDataToHash("ee", "{0} kple {1}", "{0}, {1}", "{0}, {1}", "{0}, kple {1}", errorCode);
+ addDataToHash("el", "{0} \\u03ba\\u03b1\\u03b9 {1}", "{0}, {1}", "{0}, {1}", "{0} \\u03ba\\u03b1\\u03b9 {1}", errorCode);
+ addDataToHash("en", "{0} and {1}", "{0}, {1}", "{0}, {1}", "{0}, and {1}", errorCode);
+ addDataToHash("es", "{0} y {1}", "{0}, {1}", "{0}, {1}", "{0} y {1}", errorCode);
+ addDataToHash("et", "{0} ja {1}", "{0}, {1}", "{0}, {1}", "{0} ja {1}", errorCode);
+ addDataToHash("eu", "{0} eta {1}", "{0}, {1}", "{0}, {1}", "{0} eta {1}", errorCode);
+ addDataToHash("fa", "{0} \\u0648 {1}", "{0}\\u060c\\u200f {1}", "{0}\\u060c\\u200f {1}", "{0}\\u060c \\u0648 {1}", errorCode);
+ addDataToHash("fi", "{0} ja {1}", "{0}, {1}", "{0}, {1}", "{0} ja {1}", errorCode);
+ addDataToHash("fil", "{0} at {1}", "{0}, {1}", "{0}, {1}", "{0} at {1}", errorCode);
+ addDataToHash("fo", "{0} og {1}", "{0}, {1}", "{0}, {1}", "{0} og {1}", errorCode);
+ addDataToHash("fr", "{0} et {1}", "{0}, {1}", "{0}, {1}", "{0} et {1}", errorCode);
+ addDataToHash("fur", "{0} e {1}", "{0}, {1}", "{0}, {1}", "{0} e {1}", errorCode);
+ addDataToHash("gd", "{0} agus {1}", "{0}, {1}", "{0}, {1}", "{0}, agus {1}", errorCode);
+ addDataToHash("gl", "{0} e {1}", "{0}, {1}", "{0}, {1}", "{0} e {1}", errorCode);
+ addDataToHash("gsw", "{0} und {1}", "{0}, {1}", "{0}, {1}", "{0} und {1}", errorCode);
+ addDataToHash("gu", "{0} \\u0a85\\u0aa8\\u0ac7 {1}", "{0}, {1}", "{0}, {1}", "{0} \\u0a85\\u0aa8\\u0ac7 {1}", errorCode);
+ addDataToHash("he", "{0} \\u05d5-{1}", "{0}, {1}", "{0}, {1}", "{0} \\u05d5-{1}", errorCode);
+ addDataToHash("hi", "{0} \\u0914\\u0930 {1}", "{0}, {1}", "{0}, {1}", "{0}, \\u0914\\u0930 {1}", errorCode);
+ addDataToHash("hr", "{0} i {1}", "{0}, {1}", "{0}, {1}", "{0} i {1}", errorCode);
+ addDataToHash("hu", "{0} \\u00e9s {1}", "{0}, {1}", "{0}, {1}", "{0} \\u00e9s {1}", errorCode);
+ addDataToHash("id", "{0} dan {1}", "{0}, {1}", "{0}, {1}", "{0}, dan {1}", errorCode);
+ addDataToHash("is", "{0} og {1}", "{0}, {1}", "{0}, {1}", "{0} og {1}", errorCode);
+ addDataToHash("it", "{0} e {1}", "{0}, {1}", "{0}, {1}", "{0}, e {1}", errorCode);
+ addDataToHash("ja", "{0}\\u3001{1}", "{0}\\u3001{1}", "{0}\\u3001{1}", "{0}\\u3001{1}", errorCode);
+ addDataToHash("ka", "{0} \\u10d3\\u10d0 {1}", "{0}, {1}", "{0}, {1}", "{0} \\u10d3\\u10d0 {1}", errorCode);
+ addDataToHash("kea", "{0} y {1}", "{0}, {1}", "{0}, {1}", "{0} y {1}", errorCode);
+ addDataToHash("kl", "{0} aamma {1}", "{0} aamma {1}", "{0}, {1}", "{0}, {1}", errorCode);
+ addDataToHash("kn", "{0} \\u0cae\\u0ca4\\u0ccd\\u0ca4\\u0cc1 {1}", "{0}, {1}", "{0}, {1}",
+ "{0}, \\u0cae\\u0ca4\\u0ccd\\u0ca4\\u0cc1 {1}", errorCode);
+ addDataToHash("ko", "{0} \\ubc0f {1}", "{0}, {1}", "{0}, {1}", "{0} \\ubc0f {1}", errorCode);
+ addDataToHash("ksh", "{0} un {1}", "{0}, {1}", "{0}, {1}", "{0} un {1}", errorCode);
+ addDataToHash("lt", "{0} ir {1}", "{0}, {1}", "{0}, {1}", "{0} ir {1}", errorCode);
+ addDataToHash("lv", "{0} un {1}", "{0}, {1}", "{0}, {1}", "{0} un {1}", errorCode);
+ addDataToHash("ml", "{0} \\u0d15\\u0d42\\u0d1f\\u0d3e\\u0d24\\u0d46 {1}", "{0}, {1}", "{0}, {1}",
+ "{0}, {1} \\u0d0e\\u0d28\\u0d4d\\u0d28\\u0d3f\\u0d35", errorCode);
+ addDataToHash("mr", "{0} \\u0906\\u0923\\u093f {1}", "{0}, {1}", "{0}, {1}", "{0} \\u0906\\u0923\\u093f {1}", errorCode);
+ addDataToHash("ms", "{0} dan {1}", "{0}, {1}", "{0}, {1}", "{0}, dan {1}", errorCode);
+ addDataToHash("nb", "{0} og {1}", "{0}, {1}", "{0}, {1}", "{0} og {1}", errorCode);
+ addDataToHash("nl", "{0} en {1}", "{0}, {1}", "{0}, {1}", "{0} en {1}", errorCode);
+ addDataToHash("nn", "{0} og {1}", "{0}, {1}", "{0}, {1}", "{0} og {1}", errorCode);
+ addDataToHash("pl", "{0} i {1}", "{0}; {1}", "{0}; {1}", "{0} i {1}", errorCode);
+ addDataToHash("pt", "{0} e {1}", "{0}, {1}", "{0}, {1}", "{0} e {1}", errorCode);
+ addDataToHash("ro", "{0} \\u015fi {1}", "{0}, {1}", "{0}, {1}", "{0} \\u015fi {1}", errorCode);
+ addDataToHash("", "{0}, {1}", "{0}, {1}", "{0}, {1}", "{0}, {1}", errorCode); // root
+ addDataToHash("ru", "{0} \\u0438 {1}", "{0}, {1}", "{0}, {1}", "{0} \\u0438 {1}", errorCode);
+ addDataToHash("se", "{0} ja {1}", "{0}, {1}", "{0}, {1}", "{0} ja {1}", errorCode);
+ addDataToHash("sk", "{0} a {1}", "{0}, {1}", "{0}, {1}", "{0} a {1}", errorCode);
+ addDataToHash("sl", "{0} in {1}", "{0}, {1}", "{0}, {1}", "{0} in {1}", errorCode);
+ addDataToHash("sr", "{0} \\u0438 {1}", "{0}, {1}", "{0}, {1}", "{0} \\u0438 {1}", errorCode);
+ addDataToHash("sr_Cyrl", "{0} \\u0438 {1}", "{0}, {1}", "{0}, {1}", "{0} \\u0438 {1}", errorCode);
+ addDataToHash("sr_Latn", "{0} i {1}", "{0}, {1}", "{0}, {1}", "{0} i {1}", errorCode);
+ addDataToHash("sv", "{0} och {1}", "{0}, {1}", "{0}, {1}", "{0} och {1}", errorCode);
+ addDataToHash("sw", "{0} na {1}", "{0}, {1}", "{0}, {1}", "{0}, na {1}", errorCode);
+ addDataToHash("ta", "{0} \\u0bae\\u0bb1\\u0bcd\\u0bb1\\u0bc1\\u0bae\\u0bcd {1}", "{0}, {1}", "{0}, {1}",
+ "{0} \\u0bae\\u0bb1\\u0bcd\\u0bb1\\u0bc1\\u0bae\\u0bcd {1}", errorCode);
+ addDataToHash("te", "{0} \\u0c2e\\u0c30\\u0c3f\\u0c2f\\u0c41 {1}", "{0}, {1}", "{0}, {1}",
+ "{0} \\u0c2e\\u0c30\\u0c3f\\u0c2f\\u0c41 {1}", errorCode);
+ addDataToHash("th", "{0}\\u0e41\\u0e25\\u0e30{1}", "{0} {1}", "{0} {1}", "{0} \\u0e41\\u0e25\\u0e30{1}", errorCode);
+ addDataToHash("tr", "{0} ve {1}", "{0}, {1}", "{0}, {1}", "{0} ve {1}", errorCode);
+ addDataToHash("uk", "{0} \\u0442\\u0430 {1}", "{0}, {1}", "{0}, {1}", "{0} \\u0442\\u0430 {1}", errorCode);
+ addDataToHash("ur", "{0} \\u0627\\u0648\\u0631 {1}", "{0}\\u060c {1}", "{0}\\u060c {1}",
+ "{0}\\u060c \\u0627\\u0648\\u0631 {1}", errorCode);
+ addDataToHash("vi", "{0} v\\u00e0 {1}", "{0}, {1}", "{0}, {1}", "{0} v\\u00e0 {1}", errorCode);
+ addDataToHash("wae", "{0} und {1}", "{0}, {1}", "{0}, {1}", "{0} und {1}", errorCode);
+ addDataToHash("zh", "{0}\\u548c{1}", "{0}\\u3001{1}", "{0}\\u3001{1}", "{0}\\u548c{1}", errorCode);
+ addDataToHash("zu", "I-{0} ne-{1}", "{0}, {1}", "{0}, {1}", "{0}, no-{1}", errorCode);
+}
+
+void ListFormatter::addDataToHash(
+ const char* locale,
+ const char* two,
+ const char* start,
+ const char* middle,
+ const char* end,
+ UErrorCode& errorCode) {
+ if (U_FAILURE(errorCode)) {
+ return;
+ }
+ UnicodeString key(locale, -1, US_INV);
+ ListFormatData* value = new ListFormatData(
+ UnicodeString(two, -1, US_INV).unescape(),
+ UnicodeString(start, -1, US_INV).unescape(),
+ UnicodeString(middle, -1, US_INV).unescape(),
+ UnicodeString(end, -1, US_INV).unescape());
+
+ if (value == NULL) {
+ errorCode = U_MEMORY_ALLOCATION_ERROR;
+ return;
+ }
+ listPatternHash->put(key, value, errorCode);
+}
+
+const ListFormatData* ListFormatter::getListFormatData(
+ const Locale& locale, UErrorCode& errorCode) {
+ if (U_FAILURE(errorCode)) {
+ return NULL;
+ }
+ {
+ Mutex m(&listFormatterMutex);
+ if (listPatternHash == NULL) {
+ initializeHash(errorCode);
+ if (U_FAILURE(errorCode)) {
+ return NULL;
+ }
+ }
+ }
+
+ UnicodeString key(locale.getName(), -1, US_INV);
+ return static_cast<const ListFormatData*>(listPatternHash->get(key));
+}
+
+ListFormatter* ListFormatter::createInstance(UErrorCode& errorCode) {
+ Locale locale; // The default locale.
+ return createInstance(locale, errorCode);
+}
+
+ListFormatter* ListFormatter::createInstance(const Locale& locale, UErrorCode& errorCode) {
+ Locale tempLocale = locale;
+ for (;;) {
+ const ListFormatData* listFormatData = getListFormatData(tempLocale, errorCode);
+ if (U_FAILURE(errorCode)) {
+ return NULL;
+ }
+ if (listFormatData != NULL) {
+ ListFormatter* p = new ListFormatter(*listFormatData);
+ if (p == NULL) {
+ errorCode = U_MEMORY_ALLOCATION_ERROR;
+ return NULL;
+ }
+ return p;
+ }
+ errorCode = U_ZERO_ERROR;
+ Locale correctLocale;
+ getFallbackLocale(tempLocale, correctLocale, errorCode);
+ if (U_FAILURE(errorCode)) {
+ return NULL;
+ }
+ if (correctLocale.isBogus()) {
+ return createInstance(Locale::getRoot(), errorCode);
+ }
+ tempLocale = correctLocale;
+ }
+}
+
+ListFormatter::ListFormatter(const ListFormatData& listFormatterData) : data(listFormatterData) {
+}
+
+ListFormatter::~ListFormatter() {}
+
+void ListFormatter::getFallbackLocale(const Locale& in, Locale& out, UErrorCode& errorCode) {
+ if (uprv_strcmp(in.getName(), "zh_TW") == 0) {
+ out = Locale::getTraditionalChinese();
+ } else {
+ const char* localeString = in.getName();
+ const char* extStart = locale_getKeywordsStart(localeString);
+ if (extStart == NULL) {
+ extStart = uprv_strchr(localeString, 0);
+ }
+ const char* last = extStart;
+
+ // TODO: Check whether uloc_getParent() will work here.
+ while (last > localeString && *(last - 1) != '_') {
+ --last;
+ }
+
+ // Truncate empty segment.
+ while (last > localeString) {
+ if (*(last-1) != '_') {
+ break;
+ }
+ --last;
+ }
+
+ size_t localePortionLen = last - localeString;
+ CharString fullLocale;
+ fullLocale.append(localeString, localePortionLen, errorCode).append(extStart, errorCode);
+
+ if (U_FAILURE(errorCode)) {
+ return;
+ }
+ out = Locale(fullLocale.data());
+ }
+}
+
+UnicodeString& ListFormatter::format(const UnicodeString items[], int32_t nItems,
+ UnicodeString& appendTo, UErrorCode& errorCode) const {
+ if (U_FAILURE(errorCode)) {
+ return appendTo;
+ }
+
+ if (nItems > 0) {
+ UnicodeString newString = items[0];
+ if (nItems == 2) {
+ addNewString(data.twoPattern, newString, items[1], errorCode);
+ } else if (nItems > 2) {
+ addNewString(data.startPattern, newString, items[1], errorCode);
+ int i;
+ for (i = 2; i < nItems - 1; ++i) {
+ addNewString(data.middlePattern, newString, items[i], errorCode);
+ }
+ addNewString(data.endPattern, newString, items[nItems - 1], errorCode);
+ }
+ if (U_SUCCESS(errorCode)) {
+ appendTo += newString;
+ }
+ }
+ return appendTo;
+}
+
+/**
+ * Joins originalString and nextString using the pattern pat and puts the result in
+ * originalString.
+ */
+void ListFormatter::addNewString(const UnicodeString& pat, UnicodeString& originalString,
+ const UnicodeString& nextString, UErrorCode& errorCode) const {
+ if (U_FAILURE(errorCode)) {
+ return;
+ }
+
+ int32_t p0Offset = pat.indexOf(FIRST_PARAMETER, 3, 0);
+ if (p0Offset < 0) {
+ errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+ return;
+ }
+ int32_t p1Offset = pat.indexOf(SECOND_PARAMETER, 3, 0);
+ if (p1Offset < 0) {
+ errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+ return;
+ }
+
+ int32_t i, j;
+
+ const UnicodeString* firstString;
+ const UnicodeString* secondString;
+ if (p0Offset < p1Offset) {
+ i = p0Offset;
+ j = p1Offset;
+ firstString = &originalString;
+ secondString = &nextString;
+ } else {
+ i = p1Offset;
+ j = p0Offset;
+ firstString = &nextString;
+ secondString = &originalString;
+ }
+
+ UnicodeString result = UnicodeString(pat, 0, i) + *firstString;
+ result += UnicodeString(pat, i+3, j-i-3);
+ result += *secondString;
+ result += UnicodeString(pat, j+3);
+ originalString = result;
+}
+
+UOBJECT_DEFINE_NO_RTTI_IMPLEMENTATION(ListFormatter)
+
+U_NAMESPACE_END
diff --git a/Build/source/libs/icu/icu-50.1/common/umutex.cpp b/Build/source/libs/icu/icu-50.1/common/umutex.cpp
new file mode 100644
index 00000000000..a7299a5cfd1
--- /dev/null
+++ b/Build/source/libs/icu/icu-50.1/common/umutex.cpp
@@ -0,0 +1,483 @@
+/*
+******************************************************************************
+*
+* Copyright (C) 1997-2012, International Business Machines
+* Corporation and others. All Rights Reserved.
+*
+******************************************************************************
+*
+* File umutex.cpp
+*
+* Modification History:
+*
+* Date Name Description
+* 04/02/97 aliu Creation.
+* 04/07/99 srl updated
+* 05/13/99 stephen Changed to umutex (from cmutex).
+* 11/22/99 aliu Make non-global mutex autoinitialize [j151]
+******************************************************************************
+*/
+
+#include "unicode/utypes.h"
+#include "uassert.h"
+#include "ucln_cmn.h"
+
+/*
+ * ICU Mutex wrappers. Wrap operating system mutexes, giving the rest of ICU a
+ * platform independent set of mutex operations. For internal ICU use only.
+ */
+
+#if U_PLATFORM_HAS_WIN32_API
+ /* Prefer native Windows APIs even if POSIX is implemented (i.e., on Cygwin). */
+# undef POSIX
+#elif U_PLATFORM_IMPLEMENTS_POSIX
+# define POSIX
+#else
+# undef POSIX
+#endif
+
+#if defined(POSIX)
+# include <pthread.h> /* must be first, so that we get the multithread versions of things. */
+#endif /* POSIX */
+
+#if U_PLATFORM_HAS_WIN32_API
+# define WIN32_LEAN_AND_MEAN
+# define VC_EXTRALEAN
+# define NOUSER
+# define NOSERVICE
+# define NOIME
+# define NOMCX
+# include <windows.h>
+#endif
+
+#include "umutex.h"
+#include "cmemory.h"
+
+#if U_PLATFORM_HAS_WIN32_API
+#define SYNC_COMPARE_AND_SWAP(dest, oldval, newval) \
+ InterlockedCompareExchangePointer(dest, newval, oldval)
+
+#elif defined(POSIX)
+#if (U_HAVE_GCC_ATOMICS == 1)
+#define SYNC_COMPARE_AND_SWAP(dest, oldval, newval) \
+ __sync_val_compare_and_swap(dest, oldval, newval)
+#else
+#define SYNC_COMPARE_AND_SWAP(dest, oldval, newval) \
+ mutexed_compare_and_swap(dest, newval, oldval)
+#endif
+
+#else
+// Unknown platform. Note that user can still set mutex functions at run time.
+#define SYNC_COMPARE_AND_SWAP(dest, oldval, newval) \
+ mutexed_compare_and_swap(dest, newval, oldval)
+#endif
+
+static void *mutexed_compare_and_swap(void **dest, void *newval, void *oldval);
+
+// The ICU global mutex. Used when ICU implementation code passes NULL for the mutex pointer.
+static UMutex globalMutex = U_MUTEX_INITIALIZER;
+
+// Implementation mutex. Used for compare & swap when no intrinsic is available, and
+// for safe initialization of user defined mutexes.
+static UMutex implMutex = U_MUTEX_INITIALIZER;
+
+// List of all user mutexes that have been initialized.
+// Used to allow us to destroy them when cleaning up ICU.
+// Normal platform mutexes are not kept track of in this way - they survive until the process is shut down.
+// Normal platfrom mutexes don't allocate storage, so not cleaning them up won't trigger memory leak complaints.
+//
+// Note: putting this list in allocated memory would be awkward to arrange, because memory allocations
+// are used as a flag to indicate that ICU has been initialized, and setting other ICU
+// override functions will no longer work.
+//
+static const int MUTEX_LIST_LIMIT = 100;
+static UMutex *gMutexList[MUTEX_LIST_LIMIT];
+static int gMutexListSize = 0;
+
+
+/*
+ * User mutex implementation functions. If non-null, call back to these rather than
+ * directly using the system (Posix or Windows) APIs. See u_setMutexFunctions().
+ * (declarations are in uclean.h)
+ */
+static UMtxInitFn *pMutexInitFn = NULL;
+static UMtxFn *pMutexDestroyFn = NULL;
+static UMtxFn *pMutexLockFn = NULL;
+static UMtxFn *pMutexUnlockFn = NULL;
+static const void *gMutexContext = NULL;
+
+
+// Clean up (undo) the effects of u_setMutexFunctions().
+//
+static void usrMutexCleanup() {
+ if (pMutexDestroyFn != NULL) {
+ for (int i = 0; i < gMutexListSize; i++) {
+ UMutex *m = gMutexList[i];
+ U_ASSERT(m->fInitialized);
+ (*pMutexDestroyFn)(gMutexContext, &m->fUserMutex);
+ m->fInitialized = FALSE;
+ }
+ (*pMutexDestroyFn)(gMutexContext, &globalMutex.fUserMutex);
+ (*pMutexDestroyFn)(gMutexContext, &implMutex.fUserMutex);
+ }
+ gMutexListSize = 0;
+ pMutexInitFn = NULL;
+ pMutexDestroyFn = NULL;
+ pMutexLockFn = NULL;
+ pMutexUnlockFn = NULL;
+ gMutexContext = NULL;
+}
+
+
+/*
+ * User mutex lock.
+ *
+ * User mutexes need to be initialized before they can be used. We use the impl mutex
+ * to synchronize the initialization check. This could be sped up on platforms that
+ * support alternate ways to safely check the initialization flag.
+ *
+ */
+static void usrMutexLock(UMutex *mutex) {
+ UErrorCode status = U_ZERO_ERROR;
+ if (!(mutex == &implMutex || mutex == &globalMutex)) {
+ umtx_lock(&implMutex);
+ if (!mutex->fInitialized) {
+ (*pMutexInitFn)(gMutexContext, &mutex->fUserMutex, &status);
+ U_ASSERT(U_SUCCESS(status));
+ mutex->fInitialized = TRUE;
+ U_ASSERT(gMutexListSize < MUTEX_LIST_LIMIT);
+ if (gMutexListSize < MUTEX_LIST_LIMIT) {
+ gMutexList[gMutexListSize] = mutex;
+ ++gMutexListSize;
+ }
+ }
+ umtx_unlock(&implMutex);
+ }
+ (*pMutexLockFn)(gMutexContext, &mutex->fUserMutex);
+}
+
+
+
+#if defined(POSIX)
+
+//
+// POSIX implementation of UMutex.
+//
+// Each UMutex has a corresponding pthread_mutex_t.
+// All are statically initialized and ready for use.
+// There is no runtime mutex initialization code needed.
+
+U_CAPI void U_EXPORT2
+umtx_lock(UMutex *mutex) {
+ if (mutex == NULL) {
+ mutex = &globalMutex;
+ }
+ if (pMutexLockFn) {
+ usrMutexLock(mutex);
+ } else {
+ #if U_DEBUG
+ // #if to avoid unused variable warnings in non-debug builds.
+ int sysErr = pthread_mutex_lock(&mutex->fMutex);
+ U_ASSERT(sysErr == 0);
+ #else
+ pthread_mutex_lock(&mutex->fMutex);
+ #endif
+ }
+}
+
+
+U_CAPI void U_EXPORT2
+umtx_unlock(UMutex* mutex)
+{
+ if (mutex == NULL) {
+ mutex = &globalMutex;
+ }
+ if (pMutexUnlockFn) {
+ (*pMutexUnlockFn)(gMutexContext, &mutex->fUserMutex);
+ } else {
+ #if U_DEBUG
+ // #if to avoid unused variable warnings in non-debug builds.
+ int sysErr = pthread_mutex_unlock(&mutex->fMutex);
+ U_ASSERT(sysErr == 0);
+ #else
+ pthread_mutex_unlock(&mutex->fMutex);
+ #endif
+ }
+}
+
+#elif U_PLATFORM_HAS_WIN32_API
+//
+// Windows implementation of UMutex.
+//
+// Each UMutex has a corresponding Windows CRITICAL_SECTION.
+// CRITICAL_SECTIONS must be initialized before use. This is done
+// with a InitOnceExcuteOnce operation.
+//
+// InitOnceExecuteOnce was introduced with Windows Vista. For now ICU
+// must support Windows XP, so we roll our own. ICU will switch to the
+// native Windows InitOnceExecuteOnce when possible.
+
+typedef UBool (*U_PINIT_ONCE_FN) (
+ U_INIT_ONCE *initOnce,
+ void *parameter,
+ void **context
+);
+
+UBool u_InitOnceExecuteOnce(
+ U_INIT_ONCE *initOnce,
+ U_PINIT_ONCE_FN initFn,
+ void *parameter,
+ void **context) {
+ for (;;) {
+ long previousState = InterlockedCompareExchange(
+ &initOnce->fState, // Destination,
+ 1, // Exchange Value
+ 0); // Compare value
+ if (previousState == 2) {
+ // Initialization was already completed.
+ if (context != NULL) {
+ *context = initOnce->fContext;
+ }
+ return TRUE;
+ }
+ if (previousState == 1) {
+ // Initialization is in progress in some other thread.
+ // Loop until it completes.
+ Sleep(1);
+ continue;
+ }
+
+ // Initialization needed. Execute the callback function to do it.
+ U_ASSERT(previousState == 0);
+ U_ASSERT(initOnce->fState == 1);
+ UBool success = (*initFn)(initOnce, parameter, &initOnce->fContext);
+ U_ASSERT(success); // ICU is not supporting the failure case.
+
+ // Assign the state indicating that initialization has completed.
+ // Using InterlockedCompareExchange to do it ensures that all
+ // threads will have a consistent view of memory.
+ previousState = InterlockedCompareExchange(&initOnce->fState, 2, 1);
+ U_ASSERT(previousState == 1);
+ // Next loop iteration will see the initialization and return.
+ }
+};
+
+static UBool winMutexInit(U_INIT_ONCE *initOnce, void *param, void **context) {
+ UMutex *mutex = static_cast<UMutex *>(param);
+ U_ASSERT(sizeof(CRITICAL_SECTION) <= sizeof(mutex->fCS));
+ InitializeCriticalSection((CRITICAL_SECTION *)mutex->fCS);
+ return TRUE;
+}
+
+/*
+ * umtx_lock
+ */
+U_CAPI void U_EXPORT2
+umtx_lock(UMutex *mutex) {
+ if (mutex == NULL) {
+ mutex = &globalMutex;
+ }
+ if (pMutexLockFn) {
+ usrMutexLock(mutex);
+ } else {
+ u_InitOnceExecuteOnce(&mutex->fInitOnce, winMutexInit, mutex, NULL);
+ EnterCriticalSection((CRITICAL_SECTION *)mutex->fCS);
+ }
+}
+
+U_CAPI void U_EXPORT2
+umtx_unlock(UMutex* mutex)
+{
+ if (mutex == NULL) {
+ mutex = &globalMutex;
+ }
+ if (pMutexUnlockFn) {
+ (*pMutexUnlockFn)(gMutexContext, &mutex->fUserMutex);
+ } else {
+ LeaveCriticalSection((CRITICAL_SECTION *)mutex->fCS);
+ }
+}
+
+#endif // Windows Implementation
+
+
+U_CAPI void U_EXPORT2
+u_setMutexFunctions(const void *context, UMtxInitFn *i, UMtxFn *d, UMtxFn *l, UMtxFn *u,
+ UErrorCode *status) {
+ if (U_FAILURE(*status)) {
+ return;
+ }
+
+ /* Can not set a mutex function to a NULL value */
+ if (i==NULL || d==NULL || l==NULL || u==NULL) {
+ *status = U_ILLEGAL_ARGUMENT_ERROR;
+ return;
+ }
+
+ /* If ICU is not in an initial state, disallow this operation. */
+ if (cmemory_inUse()) {
+ *status = U_INVALID_STATE_ERROR;
+ return;
+ }
+
+ // Clean up any previously set user mutex functions.
+ // It's possible to call u_setMutexFunctions() more than once without without explicitly cleaning up,
+ // and the last call should take. Kind of a corner case, but it worked once, there is a test for
+ // it, so we keep it working. The global and impl mutexes will have been created by the
+ // previous u_setMutexFunctions(), and now need to be destroyed.
+
+ usrMutexCleanup();
+
+ /* Swap in the mutex function pointers. */
+ pMutexInitFn = i;
+ pMutexDestroyFn = d;
+ pMutexLockFn = l;
+ pMutexUnlockFn = u;
+ gMutexContext = context;
+ gMutexListSize = 0;
+
+ /* Initialize the global and impl mutexes. Safe to do at this point because
+ * u_setMutexFunctions must be done in a single-threaded envioronment. Not thread safe.
+ */
+ (*pMutexInitFn)(gMutexContext, &globalMutex.fUserMutex, status);
+ globalMutex.fInitialized = TRUE;
+ (*pMutexInitFn)(gMutexContext, &implMutex.fUserMutex, status);
+ implMutex.fInitialized = TRUE;
+}
+
+
+
+/* synchronized compare and swap function, for use when OS or compiler built-in
+ * equivalents aren't available.
+ */
+static void *mutexed_compare_and_swap(void **dest, void *newval, void *oldval) {
+ umtx_lock(&implMutex);
+ void *temp = *dest;
+ if (temp == oldval) {
+ *dest = newval;
+ }
+ umtx_unlock(&implMutex);
+
+ return temp;
+}
+
+
+
+/*-----------------------------------------------------------------
+ *
+ * Atomic Increment and Decrement
+ * umtx_atomic_inc
+ * umtx_atomic_dec
+ *
+ *----------------------------------------------------------------*/
+
+/* Pointers to user-supplied inc/dec functions. Null if no funcs have been set. */
+static UMtxAtomicFn *pIncFn = NULL;
+static UMtxAtomicFn *pDecFn = NULL;
+static const void *gIncDecContext = NULL;
+
+#if defined (POSIX) && (U_HAVE_GCC_ATOMICS == 0)
+static UMutex gIncDecMutex = U_MUTEX_INITIALIZER;
+#endif
+
+U_CAPI int32_t U_EXPORT2
+umtx_atomic_inc(int32_t *p) {
+ int32_t retVal;
+ if (pIncFn) {
+ retVal = (*pIncFn)(gIncDecContext, p);
+ } else {
+ #if U_PLATFORM_HAS_WIN32_API
+ retVal = InterlockedIncrement((LONG*)p);
+ #elif defined(USE_MAC_OS_ATOMIC_INCREMENT)
+ retVal = OSAtomicIncrement32Barrier(p);
+ #elif (U_HAVE_GCC_ATOMICS == 1)
+ retVal = __sync_add_and_fetch(p, 1);
+ #elif defined (POSIX)
+ umtx_lock(&gIncDecMutex);
+ retVal = ++(*p);
+ umtx_unlock(&gIncDecMutex);
+ #else
+ /* Unknown Platform. */
+ retVal = ++(*p);
+ #endif
+ }
+ return retVal;
+}
+
+U_CAPI int32_t U_EXPORT2
+umtx_atomic_dec(int32_t *p) {
+ int32_t retVal;
+ if (pDecFn) {
+ retVal = (*pDecFn)(gIncDecContext, p);
+ } else {
+ #if U_PLATFORM_HAS_WIN32_API
+ retVal = InterlockedDecrement((LONG*)p);
+ #elif defined(USE_MAC_OS_ATOMIC_INCREMENT)
+ retVal = OSAtomicDecrement32Barrier(p);
+ #elif (U_HAVE_GCC_ATOMICS == 1)
+ retVal = __sync_sub_and_fetch(p, 1);
+ #elif defined (POSIX)
+ umtx_lock(&gIncDecMutex);
+ retVal = --(*p);
+ umtx_unlock(&gIncDecMutex);
+ #else
+ /* Unknown Platform. */
+ retVal = --(*p);
+ #endif
+ }
+ return retVal;
+}
+
+
+
+U_CAPI void U_EXPORT2
+u_setAtomicIncDecFunctions(const void *context, UMtxAtomicFn *ip, UMtxAtomicFn *dp,
+ UErrorCode *status) {
+ if (U_FAILURE(*status)) {
+ return;
+ }
+ /* Can not set a mutex function to a NULL value */
+ if (ip==NULL || dp==NULL) {
+ *status = U_ILLEGAL_ARGUMENT_ERROR;
+ return;
+ }
+ /* If ICU is not in an initial state, disallow this operation. */
+ if (cmemory_inUse()) {
+ *status = U_INVALID_STATE_ERROR;
+ return;
+ }
+
+ pIncFn = ip;
+ pDecFn = dp;
+ gIncDecContext = context;
+
+#if U_DEBUG
+ {
+ int32_t testInt = 0;
+ U_ASSERT(umtx_atomic_inc(&testInt) == 1); /* Sanity Check. Do the functions work at all? */
+ U_ASSERT(testInt == 1);
+ U_ASSERT(umtx_atomic_dec(&testInt) == 0);
+ U_ASSERT(testInt == 0);
+ }
+#endif
+}
+
+
+/*
+ * Mutex Cleanup Function
+ * Reset the mutex function callback pointers.
+ * Called from the global ICU u_cleanup() function.
+ */
+U_CFUNC UBool umtx_cleanup(void) {
+ /* Extra, do-nothing function call to suppress compiler warnings on platforms where
+ * mutexed_compare_and_swap is not otherwise used. */
+ void *pv = &globalMutex;
+ mutexed_compare_and_swap(&pv, NULL, NULL);
+ usrMutexCleanup();
+
+ pIncFn = NULL;
+ pDecFn = NULL;
+ gIncDecContext = NULL;
+
+ return TRUE;
+}
diff --git a/Build/source/libs/icu/icu-50.1/common/unicode/listformatter.h b/Build/source/libs/icu/icu-50.1/common/unicode/listformatter.h
new file mode 100644
index 00000000000..37042379db6
--- /dev/null
+++ b/Build/source/libs/icu/icu-50.1/common/unicode/listformatter.h
@@ -0,0 +1,134 @@
+/*
+*******************************************************************************
+*
+* Copyright (C) 2012, International Business Machines
+* Corporation and others. All Rights Reserved.
+*
+*******************************************************************************
+* file name: listformatter.h
+* encoding: US-ASCII
+* tab size: 8 (not used)
+* indentation:4
+*
+* created on: 20120426
+* created by: Umesh P. Nair
+*/
+
+#ifndef __LISTFORMATTER_H__
+#define __LISTFORMATTER_H__
+
+#include "unicode/unistr.h"
+#include "unicode/locid.h"
+
+
+U_NAMESPACE_BEGIN
+
+/** @internal */
+class Hashtable;
+
+/** @internal */
+struct ListFormatData : public UMemory {
+ UnicodeString twoPattern;
+ UnicodeString startPattern;
+ UnicodeString middlePattern;
+ UnicodeString endPattern;
+
+ ListFormatData(const UnicodeString& two, const UnicodeString& start, const UnicodeString& middle, const UnicodeString& end) :
+ twoPattern(two), startPattern(start), middlePattern(middle), endPattern(end) {}
+};
+
+
+/**
+ * \file
+ * \brief C++ API: API for formatting a list.
+ */
+
+
+/**
+ * An immutable class for formatting a list, using data from CLDR (or supplied
+ * separately).
+ *
+ * Example: Input data ["Alice", "Bob", "Charlie", "Delta"] will be formatted
+ * as "Alice, Bob, Charlie and Delta" in English.
+ *
+ * The ListFormatter class is not intended for public subclassing.
+ */
+class U_COMMON_API ListFormatter : public UObject{
+
+ public:
+ /**
+ * Creates a ListFormatter appropriate for the default locale.
+ *
+ * @param errorCode ICU error code, set if no data available for default locale.
+ * @return Pointer to a ListFormatter object for the default locale,
+ * created from internal data derived from CLDR data.
+ * @draft ICU 50
+ */
+ static ListFormatter* createInstance(UErrorCode& errorCode);
+
+ /**
+ * Creates a ListFormatter appropriate for a locale.
+ *
+ * @param locale The locale.
+ * @param errorCode ICU error code, set if no data available for the given locale.
+ * @return A ListFormatter object created from internal data derived from
+ * CLDR data.
+ * @draft ICU 50
+ */
+ static ListFormatter* createInstance(const Locale& locale, UErrorCode& errorCode);
+
+
+ /**
+ * Destructor.
+ *
+ * @draft ICU 50
+ */
+ virtual ~ListFormatter();
+
+
+ /**
+ * Formats a list of strings.
+ *
+ * @param items An array of strings to be combined and formatted.
+ * @param n_items Length of the array items.
+ * @param appendTo The string to which the result should be appended to.
+ * @param errorCode ICU error code, set if there is an error.
+ * @return Formatted string combining the elements of items, appended to appendTo.
+ * @draft ICU 50
+ */
+ UnicodeString& format(const UnicodeString items[], int32_t n_items,
+ UnicodeString& appendTo, UErrorCode& errorCode) const;
+
+ /**
+ * Gets the fallback locale for a given locale.
+ * TODO: Consider moving this to the Locale class.
+ * @param in The input locale.
+ * @param out The output locale after fallback.
+ * @internal For testing.
+ */
+ static void getFallbackLocale(const Locale& in, Locale& out, UErrorCode& errorCode);
+
+ /**
+ * @internal constructor made public for testing.
+ */
+ ListFormatter(const ListFormatData& listFormatterData);
+
+ private:
+ static void initializeHash(UErrorCode& errorCode);
+ static void addDataToHash(const char* locale, const char* two, const char* start, const char* middle, const char* end, UErrorCode& errorCode);
+ static const ListFormatData* getListFormatData(const Locale& locale, UErrorCode& errorCode);
+
+ ListFormatter();
+ ListFormatter(const ListFormatter&);
+
+ ListFormatter& operator = (const ListFormatter&);
+ void addNewString(const UnicodeString& pattern, UnicodeString& originalString,
+ const UnicodeString& newString, UErrorCode& errorCode) const;
+ virtual UClassID getDynamicClassID() const;
+
+ const ListFormatData& data;
+};
+
+U_NAMESPACE_END
+
+#endif
diff --git a/Build/source/libs/icu/icu-50.1/common/utypeinfo.h b/Build/source/libs/icu/icu-50.1/common/utypeinfo.h
new file mode 100644
index 00000000000..4de16d6d790
--- /dev/null
+++ b/Build/source/libs/icu/icu-50.1/common/utypeinfo.h
@@ -0,0 +1,27 @@
+/*
+******************************************************************************
+*
+* Copyright (C) 2012, International Business Machines
+* Corporation and others. All Rights Reserved.
+*
+******************************************************************************
+*/
+
+#ifndef __UTYPEINFO_H__
+#define __UTYPEINFO_H__
+
+// Windows header <typeinfo> does not define 'exception' in 'std' namespace.
+// Therefore, a project using ICU cannot be compiled with _HAS_EXCEPTION
+// set to 0 on Windows with Visual Studio. To work around that, we have to
+// include <exception> explicilty and add using statement below.
+// Whenever 'typeid' is used, this header has to be included
+// instead of <typeinfo>.
+// Visual Stuido 10 emits warning 4275 with this change. If you compile
+// with exception disabled, you have to suppress warning 4275.
+#if defined(_MSC_VER) && _HAS_EXCEPTIONS == 0
+#include <exception>
+using std::exception;
+#endif
+#include <typeinfo> // for 'typeid' to work
+
+#endif