diff options
Diffstat (limited to 'deps/icu-small/source/i18n')
420 files changed, 6583 insertions, 5452 deletions
diff --git a/deps/icu-small/source/i18n/affixpatternparser.cpp b/deps/icu-small/source/i18n/affixpatternparser.cpp index fc98f7bf45..05e45dbb12 100644 --- a/deps/icu-small/source/i18n/affixpatternparser.cpp +++ b/deps/icu-small/source/i18n/affixpatternparser.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* * Copyright (C) 2015, International Business Machines * Corporation and others. All Rights Reserved. @@ -44,7 +46,8 @@ nextToken(const UChar *buffer, int32_t idx, int32_t len, UChar *token) { *token = buffer[idx + 1]; if (buffer[idx + 1] == 0xA4) { int32_t i = 2; - for (; idx + i < len && i < 4 && buffer[idx + i] == buffer[idx + 1]; ++i); + for (; idx + i < len && i < 4 && buffer[idx + i] == buffer[idx + 1]; ++i) + ; return i; } return 2; @@ -66,7 +69,8 @@ nextUserToken(const UChar *buffer, int32_t idx, int32_t len, UChar *token) { break; } int32_t i = 1; - for (; idx + i < len && i < max && buffer[idx + i] == buffer[idx]; ++i); + for (; idx + i < len && i < max && buffer[idx + i] == buffer[idx]; ++i) + ; return i; } diff --git a/deps/icu-small/source/i18n/affixpatternparser.h b/deps/icu-small/source/i18n/affixpatternparser.h index 2105540a1a..07f84c5314 100644 --- a/deps/icu-small/source/i18n/affixpatternparser.h +++ b/deps/icu-small/source/i18n/affixpatternparser.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2015, International Business Machines diff --git a/deps/icu-small/source/i18n/alphaindex.cpp b/deps/icu-small/source/i18n/alphaindex.cpp index 9159014f80..8a2f0a3cb5 100644 --- a/deps/icu-small/source/i18n/alphaindex.cpp +++ b/deps/icu-small/source/i18n/alphaindex.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2009-2014, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/anytrans.cpp b/deps/icu-small/source/i18n/anytrans.cpp index 695a9390b6..8ec6f837cf 100644 --- a/deps/icu-small/source/i18n/anytrans.cpp +++ b/deps/icu-small/source/i18n/anytrans.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ***************************************************************** * Copyright (c) 2002-2014, International Business Machines Corporation diff --git a/deps/icu-small/source/i18n/anytrans.h b/deps/icu-small/source/i18n/anytrans.h index 228ccbe03a..d06d2baa57 100644 --- a/deps/icu-small/source/i18n/anytrans.h +++ b/deps/icu-small/source/i18n/anytrans.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* *********************************************************************** * Copyright (c) 2002-2007, International Business Machines Corporation diff --git a/deps/icu-small/source/i18n/astro.cpp b/deps/icu-small/source/i18n/astro.cpp index 1b3bf58964..d657aaa20d 100644 --- a/deps/icu-small/source/i18n/astro.cpp +++ b/deps/icu-small/source/i18n/astro.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /************************************************************************ * Copyright (C) 1996-2012, International Business Machines Corporation * and others. All Rights Reserved. diff --git a/deps/icu-small/source/i18n/astro.h b/deps/icu-small/source/i18n/astro.h index cd20b6cf25..e854661763 100644 --- a/deps/icu-small/source/i18n/astro.h +++ b/deps/icu-small/source/i18n/astro.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /************************************************************************ * Copyright (C) 1996-2008, International Business Machines Corporation * * and others. All Rights Reserved. * diff --git a/deps/icu-small/source/i18n/basictz.cpp b/deps/icu-small/source/i18n/basictz.cpp index 7fea290f16..b464f5cc5f 100644 --- a/deps/icu-small/source/i18n/basictz.cpp +++ b/deps/icu-small/source/i18n/basictz.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2007-2013, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/bocsu.cpp b/deps/icu-small/source/i18n/bocsu.cpp index cfc9816693..a2f94f239e 100644 --- a/deps/icu-small/source/i18n/bocsu.cpp +++ b/deps/icu-small/source/i18n/bocsu.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2001-2014, International Business Machines diff --git a/deps/icu-small/source/i18n/bocsu.h b/deps/icu-small/source/i18n/bocsu.h index 0f89a0fbeb..56b03500b1 100644 --- a/deps/icu-small/source/i18n/bocsu.h +++ b/deps/icu-small/source/i18n/bocsu.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2001-2014, International Business Machines diff --git a/deps/icu-small/source/i18n/brktrans.cpp b/deps/icu-small/source/i18n/brktrans.cpp index dafac399f8..714a0a8720 100644 --- a/deps/icu-small/source/i18n/brktrans.cpp +++ b/deps/icu-small/source/i18n/brktrans.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2008-2015, International Business Machines diff --git a/deps/icu-small/source/i18n/brktrans.h b/deps/icu-small/source/i18n/brktrans.h index 5a4c4b6d6b..27228321e6 100644 --- a/deps/icu-small/source/i18n/brktrans.h +++ b/deps/icu-small/source/i18n/brktrans.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2008-2015, International Business Machines diff --git a/deps/icu-small/source/i18n/buddhcal.cpp b/deps/icu-small/source/i18n/buddhcal.cpp index 5c9f80ed0c..c8a3a91a2c 100644 --- a/deps/icu-small/source/i18n/buddhcal.cpp +++ b/deps/icu-small/source/i18n/buddhcal.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2003-2013, International Business Machines Corporation and * diff --git a/deps/icu-small/source/i18n/buddhcal.h b/deps/icu-small/source/i18n/buddhcal.h index 441156d3d8..95db980600 100644 --- a/deps/icu-small/source/i18n/buddhcal.h +++ b/deps/icu-small/source/i18n/buddhcal.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** * Copyright (C) 2003-2013, International Business Machines Corporation diff --git a/deps/icu-small/source/i18n/calendar.cpp b/deps/icu-small/source/i18n/calendar.cpp index 5a1bef805f..9b0f5a0ad3 100644 --- a/deps/icu-small/source/i18n/calendar.cpp +++ b/deps/icu-small/source/i18n/calendar.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 1997-2016, International Business Machines Corporation and * @@ -634,7 +636,9 @@ static const int32_t kCalendarLimits[UCAL_FIELD_COUNT][4] = { }; // Resource bundle tags read by this class +static const char gCalendar[] = "calendar"; static const char gMonthNames[] = "monthNames"; +static const char gGregorian[] = "gregorian"; // Data flow in Calendar // --------------------- @@ -3791,12 +3795,30 @@ Calendar::setWeekData(const Locale& desiredLocale, const char *type, UErrorCode& from the calendar data. The code used to use the dateTimeElements resource to get first day of week data, but this was moved to supplemental data under ticket 7755. (JCE) */ - CalendarData calData(useLocale,type,status); - UResourceBundle *monthNames = calData.getByKey(gMonthNames,status); + // Get the monthNames resource bundle for the calendar 'type'. Fallback to gregorian if the resource is not + // found. + LocalUResourceBundlePointer calData(ures_open(NULL, useLocale.getBaseName(), &status)); + ures_getByKey(calData.getAlias(), gCalendar, calData.getAlias(), &status); + + LocalUResourceBundlePointer monthNames; + if (type != NULL && *type != '\0' && uprv_strcmp(type, gGregorian) != 0) { + monthNames.adoptInstead(ures_getByKeyWithFallback(calData.getAlias(), type, NULL, &status)); + ures_getByKeyWithFallback(monthNames.getAlias(), gMonthNames, + monthNames.getAlias(), &status); + } + + if (monthNames.isNull() || status == U_MISSING_RESOURCE_ERROR) { + status = U_ZERO_ERROR; + monthNames.adoptInstead(ures_getByKeyWithFallback(calData.getAlias(), gGregorian, + monthNames.orphan(), &status)); + ures_getByKeyWithFallback(monthNames.getAlias(), gMonthNames, + monthNames.getAlias(), &status); + } + if (U_SUCCESS(status)) { U_LOCALE_BASED(locBased,*this); - locBased.setLocaleIDs(ures_getLocaleByType(monthNames, ULOC_VALID_LOCALE, &status), - ures_getLocaleByType(monthNames, ULOC_ACTUAL_LOCALE, &status)); + locBased.setLocaleIDs(ures_getLocaleByType(monthNames.getAlias(), ULOC_VALID_LOCALE, &status), + ures_getLocaleByType(monthNames.getAlias(), ULOC_ACTUAL_LOCALE, &status)); } else { status = U_USING_FALLBACK_WARNING; return; @@ -3815,9 +3837,6 @@ Calendar::setWeekData(const Locale& desiredLocale, const char *type, UErrorCode& } if (U_FAILURE(status)) { -#if defined (U_DEBUG_CALDATA) - fprintf(stderr, " Failure loading weekData from supplemental = %s\n", u_errorName(status)); -#endif status = U_USING_FALLBACK_WARNING; } else { int32_t arrLen; diff --git a/deps/icu-small/source/i18n/casetrn.cpp b/deps/icu-small/source/i18n/casetrn.cpp index 602c22914f..7f71362c33 100644 --- a/deps/icu-small/source/i18n/casetrn.cpp +++ b/deps/icu-small/source/i18n/casetrn.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * diff --git a/deps/icu-small/source/i18n/casetrn.h b/deps/icu-small/source/i18n/casetrn.h index b20cb8e969..1067e0fc7b 100644 --- a/deps/icu-small/source/i18n/casetrn.h +++ b/deps/icu-small/source/i18n/casetrn.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * diff --git a/deps/icu-small/source/i18n/cecal.cpp b/deps/icu-small/source/i18n/cecal.cpp index 9c2759ba75..38c89799be 100644 --- a/deps/icu-small/source/i18n/cecal.cpp +++ b/deps/icu-small/source/i18n/cecal.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2003 - 2009, International Business Machines Corporation and * diff --git a/deps/icu-small/source/i18n/cecal.h b/deps/icu-small/source/i18n/cecal.h index 471d88933e..ce6f4209ca 100644 --- a/deps/icu-small/source/i18n/cecal.h +++ b/deps/icu-small/source/i18n/cecal.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2003 - 2008, International Business Machines Corporation and * diff --git a/deps/icu-small/source/i18n/chnsecal.cpp b/deps/icu-small/source/i18n/chnsecal.cpp index d2c9e9ea0b..0cf88205cb 100644 --- a/deps/icu-small/source/i18n/chnsecal.cpp +++ b/deps/icu-small/source/i18n/chnsecal.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * Copyright (C) 2007-2014, International Business Machines Corporation diff --git a/deps/icu-small/source/i18n/chnsecal.h b/deps/icu-small/source/i18n/chnsecal.h index ba3f943066..e000df7158 100644 --- a/deps/icu-small/source/i18n/chnsecal.h +++ b/deps/icu-small/source/i18n/chnsecal.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ***************************************************************************** * Copyright (C) 2007-2013, International Business Machines Corporation diff --git a/deps/icu-small/source/i18n/choicfmt.cpp b/deps/icu-small/source/i18n/choicfmt.cpp index e739adde0c..3630157852 100644 --- a/deps/icu-small/source/i18n/choicfmt.cpp +++ b/deps/icu-small/source/i18n/choicfmt.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 1997-2013, International Business Machines Corporation and * diff --git a/deps/icu-small/source/i18n/coleitr.cpp b/deps/icu-small/source/i18n/coleitr.cpp index c842663ba1..4825baebcd 100644 --- a/deps/icu-small/source/i18n/coleitr.cpp +++ b/deps/icu-small/source/i18n/coleitr.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 1996-2014, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/coll.cpp b/deps/icu-small/source/i18n/coll.cpp index 6a8dc1c0d0..46e5324ffd 100644 --- a/deps/icu-small/source/i18n/coll.cpp +++ b/deps/icu-small/source/i18n/coll.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * Copyright (C) 1996-2014, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/collation.cpp b/deps/icu-small/source/i18n/collation.cpp index c01457e738..bac7498dfc 100644 --- a/deps/icu-small/source/i18n/collation.cpp +++ b/deps/icu-small/source/i18n/collation.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2010-2014, International Business Machines diff --git a/deps/icu-small/source/i18n/collation.h b/deps/icu-small/source/i18n/collation.h index 53cffa983c..c82d9a4778 100644 --- a/deps/icu-small/source/i18n/collation.h +++ b/deps/icu-small/source/i18n/collation.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2010-2015, International Business Machines diff --git a/deps/icu-small/source/i18n/collationbuilder.cpp b/deps/icu-small/source/i18n/collationbuilder.cpp index 3465832d5a..0025cfc34f 100644 --- a/deps/icu-small/source/i18n/collationbuilder.cpp +++ b/deps/icu-small/source/i18n/collationbuilder.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2013-2014, International Business Machines diff --git a/deps/icu-small/source/i18n/collationbuilder.h b/deps/icu-small/source/i18n/collationbuilder.h index cd499a4e92..7dda928a51 100644 --- a/deps/icu-small/source/i18n/collationbuilder.h +++ b/deps/icu-small/source/i18n/collationbuilder.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2013-2014, International Business Machines diff --git a/deps/icu-small/source/i18n/collationcompare.cpp b/deps/icu-small/source/i18n/collationcompare.cpp index 3b72d05d71..5d8bd90d6c 100644 --- a/deps/icu-small/source/i18n/collationcompare.cpp +++ b/deps/icu-small/source/i18n/collationcompare.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 1996-2015, International Business Machines diff --git a/deps/icu-small/source/i18n/collationcompare.h b/deps/icu-small/source/i18n/collationcompare.h index 0185226d62..630b90b556 100644 --- a/deps/icu-small/source/i18n/collationcompare.h +++ b/deps/icu-small/source/i18n/collationcompare.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 1996-2014, International Business Machines diff --git a/deps/icu-small/source/i18n/collationdata.cpp b/deps/icu-small/source/i18n/collationdata.cpp index 7f781f50f1..d3a62e4fd0 100644 --- a/deps/icu-small/source/i18n/collationdata.cpp +++ b/deps/icu-small/source/i18n/collationdata.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2012-2015, International Business Machines diff --git a/deps/icu-small/source/i18n/collationdata.h b/deps/icu-small/source/i18n/collationdata.h index dd7fcebea4..ab40bbd89e 100644 --- a/deps/icu-small/source/i18n/collationdata.h +++ b/deps/icu-small/source/i18n/collationdata.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2010-2015, International Business Machines diff --git a/deps/icu-small/source/i18n/collationdatabuilder.cpp b/deps/icu-small/source/i18n/collationdatabuilder.cpp index 7bdf184cc0..4a9a67c7b0 100644 --- a/deps/icu-small/source/i18n/collationdatabuilder.cpp +++ b/deps/icu-small/source/i18n/collationdatabuilder.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2012-2015, International Business Machines diff --git a/deps/icu-small/source/i18n/collationdatabuilder.h b/deps/icu-small/source/i18n/collationdatabuilder.h index cfa46fd550..f2c9a820ad 100644 --- a/deps/icu-small/source/i18n/collationdatabuilder.h +++ b/deps/icu-small/source/i18n/collationdatabuilder.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2012-2014, International Business Machines diff --git a/deps/icu-small/source/i18n/collationdatareader.cpp b/deps/icu-small/source/i18n/collationdatareader.cpp index f7098f9841..df0b2a3680 100644 --- a/deps/icu-small/source/i18n/collationdatareader.cpp +++ b/deps/icu-small/source/i18n/collationdatareader.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2013-2015, International Business Machines diff --git a/deps/icu-small/source/i18n/collationdatareader.h b/deps/icu-small/source/i18n/collationdatareader.h index 4a9fa5eeca..ff8ec3d406 100644 --- a/deps/icu-small/source/i18n/collationdatareader.h +++ b/deps/icu-small/source/i18n/collationdatareader.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2013-2015, International Business Machines diff --git a/deps/icu-small/source/i18n/collationdatawriter.cpp b/deps/icu-small/source/i18n/collationdatawriter.cpp index 6943ed2c61..596236bc61 100644 --- a/deps/icu-small/source/i18n/collationdatawriter.cpp +++ b/deps/icu-small/source/i18n/collationdatawriter.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2013-2015, International Business Machines diff --git a/deps/icu-small/source/i18n/collationdatawriter.h b/deps/icu-small/source/i18n/collationdatawriter.h index 50e26524ce..6169e0fd26 100644 --- a/deps/icu-small/source/i18n/collationdatawriter.h +++ b/deps/icu-small/source/i18n/collationdatawriter.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2013-2014, International Business Machines diff --git a/deps/icu-small/source/i18n/collationfastlatin.cpp b/deps/icu-small/source/i18n/collationfastlatin.cpp index 70e393c4df..c3e8c98b3a 100644 --- a/deps/icu-small/source/i18n/collationfastlatin.cpp +++ b/deps/icu-small/source/i18n/collationfastlatin.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2013-2015, International Business Machines diff --git a/deps/icu-small/source/i18n/collationfastlatin.h b/deps/icu-small/source/i18n/collationfastlatin.h index 6a25c6692c..00a2d1b510 100644 --- a/deps/icu-small/source/i18n/collationfastlatin.h +++ b/deps/icu-small/source/i18n/collationfastlatin.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2013-2015, International Business Machines diff --git a/deps/icu-small/source/i18n/collationfastlatinbuilder.cpp b/deps/icu-small/source/i18n/collationfastlatinbuilder.cpp index d5acda15b0..032e5e82aa 100644 --- a/deps/icu-small/source/i18n/collationfastlatinbuilder.cpp +++ b/deps/icu-small/source/i18n/collationfastlatinbuilder.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2013-2015, International Business Machines @@ -147,7 +149,7 @@ CollationFastLatinBuilder::loadGroups(const CollationData &data, UErrorCode &err // missing data return FALSE; } - result.append(0); // reserve a slot for this group + result.append((UChar)0); // reserve a slot for this group } firstDigitPrimary = data.getFirstPrimaryForGroup(UCOL_REORDER_CODE_DIGIT); @@ -564,7 +566,7 @@ CollationFastLatinBuilder::encodeCharCEs(UErrorCode &errorCode) { if(U_FAILURE(errorCode)) { return FALSE; } int32_t miniCEsStart = result.length(); for(int32_t i = 0; i < CollationFastLatin::NUM_FAST_CHARS; ++i) { - result.append(0); // initialize to completely ignorable + result.append((UChar)0); // initialize to completely ignorable } int32_t indexBase = result.length(); for(int32_t i = 0; i < CollationFastLatin::NUM_FAST_CHARS; ++i) { diff --git a/deps/icu-small/source/i18n/collationfastlatinbuilder.h b/deps/icu-small/source/i18n/collationfastlatinbuilder.h index b9eedf985a..9d380380b4 100644 --- a/deps/icu-small/source/i18n/collationfastlatinbuilder.h +++ b/deps/icu-small/source/i18n/collationfastlatinbuilder.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2013-2016, International Business Machines diff --git a/deps/icu-small/source/i18n/collationfcd.cpp b/deps/icu-small/source/i18n/collationfcd.cpp index 153953cfc8..de1d9a2d1d 100644 --- a/deps/icu-small/source/i18n/collationfcd.cpp +++ b/deps/icu-small/source/i18n/collationfcd.cpp @@ -1,5 +1,7 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* - * Copyright (C) 1999-2015, International Business Machines + * Copyright (C) 1999-2016, International Business Machines * Corporation and others. All Rights Reserved. * * file name: collationfcd.cpp @@ -20,27 +22,27 @@ const uint8_t CollationFCD::lcccIndex[2048]={ 0,0,0,0,0,0,0,0,1,1,2,3,0,0,0,0, 0,0,0,0,4,0,0,0,0,0,0,0,5,6,7,0, 8,0,9,0xa,0,0,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0x10, -0x11,0x12,0x13,0,0,0,0,0x14,0,0x15,0x16,0,0,0x15,0x17,0, -0,0x15,0x17,0,0,0x15,0x17,0,0,0x15,0x17,0,0,0,0x17,0, -0,0,0x18,0,0,0x15,0x17,0,0,0,0x17,0,0,0,0x19,0, -0,0x1a,0x1b,0,0,0x1c,0x1b,0,0x1c,0x1d,0,0x1e,0x1f,0,0x20,0, -0,0x21,0,0,0x17,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0x22,0,0,0,0,0, +0x11,0x12,0x13,0,0,0,0x14,0x15,0,0x16,0x17,0,0,0x16,0x18,0, +0,0x16,0x18,0,0,0x16,0x18,0,0,0x16,0x18,0,0,0,0x18,0, +0,0,0x19,0,0,0x16,0x18,0,0,0,0x18,0,0,0,0x1a,0, +0,0x1b,0x1c,0,0,0x1d,0x1c,0,0x1d,0x1e,0,0x1f,0x20,0,0x21,0, +0,0x22,0,0,0x18,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0x23,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0x23,0x23,0,0,0,0,0x24,0, -0,0,0,0,0,0x25,0,0,0,0x13,0,0,0,0,0,0, -0x26,0,0,0x27,0,0x28,0,0,0,0x23,0x29,0x10,0,0x2a,0,0x2b, -0,0x2c,0,0,0,0,0x2d,0x2e,0,0,0,0,0,0,1,0x2f, +0,0,0,0,0,0,0,0,0x24,0x24,0,0,0,0,0x25,0, +0,0,0,0,0,0x26,0,0,0,0x13,0,0,0,0,0,0, +0x27,0,0,0x28,0,0x29,0,0,0,0x24,0x2a,0x10,0,0x2b,0,0x2c, +0,0x2d,0,0,0,0,0x2e,0x2f,0,0,0,0,0,0,1,0x30, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0x30,0x31,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0x31,0x32,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0x32,0,0,0,0x33,0,0,0,1, +0,0,0,0,0,0,0,0x33,0,0,0,0x34,0,0,0,1, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0x34,0,0,0x35,0,0,0,0,0,0,0,0,0,0,0, +0,0x35,0,0,0x36,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, @@ -99,9 +101,9 @@ const uint8_t CollationFCD::lcccIndex[2048]={ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0x36,0x37,0,0,0x38,0,0,0,0,0,0,0,0, -0x20,0,0,0,0,0,0x29,0x39,0,0x3a,0x3b,0,0,0x3b,0x3c,0, -0,0,0,0,0,0x3d,0x3e,0x3f,0,0,0,0,0,0,0,0x17, +0,0,0,0x37,0x38,0,0,0x39,0,0,0,0,0,0,0,0, +0x21,0,0,0,0,0,0x2a,0x3a,0,0x3b,0x3c,0,0,0x3c,0x3d,0, +0,0,0,0,0,0x3e,0x3f,0x40,0,0,0,0,0,0,0,0x18, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, @@ -124,7 +126,7 @@ const uint8_t CollationFCD::lcccIndex[2048]={ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0x40,0x41,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0x41,0x42,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, @@ -141,17 +143,17 @@ const uint8_t CollationFCD::lcccIndex[2048]={ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0x42,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0x43,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; -const uint32_t CollationFCD::lcccBits[67]={ +const uint32_t CollationFCD::lcccBits[68]={ 0,0xffffffff,0xffff7fff,0xffff,0xf8,0xfffe0000,0xbfffffff,0xb6,0x7ff0000,0xfffff800,0x10000,0x9fc00000,0x3d9f,0x20000,0xffff0000,0x7ff, -0xff800,0xfbc00000,0x3eef,0xe000000,0xfffffff8,0x10000000,0x1e2000,0x2000,0x602000,0x400,0x7000000,0xf00,0x3000000,0x2a00000,0x3c3e0000,0xdf, -0x40,0x6800000,0xe0000000,0x100000,0x20040000,0x200,0x1800000,0x9fe00001,0x3fff0000,0x10,0xc00,0xc0040,0x800000,0xfff70000,0x31021fd,0xf03fffff, -0x1fff0000,0x1ffe2,0x38000,0x80000000,0xfc00,0x6000000,0x3ff08000,0xc0000000,0x30000,0x3ffff,0x3800,0x80000,1,0xc19d0000,2,0x400000, -0x4000035,0x4108000,0x40000000 +0xff800,0xfbc00000,0x3eef,0xe000000,0xfff00000,0xfffffffb,0x10000000,0x1e2000,0x2000,0x602000,0x400,0x7000000,0xf00,0x3000000,0x2a00000,0x3c3e0000, +0xdf,0x40,0x6800000,0xe0000000,0x100000,0x20040000,0x200,0x1800000,0x9fe00001,0x3fff0000,0x10,0xc00,0xc0040,0x800000,0xfff70000,0x31021fd, +0xf83fffff,0x1fff0000,0x1ffe2,0x38000,0x80000000,0xfc00,0x6000000,0x3ff08000,0xc0000000,0x30000,0x3ffff,0x3800,0x80000,1,0xc19d0000,2, +0x400000,0x40000b5,0x5108000,0x40000000 }; const uint8_t CollationFCD::tcccIndex[2048]={ @@ -159,27 +161,27 @@ const uint8_t CollationFCD::tcccIndex[2048]={ 0xb,0xc,0,0,0,0,0,0,1,1,0xd,0xe,0xf,0x10,0x11,0, 0x12,0x13,0x14,0x15,0x16,0,0x17,0x18,0,0,0,0,0x19,0x1a,0x1b,0, 0x1c,0x1d,0x1e,0x1f,0,0,0x20,0x21,0x22,0x23,0x24,0,0,0,0,0x25, -0x26,0x27,0x28,0,0,0,0,0x29,0,0x2a,0x2b,0,0,0x2c,0x2d,0, -0,0x2e,0x2f,0,0,0x2c,0x30,0,0,0x2c,0x31,0,0,0,0x30,0, -0,0,0x32,0,0,0x2c,0x30,0,0,0,0x30,0,0,0,0x33,0, -0,0x34,0x35,0,0,0x36,0x35,0,0x36,0x37,0,0x38,0x39,0,0x3a,0, -0,0x3b,0,0,0x30,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0x3c,0,0,0,0,0, +0x26,0x27,0x28,0,0,0,0x29,0x2a,0,0x2b,0x2c,0,0,0x2d,0x2e,0, +0,0x2f,0x30,0,0,0x2d,0x31,0,0,0x2d,0x32,0,0,0,0x31,0, +0,0,0x33,0,0,0x2d,0x31,0,0,0,0x31,0,0,0,0x34,0, +0,0x35,0x36,0,0,0x37,0x36,0,0x37,0x38,0,0x39,0x3a,0,0x3b,0, +0,0x3c,0,0,0x31,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0x3d,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0x3d,0x3d,0,0,0,0,0x3e,0, -0,0,0,0,0,0x3f,0,0,0,0x28,0,0,0,0,0,0, -0x40,0,0,0x41,0,0x42,0,0,0,0x3d,0x43,0x25,0,0x44,0,0x45, -0,0x46,0,0,0,0,0x47,0x48,0,0,0,0,0,0,1,0x49, -1,1,1,1,0x4a,1,1,0x4b,0x4c,1,0x4d,0x4e,1,0x4f,0x50,0x51, -0,0,0,0,0,0,0x52,0x53,0,0x54,0,0,0x55,0x56,0x57,0, -0x58,0x59,0x5a,0x5b,0x5c,0x5d,0,0x5e,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0x3e,0x3e,0,0,0,0,0x3f,0, +0,0,0,0,0,0x40,0,0,0,0x28,0,0,0,0,0,0, +0x41,0,0,0x42,0,0x43,0,0,0,0x3e,0x44,0x25,0,0x45,0,0x46, +0,0x47,0,0,0,0,0x48,0x49,0,0,0,0,0,0,1,0x4a, +1,1,1,1,0x4b,1,1,0x4c,0x4d,1,0x4e,0x4f,1,0x50,0x51,0x52, +0,0,0,0,0,0,0x53,0x54,0,0x55,0,0,0x56,0x57,0x58,0, +0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0,0x5f,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0x2c,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0x5f,0,0,0,0x60,0,0,0,1, +0,0,0,0,0,0,0x2d,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0x60,0,0,0,0x61,0,0,0,1, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0x61,0x62,0x63,0x64,0x62,0x63,0x65,0,0,0,0,0,0,0,0, +0,0x62,0x63,0x64,0x65,0x63,0x64,0x66,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, @@ -238,9 +240,9 @@ const uint8_t CollationFCD::tcccIndex[2048]={ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0x66,0x67,0,0,0x68,0,0,0,0,0,0,0,0, -0x3a,0,0,0,0,0,0x43,0x69,0,0x6a,0x6b,0,0,0x6b,0x6c,0, -0,0,0,0,0,0x6d,0x6e,0x6f,0,0,0,0,0,0,0,0x30, +0,0,0,0x67,0x68,0,0,0x69,0,0,0,0,0,0,0,0, +0x3b,0,0,0,0,0,0x44,0x6a,0,0x6b,0x6c,0,0,0x6c,0x6d,0, +0,0,0,0,0,0x6e,0x6f,0x70,0,0,0,0,0,0,0,0x31, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, @@ -263,7 +265,7 @@ const uint8_t CollationFCD::tcccIndex[2048]={ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0x70,0x71,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0x71,0x72,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, @@ -280,20 +282,20 @@ const uint8_t CollationFCD::tcccIndex[2048]={ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0x3c,0x72,0x73,0,0,0,0,0, +0,0,0,0,0,0,0,0,0x3d,0x73,0x74,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xe,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; -const uint32_t CollationFCD::tcccBits[116]={ +const uint32_t CollationFCD::tcccBits[117]={ 0,0xffffffff,0x3e7effbf,0xbe7effbf,0xfffcffff,0x7ef1ff3f,0xfff3f1f8,0x7fffff3f,0x18003,0xdfffe000,0xff31ffcf,0xcfffffff,0xfffc0,0xffff7fff,0xffff,0x1d760, 0x1fc00,0x187c00,0x200708b,0x2000000,0x708b0000,0xc00000,0xf8,0xfccf0006,0x33ffcfc,0xfffe0000,0xbfffffff,0xb6,0x7ff0000,0x7c,0xfffff800,0x10000, -0x9fc80005,0x3d9f,0x20000,0xffff0000,0x7ff,0xff800,0xfbc00000,0x3eef,0xe000000,0xfffffff8,0x10120200,0xff1e2000,0x10000000,0xb0002000,0x10480000,0x4e002000, -0x2000,0x30002000,0x602100,0x24000400,0x7000000,0xf00,0x3000000,0x2a00000,0x3d7e0000,0xdf,0x40,0x6800000,0xe0000000,0x100000,0x20040000,0x200, -0x1800000,0x9fe00001,0x3fff0000,0x10,0xc00,0xc0040,0x800000,0xfff70000,0x31021fd,0xf03fffff,0xbffffff,0x3ffffff,0x3f3fffff,0xaaff3f3f,0x3fffffff,0x1fdfffff, -0xefcfffde,0x1fdc7fff,0x1fff0000,0x1ffe2,0x800,0xc000000,0x4000,0xe000,0x1210,0x50,0x292,0x333e005,0x333,0xf000,0x3c0f,0x38000, -0x80000000,0xfc00,0x55555000,0x36db02a5,0x46100000,0x47900000,0x3ff08000,0xc0000000,0x30000,0x3ffff,0x3800,0x80000,1,0xc19d0000,2,0x400000, -0x4000035,0x4108000,0x5f7ffc00,0x7fdb +0x9fc80005,0x3d9f,0x20000,0xffff0000,0x7ff,0xff800,0xfbc00000,0x3eef,0xe000000,0xfff00000,0xfffffffb,0x10120200,0xff1e2000,0x10000000,0xb0002000,0x10480000, +0x4e002000,0x2000,0x30002000,0x602100,0x24000400,0x7000000,0xf00,0x3000000,0x2a00000,0x3d7e0000,0xdf,0x40,0x6800000,0xe0000000,0x100000,0x20040000, +0x200,0x1800000,0x9fe00001,0x3fff0000,0x10,0xc00,0xc0040,0x800000,0xfff70000,0x31021fd,0xf83fffff,0xbffffff,0x3ffffff,0x3f3fffff,0xaaff3f3f,0x3fffffff, +0x1fdfffff,0xefcfffde,0x1fdc7fff,0x1fff0000,0x1ffe2,0x800,0xc000000,0x4000,0xe000,0x1210,0x50,0x292,0x333e005,0x333,0xf000,0x3c0f, +0x38000,0x80000000,0xfc00,0x55555000,0x36db02a5,0x46100000,0x47900000,0x3ff08000,0xc0000000,0x30000,0x3ffff,0x3800,0x80000,1,0xc19d0000,2, +0x400000,0x40000b5,0x5108000,0x5f7ffc00,0x7fdb }; U_NAMESPACE_END diff --git a/deps/icu-small/source/i18n/collationfcd.h b/deps/icu-small/source/i18n/collationfcd.h index f4cc8a170e..150f4880c9 100644 --- a/deps/icu-small/source/i18n/collationfcd.h +++ b/deps/icu-small/source/i18n/collationfcd.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2012-2014, International Business Machines diff --git a/deps/icu-small/source/i18n/collationiterator.cpp b/deps/icu-small/source/i18n/collationiterator.cpp index 86199bcd17..e6e8f27e2f 100644 --- a/deps/icu-small/source/i18n/collationiterator.cpp +++ b/deps/icu-small/source/i18n/collationiterator.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2010-2014, International Business Machines diff --git a/deps/icu-small/source/i18n/collationiterator.h b/deps/icu-small/source/i18n/collationiterator.h index a7b2cbfbce..0161f5a7b1 100644 --- a/deps/icu-small/source/i18n/collationiterator.h +++ b/deps/icu-small/source/i18n/collationiterator.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2010-2014, International Business Machines diff --git a/deps/icu-small/source/i18n/collationkeys.cpp b/deps/icu-small/source/i18n/collationkeys.cpp index 3fb1af1b36..91302285d6 100644 --- a/deps/icu-small/source/i18n/collationkeys.cpp +++ b/deps/icu-small/source/i18n/collationkeys.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2012-2015, International Business Machines diff --git a/deps/icu-small/source/i18n/collationkeys.h b/deps/icu-small/source/i18n/collationkeys.h index d1cc76f028..74b370e710 100644 --- a/deps/icu-small/source/i18n/collationkeys.h +++ b/deps/icu-small/source/i18n/collationkeys.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2012-2014, International Business Machines diff --git a/deps/icu-small/source/i18n/collationroot.cpp b/deps/icu-small/source/i18n/collationroot.cpp index 749f05c51c..f862e410b8 100644 --- a/deps/icu-small/source/i18n/collationroot.cpp +++ b/deps/icu-small/source/i18n/collationroot.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2012-2014, International Business Machines @@ -45,7 +47,7 @@ static UBool U_CALLCONV uprv_collation_root_cleanup() { U_CDECL_END -void +void U_CALLCONV CollationRoot::load(UErrorCode &errorCode) { if(U_FAILURE(errorCode)) { return; } LocalPointer<CollationTailoring> t(new CollationTailoring(NULL)); diff --git a/deps/icu-small/source/i18n/collationroot.h b/deps/icu-small/source/i18n/collationroot.h index 345fbe77eb..26e5071fff 100644 --- a/deps/icu-small/source/i18n/collationroot.h +++ b/deps/icu-small/source/i18n/collationroot.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2012-2014, International Business Machines @@ -34,7 +36,7 @@ public: static const CollationSettings *getSettings(UErrorCode &errorCode); private: - static void load(UErrorCode &errorCode); + static void U_CALLCONV load(UErrorCode &errorCode); }; U_NAMESPACE_END diff --git a/deps/icu-small/source/i18n/collationrootelements.cpp b/deps/icu-small/source/i18n/collationrootelements.cpp index c8fd0a09ff..638a2456c8 100644 --- a/deps/icu-small/source/i18n/collationrootelements.cpp +++ b/deps/icu-small/source/i18n/collationrootelements.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2013-2014, International Business Machines diff --git a/deps/icu-small/source/i18n/collationrootelements.h b/deps/icu-small/source/i18n/collationrootelements.h index df2a13df24..518a24fe4e 100644 --- a/deps/icu-small/source/i18n/collationrootelements.h +++ b/deps/icu-small/source/i18n/collationrootelements.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2013-2014, International Business Machines diff --git a/deps/icu-small/source/i18n/collationruleparser.cpp b/deps/icu-small/source/i18n/collationruleparser.cpp index 2d2e25fcb0..ea3ea66bc0 100644 --- a/deps/icu-small/source/i18n/collationruleparser.cpp +++ b/deps/icu-small/source/i18n/collationruleparser.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2013-2015, International Business Machines @@ -788,7 +790,7 @@ CollationRuleParser::readWords(int32_t i, UnicodeString &raw) const { return i; } if(PatternProps::isWhiteSpace(c)) { - raw.append(0x20); + raw.append(sp); i = skipWhiteSpace(i + 1); } else { raw.append(c); diff --git a/deps/icu-small/source/i18n/collationruleparser.h b/deps/icu-small/source/i18n/collationruleparser.h index 3c2b22c9dc..bd393c2b6a 100644 --- a/deps/icu-small/source/i18n/collationruleparser.h +++ b/deps/icu-small/source/i18n/collationruleparser.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2013-2014, International Business Machines diff --git a/deps/icu-small/source/i18n/collationsets.cpp b/deps/icu-small/source/i18n/collationsets.cpp index ab282d89c6..1188f31062 100644 --- a/deps/icu-small/source/i18n/collationsets.cpp +++ b/deps/icu-small/source/i18n/collationsets.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2013-2014, International Business Machines diff --git a/deps/icu-small/source/i18n/collationsets.h b/deps/icu-small/source/i18n/collationsets.h index 4f0a2b6dce..070d507ebd 100644 --- a/deps/icu-small/source/i18n/collationsets.h +++ b/deps/icu-small/source/i18n/collationsets.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2013-2014, International Business Machines diff --git a/deps/icu-small/source/i18n/collationsettings.cpp b/deps/icu-small/source/i18n/collationsettings.cpp index e3e76a4765..bc1d4e63f8 100644 --- a/deps/icu-small/source/i18n/collationsettings.cpp +++ b/deps/icu-small/source/i18n/collationsettings.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2013-2015, International Business Machines diff --git a/deps/icu-small/source/i18n/collationsettings.h b/deps/icu-small/source/i18n/collationsettings.h index d839de7e54..1522dd58be 100644 --- a/deps/icu-small/source/i18n/collationsettings.h +++ b/deps/icu-small/source/i18n/collationsettings.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2013-2015, International Business Machines diff --git a/deps/icu-small/source/i18n/collationtailoring.cpp b/deps/icu-small/source/i18n/collationtailoring.cpp index ba20cc871a..d1ffa306f1 100644 --- a/deps/icu-small/source/i18n/collationtailoring.cpp +++ b/deps/icu-small/source/i18n/collationtailoring.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2013-2015, International Business Machines diff --git a/deps/icu-small/source/i18n/collationtailoring.h b/deps/icu-small/source/i18n/collationtailoring.h index 2a9b3d566f..e463005e08 100644 --- a/deps/icu-small/source/i18n/collationtailoring.h +++ b/deps/icu-small/source/i18n/collationtailoring.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2013-2014, International Business Machines diff --git a/deps/icu-small/source/i18n/collationweights.cpp b/deps/icu-small/source/i18n/collationweights.cpp index dba362255e..9a7b9a9973 100644 --- a/deps/icu-small/source/i18n/collationweights.cpp +++ b/deps/icu-small/source/i18n/collationweights.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * diff --git a/deps/icu-small/source/i18n/collationweights.h b/deps/icu-small/source/i18n/collationweights.h index a32274b876..8f3f328547 100644 --- a/deps/icu-small/source/i18n/collationweights.h +++ b/deps/icu-small/source/i18n/collationweights.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * diff --git a/deps/icu-small/source/i18n/collunsafe.h b/deps/icu-small/source/i18n/collunsafe.h index 97a766db26..4819ad195a 100644 --- a/deps/icu-small/source/i18n/collunsafe.h +++ b/deps/icu-small/source/i18n/collunsafe.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html // collunsafe.h // Copyright (C) 2015-2016, International Business Machines Corporation and others. // All Rights Reserved. diff --git a/deps/icu-small/source/i18n/compactdecimalformat.cpp b/deps/icu-small/source/i18n/compactdecimalformat.cpp index 2004356e70..31a5123cb1 100644 --- a/deps/icu-small/source/i18n/compactdecimalformat.cpp +++ b/deps/icu-small/source/i18n/compactdecimalformat.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 1997-2015, International Business Machines Corporation and * @@ -39,7 +41,7 @@ static const char gNumberElementsTag[] = "NumberElements"; static const char gDecimalFormatTag[] = "decimalFormat"; static const char gPatternsShort[] = "patternsShort"; static const char gPatternsLong[] = "patternsLong"; -static const char gRoot[] = "root"; +static const char gLatnPath[] = "NumberElements/latn"; static const UChar u_0 = 0x30; static const UChar u_apos = 0x27; @@ -94,7 +96,13 @@ class CDFLocaleStyleData : public UMemory { // Compute cdfUnits = unitsByVariant[pluralVariant]. // Prefix and suffix to use at cdfUnits[log10(x)] UHashtable* unitsByVariant; - inline CDFLocaleStyleData() : unitsByVariant(NULL) {} + // A flag for whether or not this CDFLocaleStyleData was loaded from the + // Latin numbering system as a fallback from the locale numbering system. + // This value is meaningless if the object is bogus or empty. + UBool fromFallback; + inline CDFLocaleStyleData() : unitsByVariant(NULL), fromFallback(FALSE) { + uprv_memset(divisors, 0, sizeof(divisors)); + } ~CDFLocaleStyleData(); // Init initializes this object. void Init(UErrorCode& status); @@ -102,6 +110,9 @@ class CDFLocaleStyleData : public UMemory { return unitsByVariant == NULL; } void setToBogus(); + UBool isEmpty() { + return unitsByVariant == NULL || unitsByVariant->count == 0; + } private: CDFLocaleStyleData(const CDFLocaleStyleData&); CDFLocaleStyleData& operator=(const CDFLocaleStyleData&); @@ -146,15 +157,12 @@ static const CDFLocaleStyleData* getCDFLocaleStyleData(const Locale& inLocale, U static const CDFLocaleStyleData* extractDataByStyleEnum(const CDFLocaleData& data, UNumberCompactStyle style, UErrorCode& status); static CDFLocaleData* loadCDFLocaleData(const Locale& inLocale, UErrorCode& status); -static void initCDFLocaleData(const Locale& inLocale, CDFLocaleData* result, UErrorCode& status); -static UResourceBundle* tryGetDecimalFallback(const UResourceBundle* numberSystemResource, const char* style, UResourceBundle** fillIn, FallbackFlags flags, UErrorCode& status); -static UResourceBundle* tryGetByKeyWithFallback(const UResourceBundle* rb, const char* path, UResourceBundle** fillIn, FallbackFlags flags, UErrorCode& status); -static UBool isRoot(const UResourceBundle* rb, UErrorCode& status); -static void initCDFLocaleStyleData(const UResourceBundle* decimalFormatBundle, CDFLocaleStyleData* result, UErrorCode& status); -static void populatePower10(const UResourceBundle* power10Bundle, CDFLocaleStyleData* result, UErrorCode& status); -static int32_t populatePrefixSuffix(const char* variant, int32_t log10Value, const UnicodeString& formatStr, UHashtable* result, UErrorCode& status); +static void load(const Locale& inLocale, CDFLocaleData* result, UErrorCode& status); +static int32_t populatePrefixSuffix(const char* variant, int32_t log10Value, const UnicodeString& formatStr, UHashtable* result, UBool overwrite, UErrorCode& status); +static double calculateDivisor(double power10, int32_t numZeros); static UBool onlySpaces(UnicodeString u); static void fixQuotes(UnicodeString& s); +static void checkForOtherVariants(CDFLocaleStyleData* result, UErrorCode& status); static void fillInMissing(CDFLocaleStyleData* result); static int32_t computeLog10(double x, UBool inRange); static CDFUnit* createCDFUnit(const char* variant, int32_t log10Value, UHashtable* table, UErrorCode& status); @@ -345,7 +353,7 @@ CompactDecimalFormat::format( UnicodeString& CompactDecimalFormat::format( - const StringPiece& /* number */, + StringPiece /* number */, UnicodeString& appendTo, FieldPositionIterator* /* posIter */, UErrorCode& status) const { @@ -518,7 +526,8 @@ static CDFLocaleData* loadCDFLocaleData(const Locale& inLocale, UErrorCode& stat return NULL; } - initCDFLocaleData(inLocale, result, status); + load(inLocale, result, status); + if (U_FAILURE(status)) { delete result; return NULL; @@ -526,278 +535,226 @@ static CDFLocaleData* loadCDFLocaleData(const Locale& inLocale, UErrorCode& stat return result; } -// initCDFLocaleData initializes result with data from CLDR. -// inLocale is the locale, the CLDR data is stored in result. -// We load the UNUM_SHORT and UNUM_LONG data looking first in local numbering -// system and not including root locale in fallback. Next we try in the latn -// numbering system where we fallback all the way to root. If we don't find -// UNUM_SHORT data in these three places, we report an error. If we find -// UNUM_SHORT data before finding UNUM_LONG data we make UNUM_LONG data fall -// back to UNUM_SHORT data. -static void initCDFLocaleData(const Locale& inLocale, CDFLocaleData* result, UErrorCode& status) { - LocalPointer<NumberingSystem> ns(NumberingSystem::createInstance(inLocale, status)); - if (U_FAILURE(status)) { - return; - } - const char* numberingSystemName = ns->getName(); - UResourceBundle* rb = ures_open(NULL, inLocale.getName(), &status); - rb = ures_getByKeyWithFallback(rb, gNumberElementsTag, rb, &status); - if (U_FAILURE(status)) { - ures_close(rb); - return; - } - UResourceBundle* shortDataFillIn = NULL; - UResourceBundle* longDataFillIn = NULL; - UResourceBundle* shortData = NULL; - UResourceBundle* longData = NULL; +namespace { - if (uprv_strcmp(numberingSystemName, gLatnTag) != 0) { - LocalUResourceBundlePointer localResource( - tryGetByKeyWithFallback(rb, numberingSystemName, NULL, NOT_ROOT, status)); - shortData = tryGetDecimalFallback( - localResource.getAlias(), gPatternsShort, &shortDataFillIn, NOT_ROOT, status); - longData = tryGetDecimalFallback( - localResource.getAlias(), gPatternsLong, &longDataFillIn, NOT_ROOT, status); - } - if (U_FAILURE(status)) { - ures_close(shortDataFillIn); - ures_close(longDataFillIn); - ures_close(rb); - return; - } +struct CmptDecDataSink : public ResourceSink { + + CDFLocaleData& dataBundle; // Where to save values when they are read + UBool isLatin; // Whether or not we are traversing the Latin tree + UBool isFallback; // Whether or not we are traversing the Latin tree as fallback + + enum EPatternsTableKey { PATTERNS_SHORT, PATTERNS_LONG }; + enum EFormatsTableKey { DECIMAL_FORMAT, CURRENCY_FORMAT }; - // If we haven't found UNUM_SHORT look in latn numbering system. We must - // succeed at finding UNUM_SHORT here. - if (shortData == NULL) { - LocalUResourceBundlePointer latnResource(tryGetByKeyWithFallback(rb, gLatnTag, NULL, MUST, status)); - shortData = tryGetDecimalFallback(latnResource.getAlias(), gPatternsShort, &shortDataFillIn, MUST, status); - if (longData == NULL) { - longData = tryGetDecimalFallback(latnResource.getAlias(), gPatternsLong, &longDataFillIn, ANY, status); - if (longData != NULL && isRoot(longData, status) && !isRoot(shortData, status)) { - longData = NULL; + /* + * NumberElements{ <-- top (numbering system table) + * latn{ <-- patternsTable (one per numbering system) + * patternsLong{ <-- formatsTable (one per pattern) + * decimalFormat{ <-- powersOfTenTable (one per format) + * 1000{ <-- pluralVariantsTable (one per power of ten) + * one{"0 thousand"} <-- plural variant and template + */ + + CmptDecDataSink(CDFLocaleData& _dataBundle) + : dataBundle(_dataBundle), isLatin(FALSE), isFallback(FALSE) {} + virtual ~CmptDecDataSink(); + + virtual void put(const char *key, ResourceValue &value, UBool isRoot, UErrorCode &errorCode) { + // SPECIAL CASE: Don't consume root in the non-Latin numbering system + if (isRoot && !isLatin) { return; } + + ResourceTable patternsTable = value.getTable(errorCode); + if (U_FAILURE(errorCode)) { return; } + for (int i1 = 0; patternsTable.getKeyAndValue(i1, key, value); ++i1) { + + // Check for patternsShort or patternsLong + EPatternsTableKey patternsTableKey; + if (uprv_strcmp(key, gPatternsShort) == 0) { + patternsTableKey = PATTERNS_SHORT; + } else if (uprv_strcmp(key, gPatternsLong) == 0) { + patternsTableKey = PATTERNS_LONG; + } else { + continue; } - } - } - initCDFLocaleStyleData(shortData, &result->shortData, status); - ures_close(shortDataFillIn); - if (U_FAILURE(status)) { - ures_close(longDataFillIn); - ures_close(rb); - } - if (longData == NULL) { - result->longData.setToBogus(); - } else { - initCDFLocaleStyleData(longData, &result->longData, status); - } - ures_close(longDataFillIn); - ures_close(rb); -} - -/** - * tryGetDecimalFallback attempts to fetch the "decimalFormat" resource bundle - * with a particular style. style is either "patternsShort" or "patternsLong." - * FillIn, flags, and status work in the same way as in tryGetByKeyWithFallback. - */ -static UResourceBundle* tryGetDecimalFallback(const UResourceBundle* numberSystemResource, const char* style, UResourceBundle** fillIn, FallbackFlags flags, UErrorCode& status) { - UResourceBundle* first = tryGetByKeyWithFallback(numberSystemResource, style, fillIn, flags, status); - UResourceBundle* second = tryGetByKeyWithFallback(first, gDecimalFormatTag, fillIn, flags, status); - if (fillIn == NULL) { - ures_close(first); - } - return second; -} - -// tryGetByKeyWithFallback returns a sub-resource bundle that matches given -// criteria or NULL if none found. rb is the resource bundle that we are -// searching. If rb == NULL then this function behaves as if no sub-resource -// is found; path is the key of the sub-resource, -// (i.e "foo" but not "foo/bar"); If fillIn is NULL, caller must always call -// ures_close() on returned resource. See below for example when fillIn is -// not NULL. flags is ANY or NOT_ROOT. Optionally, these values -// can be ored with MUST. MUST by itself is the same as ANY | MUST. -// The locale of the returned sub-resource will either match the -// flags or the returned sub-resouce will be NULL. If MUST is included in -// flags, and not suitable sub-resource is found then in addition to returning -// NULL, this function also sets status to U_MISSING_RESOURCE_ERROR. If MUST -// is not included in flags, then this function just returns NULL if no -// such sub-resource is found and will never set status to -// U_MISSING_RESOURCE_ERROR. -// -// Example: This code first searches for "foo/bar" sub-resource without falling -// back to ROOT. Then searches for "baz" sub-resource as last resort. -// -// UResourcebundle* fillIn = NULL; -// UResourceBundle* data = tryGetByKeyWithFallback(rb, "foo", &fillIn, NON_ROOT, status); -// data = tryGetByKeyWithFallback(data, "bar", &fillIn, NON_ROOT, status); -// if (!data) { -// data = tryGetbyKeyWithFallback(rb, "baz", &fillIn, MUST, status); -// } -// if (U_FAILURE(status)) { -// ures_close(fillIn); -// return; -// } -// doStuffWithNonNullSubresource(data); -// -// /* Wrong! don't do the following as it can leak memory if fillIn gets set -// to NULL. */ -// fillIn = tryGetByKeyWithFallback(rb, "wrong", &fillIn, ANY, status); -// -// ures_close(fillIn); -// -static UResourceBundle* tryGetByKeyWithFallback(const UResourceBundle* rb, const char* path, UResourceBundle** fillIn, FallbackFlags flags, UErrorCode& status) { - if (U_FAILURE(status)) { - return NULL; - } - UBool must = (flags & MUST); - if (rb == NULL) { - if (must) { - status = U_MISSING_RESOURCE_ERROR; - } - return NULL; - } - UResourceBundle* result = NULL; - UResourceBundle* ownedByUs = NULL; - if (fillIn == NULL) { - ownedByUs = ures_getByKeyWithFallback(rb, path, NULL, &status); - result = ownedByUs; - } else { - *fillIn = ures_getByKeyWithFallback(rb, path, *fillIn, &status); - result = *fillIn; - } - if (U_FAILURE(status)) { - ures_close(ownedByUs); - if (status == U_MISSING_RESOURCE_ERROR && !must) { - status = U_ZERO_ERROR; - } - return NULL; - } - flags = (FallbackFlags) (flags & ~MUST); - switch (flags) { - case NOT_ROOT: - { - UBool bRoot = isRoot(result, status); - if (bRoot || U_FAILURE(status)) { - ures_close(ownedByUs); - if (must && (status == U_ZERO_ERROR)) { - status = U_MISSING_RESOURCE_ERROR; + // Traverse into the formats table + ResourceTable formatsTable = value.getTable(errorCode); + if (U_FAILURE(errorCode)) { return; } + for (int i2 = 0; formatsTable.getKeyAndValue(i2, key, value); ++i2) { + + // Check for decimalFormat or currencyFormat + EFormatsTableKey formatsTableKey; + if (uprv_strcmp(key, gDecimalFormatTag) == 0) { + formatsTableKey = DECIMAL_FORMAT; + // TODO: Enable this statement when currency support is added + // } else if (uprv_strcmp(key, gCurrencyFormat) == 0) { + // formatsTableKey = CURRENCY_FORMAT; + } else { + continue; + } + + // Set the current style and destination based on the two keys + UNumberCompactStyle style; + CDFLocaleStyleData* destination = NULL; + if (patternsTableKey == PATTERNS_LONG + && formatsTableKey == DECIMAL_FORMAT) { + style = UNUM_LONG; + destination = &dataBundle.longData; + } else if (patternsTableKey == PATTERNS_SHORT + && formatsTableKey == DECIMAL_FORMAT) { + style = UNUM_SHORT; + destination = &dataBundle.shortData; + // TODO: Enable the following statements when currency support is added + // } else if (patternsTableKey == PATTERNS_SHORT + // && formatsTableKey == CURRENCY_FORMAT) { + // style = UNUM_SHORT_CURRENCY; // or whatever the enum gets named + // destination = &dataBundle.shortCurrencyData; + // } else { + // // Silently ignore this case + // continue; + } + + // SPECIAL CASE: RULES FOR WHETHER OR NOT TO CONSUME THIS TABLE: + // 1) Don't consume longData if shortData was consumed from the non-Latin + // locale numbering system + // 2) Don't consume longData for the first time if this is the root bundle and + // shortData is already populated from a more specific locale. Note that if + // both longData and shortData are both only in root, longData will be + // consumed since it is alphabetically before shortData in the bundle. + if (isFallback + && style == UNUM_LONG + && !dataBundle.shortData.isEmpty() + && !dataBundle.shortData.fromFallback) { + continue; + } + if (isRoot + && style == UNUM_LONG + && dataBundle.longData.isEmpty() + && !dataBundle.shortData.isEmpty()) { + continue; + } + + // Set the "fromFallback" flag on the data object + destination->fromFallback = isFallback; + + // Traverse into the powers of ten table + ResourceTable powersOfTenTable = value.getTable(errorCode); + if (U_FAILURE(errorCode)) { return; } + for (int i3 = 0; powersOfTenTable.getKeyAndValue(i3, key, value); ++i3) { + + // The key will always be some even power of 10. e.g 10000. + char* endPtr = NULL; + double power10 = uprv_strtod(key, &endPtr); + if (*endPtr != 0) { + errorCode = U_INTERNAL_PROGRAM_ERROR; + return; + } + int32_t log10Value = computeLog10(power10, FALSE); + + // Silently ignore divisors that are too big. + if (log10Value >= MAX_DIGITS) continue; + + // Iterate over the plural variants ("one", "other", etc) + ResourceTable pluralVariantsTable = value.getTable(errorCode); + if (U_FAILURE(errorCode)) { return; } + for (int i4 = 0; pluralVariantsTable.getKeyAndValue(i4, key, value); ++i4) { + const char* pluralVariant = key; + const UnicodeString formatStr = value.getUnicodeString(errorCode); + + // Copy the data into the in-memory data bundle (do not overwrite + // existing values) + int32_t numZeros = populatePrefixSuffix( + pluralVariant, log10Value, formatStr, + destination->unitsByVariant, FALSE, errorCode); + + // If populatePrefixSuffix returns -1, it means that this key has been + // encountered already. + if (numZeros < 0) { + continue; + } + + // Set the divisor, which is based on the number of zeros in the template + // string. If the divisor from here is different from the one previously + // stored, it means that the number of zeros in different plural variants + // differs; throw an exception. + // TODO: How should I check for floating-point errors here? + // Is there a good reason why "divisor" is double and not long like Java? + double divisor = calculateDivisor(power10, numZeros); + if (destination->divisors[log10Value] != 0.0 + && destination->divisors[log10Value] != divisor) { + errorCode = U_INTERNAL_PROGRAM_ERROR; + return; + } + destination->divisors[log10Value] = divisor; } - return NULL; } - return result; } - case ANY: - return result; - default: - ures_close(ownedByUs); - status = U_ILLEGAL_ARGUMENT_ERROR; - return NULL; + } } -} +}; -static UBool isRoot(const UResourceBundle* rb, UErrorCode& status) { - const char* actualLocale = ures_getLocaleByType( - rb, ULOC_ACTUAL_LOCALE, &status); - if (U_FAILURE(status)) { - return FALSE; - } - return uprv_strcmp(actualLocale, gRoot) == 0; -} +// Virtual destructors must be defined out of line. +CmptDecDataSink::~CmptDecDataSink() {} +} // namespace -// initCDFLocaleStyleData loads formatting data for a particular style. -// decimalFormatBundle is the "decimalFormat" resource bundle in CLDR. -// Loaded data stored in result. -static void initCDFLocaleStyleData(const UResourceBundle* decimalFormatBundle, CDFLocaleStyleData* result, UErrorCode& status) { +static void load(const Locale& inLocale, CDFLocaleData* result, UErrorCode& status) { + LocalPointer<NumberingSystem> ns(NumberingSystem::createInstance(inLocale, status)); if (U_FAILURE(status)) { return; } - // Iterate through all the powers of 10. - int32_t size = ures_getSize(decimalFormatBundle); - UResourceBundle* power10 = NULL; - for (int32_t i = 0; i < size; ++i) { - power10 = ures_getByIndex(decimalFormatBundle, i, power10, &status); - if (U_FAILURE(status)) { - ures_close(power10); - return; - } - populatePower10(power10, result, status); - if (U_FAILURE(status)) { - ures_close(power10); - return; - } - } - ures_close(power10); - fillInMissing(result); -} + const char* nsName = ns->getName(); -// populatePower10 grabs data for a particular power of 10 from CLDR. -// The loaded data is stored in result. -static void populatePower10(const UResourceBundle* power10Bundle, CDFLocaleStyleData* result, UErrorCode& status) { + LocalUResourceBundlePointer resource(ures_open(NULL, inLocale.getName(), &status)); if (U_FAILURE(status)) { return; } - char* endPtr = NULL; - double power10 = uprv_strtod(ures_getKey(power10Bundle), &endPtr); - if (*endPtr != 0) { - status = U_INTERNAL_PROGRAM_ERROR; - return; - } - int32_t log10Value = computeLog10(power10, FALSE); - // Silently ignore divisors that are too big. - if (log10Value == MAX_DIGITS) { - return; - } - int32_t size = ures_getSize(power10Bundle); - int32_t numZeros = 0; - UBool otherVariantDefined = FALSE; - UResourceBundle* variantBundle = NULL; - // Iterate over all the plural variants for the power of 10 - for (int32_t i = 0; i < size; ++i) { - variantBundle = ures_getByIndex(power10Bundle, i, variantBundle, &status); - if (U_FAILURE(status)) { - ures_close(variantBundle); - return; - } - const char* variant = ures_getKey(variantBundle); - int32_t resLen; - const UChar* formatStrP = ures_getString(variantBundle, &resLen, &status); - if (U_FAILURE(status)) { - ures_close(variantBundle); - return; - } - UnicodeString formatStr(false, formatStrP, resLen); - if (uprv_strcmp(variant, gOther) == 0) { - otherVariantDefined = TRUE; - } - int32_t nz = populatePrefixSuffix( - variant, log10Value, formatStr, result->unitsByVariant, status); - if (U_FAILURE(status)) { - ures_close(variantBundle); + CmptDecDataSink sink(*result); + sink.isFallback = FALSE; + + // First load the number elements data if nsName is not Latin. + if (uprv_strcmp(nsName, gLatnTag) != 0) { + sink.isLatin = FALSE; + CharString path; + path.append(gNumberElementsTag, status) + .append('/', status) + .append(nsName, status); + ures_getAllItemsWithFallback(resource.getAlias(), path.data(), sink, status); + if (status == U_MISSING_RESOURCE_ERROR) { + // Silently ignore and use Latin + status = U_ZERO_ERROR; + } else if (U_FAILURE(status)) { return; } - if (nz != numZeros) { - // We expect all format strings to have the same number of 0's - // left of the decimal point. - if (numZeros != 0) { - status = U_INTERNAL_PROGRAM_ERROR; - ures_close(variantBundle); - return; - } - numZeros = nz; - } + sink.isFallback = TRUE; } - ures_close(variantBundle); - // We expect to find an OTHER variant for each power of 10. - if (!otherVariantDefined) { - status = U_INTERNAL_PROGRAM_ERROR; - return; + + // Now load Latin. + sink.isLatin = TRUE; + ures_getAllItemsWithFallback(resource.getAlias(), gLatnPath, sink, status); + if (U_FAILURE(status)) return; + + // If longData is empty, default it to be equal to shortData + if (result->longData.isEmpty()) { + result->longData.setToBogus(); } - double divisor = power10; - for (int32_t i = 1; i < numZeros; ++i) { - divisor /= 10.0; + + // Check for "other" variants in each of the three data classes, and resolve missing elements. + + if (!result->longData.isBogus()) { + checkForOtherVariants(&result->longData, status); + if (U_FAILURE(status)) return; + fillInMissing(&result->longData); } - result->divisors[log10Value] = divisor; + + checkForOtherVariants(&result->shortData, status); + if (U_FAILURE(status)) return; + fillInMissing(&result->shortData); + + // TODO: Enable this statement when currency support is added + // checkForOtherVariants(&result->shortCurrencyData, status); + // if (U_FAILURE(status)) return; + // fillInMissing(&result->shortCurrencyData); } // populatePrefixSuffix Adds a specific prefix-suffix pair to result for a @@ -810,7 +767,7 @@ static void populatePower10(const UResourceBundle* power10Bundle, CDFLocaleStyle // In the special case that formatStr contains only spaces for prefix // and suffix, populatePrefixSuffix returns log10Value + 1. static int32_t populatePrefixSuffix( - const char* variant, int32_t log10Value, const UnicodeString& formatStr, UHashtable* result, UErrorCode& status) { + const char* variant, int32_t log10Value, const UnicodeString& formatStr, UHashtable* result, UBool overwrite, UErrorCode& status) { if (U_FAILURE(status)) { return 0; } @@ -825,6 +782,13 @@ static int32_t populatePrefixSuffix( if (U_FAILURE(status)) { return 0; } + + // Return -1 if we are not overwriting an existing value + if (unit->isSet() && !overwrite) { + return -1; + } + unit->markAsSet(); + // Everything up to first 0 is the prefix unit->prefix = formatStr.tempSubString(0, firstIdx); fixQuotes(unit->prefix); @@ -846,6 +810,16 @@ static int32_t populatePrefixSuffix( return (idx - firstIdx); } +// Calculate a divisor based on the magnitude and number of zeros in the +// template string. +static double calculateDivisor(double power10, int32_t numZeros) { + double divisor = power10; + for (int32_t i = 1; i < numZeros; ++i) { + divisor /= 10.0; + } + return divisor; +} + static UBool onlySpaces(UnicodeString u) { return u.trim().length() == 0; } @@ -884,6 +858,38 @@ static void fixQuotes(UnicodeString& s) { s.truncate(dest); } +// Checks to make sure that an "other" variant is present in all +// powers of 10. +static void checkForOtherVariants(CDFLocaleStyleData* result, + UErrorCode& status) { + if (result == NULL || result->unitsByVariant == NULL) { + return; + } + + const CDFUnit* otherByBase = + (const CDFUnit*) uhash_get(result->unitsByVariant, gOther); + if (otherByBase == NULL) { + status = U_INTERNAL_PROGRAM_ERROR; + return; + } + + // Check all other plural variants, and make sure that if + // any of them are populated, then other is also populated + int32_t pos = UHASH_FIRST; + const UHashElement* element; + while ((element = uhash_nextElement(result->unitsByVariant, &pos)) != NULL) { + CDFUnit* variantsByBase = (CDFUnit*) element->value.pointer; + if (variantsByBase == otherByBase) continue; + for (int32_t log10Value = 0; log10Value < MAX_DIGITS; ++log10Value) { + if (variantsByBase[log10Value].isSet() + && !otherByBase[log10Value].isSet()) { + status = U_INTERNAL_PROGRAM_ERROR; + return; + } + } + } +} + // fillInMissing ensures that the data in result is complete. // result data is complete if for each variant in result, there exists // a prefix-suffix pair for each log10 value and there also exists @@ -973,7 +979,6 @@ static CDFUnit* createCDFUnit(const char* variant, int32_t log10Value, UHashtabl } } CDFUnit* result = &cdfUnit[log10Value]; - result->markAsSet(); return result; } diff --git a/deps/icu-small/source/i18n/coptccal.cpp b/deps/icu-small/source/i18n/coptccal.cpp index 1996327a6f..ce531ca0e8 100644 --- a/deps/icu-small/source/i18n/coptccal.cpp +++ b/deps/icu-small/source/i18n/coptccal.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2003 - 2013, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/coptccal.h b/deps/icu-small/source/i18n/coptccal.h index 47c952868b..523769fabe 100644 --- a/deps/icu-small/source/i18n/coptccal.h +++ b/deps/icu-small/source/i18n/coptccal.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2003 - 2013, International Business Machines Corporation and * diff --git a/deps/icu-small/source/i18n/cpdtrans.cpp b/deps/icu-small/source/i18n/cpdtrans.cpp index 3798a6de02..b6e328f92c 100644 --- a/deps/icu-small/source/i18n/cpdtrans.cpp +++ b/deps/icu-small/source/i18n/cpdtrans.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 1999-2011, International Business Machines diff --git a/deps/icu-small/source/i18n/cpdtrans.h b/deps/icu-small/source/i18n/cpdtrans.h index 004f04fd63..6f832df883 100644 --- a/deps/icu-small/source/i18n/cpdtrans.h +++ b/deps/icu-small/source/i18n/cpdtrans.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 1999-2011, International Business Machines diff --git a/deps/icu-small/source/i18n/csdetect.cpp b/deps/icu-small/source/i18n/csdetect.cpp index 94d440090c..8ddbe8129b 100644 --- a/deps/icu-small/source/i18n/csdetect.cpp +++ b/deps/icu-small/source/i18n/csdetect.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2005-2016, International Business Machines diff --git a/deps/icu-small/source/i18n/csdetect.h b/deps/icu-small/source/i18n/csdetect.h index bbe81c8016..d0dc0d2077 100644 --- a/deps/icu-small/source/i18n/csdetect.h +++ b/deps/icu-small/source/i18n/csdetect.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2005-2016, International Business Machines diff --git a/deps/icu-small/source/i18n/csmatch.cpp b/deps/icu-small/source/i18n/csmatch.cpp index b2c8544fc5..ea8d37cd20 100644 --- a/deps/icu-small/source/i18n/csmatch.cpp +++ b/deps/icu-small/source/i18n/csmatch.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2005-2012, International Business Machines diff --git a/deps/icu-small/source/i18n/csmatch.h b/deps/icu-small/source/i18n/csmatch.h index 19a285262d..a94b86ae7c 100644 --- a/deps/icu-small/source/i18n/csmatch.h +++ b/deps/icu-small/source/i18n/csmatch.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2005-2012, International Business Machines diff --git a/deps/icu-small/source/i18n/csr2022.cpp b/deps/icu-small/source/i18n/csr2022.cpp index 5ba30d53c4..9566ee4796 100644 --- a/deps/icu-small/source/i18n/csr2022.cpp +++ b/deps/icu-small/source/i18n/csr2022.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2005-2016, International Business Machines diff --git a/deps/icu-small/source/i18n/csr2022.h b/deps/icu-small/source/i18n/csr2022.h index ba5e5e011e..9ff2648505 100644 --- a/deps/icu-small/source/i18n/csr2022.h +++ b/deps/icu-small/source/i18n/csr2022.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2005-2015, International Business Machines diff --git a/deps/icu-small/source/i18n/csrecog.cpp b/deps/icu-small/source/i18n/csrecog.cpp index 7535e9aa66..7ae7765399 100644 --- a/deps/icu-small/source/i18n/csrecog.cpp +++ b/deps/icu-small/source/i18n/csrecog.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2005-2006, International Business Machines diff --git a/deps/icu-small/source/i18n/csrecog.h b/deps/icu-small/source/i18n/csrecog.h index 97d3af7ad1..1759ca561b 100644 --- a/deps/icu-small/source/i18n/csrecog.h +++ b/deps/icu-small/source/i18n/csrecog.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2005-2012, International Business Machines diff --git a/deps/icu-small/source/i18n/csrmbcs.cpp b/deps/icu-small/source/i18n/csrmbcs.cpp index 1963bf85ab..d61269f5e3 100644 --- a/deps/icu-small/source/i18n/csrmbcs.cpp +++ b/deps/icu-small/source/i18n/csrmbcs.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2005-2016, International Business Machines diff --git a/deps/icu-small/source/i18n/csrmbcs.h b/deps/icu-small/source/i18n/csrmbcs.h index 9ea9d8f8ee..6a49a85972 100644 --- a/deps/icu-small/source/i18n/csrmbcs.h +++ b/deps/icu-small/source/i18n/csrmbcs.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2005-2012, International Business Machines diff --git a/deps/icu-small/source/i18n/csrsbcs.cpp b/deps/icu-small/source/i18n/csrsbcs.cpp index 803105c24a..48e7dc5123 100644 --- a/deps/icu-small/source/i18n/csrsbcs.cpp +++ b/deps/icu-small/source/i18n/csrsbcs.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2005-2016, International Business Machines diff --git a/deps/icu-small/source/i18n/csrsbcs.h b/deps/icu-small/source/i18n/csrsbcs.h index b4897b1cee..2f967dd9c2 100644 --- a/deps/icu-small/source/i18n/csrsbcs.h +++ b/deps/icu-small/source/i18n/csrsbcs.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2005-2015, International Business Machines diff --git a/deps/icu-small/source/i18n/csrucode.cpp b/deps/icu-small/source/i18n/csrucode.cpp index 3780c3b3e6..201b2996c7 100644 --- a/deps/icu-small/source/i18n/csrucode.cpp +++ b/deps/icu-small/source/i18n/csrucode.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2005-2013, International Business Machines diff --git a/deps/icu-small/source/i18n/csrucode.h b/deps/icu-small/source/i18n/csrucode.h index 458b2c96ad..10e5fafe66 100644 --- a/deps/icu-small/source/i18n/csrucode.h +++ b/deps/icu-small/source/i18n/csrucode.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2005-2012, International Business Machines diff --git a/deps/icu-small/source/i18n/csrutf8.cpp b/deps/icu-small/source/i18n/csrutf8.cpp index 6dd874e0ba..4f29fa2af7 100644 --- a/deps/icu-small/source/i18n/csrutf8.cpp +++ b/deps/icu-small/source/i18n/csrutf8.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2005-2014, International Business Machines diff --git a/deps/icu-small/source/i18n/csrutf8.h b/deps/icu-small/source/i18n/csrutf8.h index 79a424b7c0..71309eade7 100644 --- a/deps/icu-small/source/i18n/csrutf8.h +++ b/deps/icu-small/source/i18n/csrutf8.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2005-2012, International Business Machines diff --git a/deps/icu-small/source/i18n/curramt.cpp b/deps/icu-small/source/i18n/curramt.cpp index 195d5f30f4..4475ff611e 100644 --- a/deps/icu-small/source/i18n/curramt.cpp +++ b/deps/icu-small/source/i18n/curramt.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2004, International Business Machines diff --git a/deps/icu-small/source/i18n/currfmt.cpp b/deps/icu-small/source/i18n/currfmt.cpp index 23a7d52aca..b92aa00e5c 100644 --- a/deps/icu-small/source/i18n/currfmt.cpp +++ b/deps/icu-small/source/i18n/currfmt.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2004-2014 International Business Machines diff --git a/deps/icu-small/source/i18n/currfmt.h b/deps/icu-small/source/i18n/currfmt.h index b3f23e56f9..83e0272465 100644 --- a/deps/icu-small/source/i18n/currfmt.h +++ b/deps/icu-small/source/i18n/currfmt.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2004-2014, International Business Machines diff --git a/deps/icu-small/source/i18n/currpinf.cpp b/deps/icu-small/source/i18n/currpinf.cpp index 9d8d524a0f..7c16fff961 100644 --- a/deps/icu-small/source/i18n/currpinf.cpp +++ b/deps/icu-small/source/i18n/currpinf.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2009-2014, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/currunit.cpp b/deps/icu-small/source/i18n/currunit.cpp index 64233aee7c..f538d65ada 100644 --- a/deps/icu-small/source/i18n/currunit.cpp +++ b/deps/icu-small/source/i18n/currunit.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2004-2014, International Business Machines diff --git a/deps/icu-small/source/i18n/dangical.cpp b/deps/icu-small/source/i18n/dangical.cpp index bfe15b59ed..3a7b2ebb8f 100644 --- a/deps/icu-small/source/i18n/dangical.cpp +++ b/deps/icu-small/source/i18n/dangical.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * Copyright (C) 2013, International Business Machines Corporation diff --git a/deps/icu-small/source/i18n/dangical.h b/deps/icu-small/source/i18n/dangical.h index cc35ca3f07..17a5004bdc 100644 --- a/deps/icu-small/source/i18n/dangical.h +++ b/deps/icu-small/source/i18n/dangical.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ***************************************************************************** * Copyright (C) 2013, International Business Machines Corporation diff --git a/deps/icu-small/source/i18n/datefmt.cpp b/deps/icu-small/source/i18n/datefmt.cpp index 048a4723ef..00f46cfdfd 100644 --- a/deps/icu-small/source/i18n/datefmt.cpp +++ b/deps/icu-small/source/i18n/datefmt.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 1997-2015, International Business Machines Corporation and * @@ -317,7 +319,7 @@ DateFormat::format(UDate date, UnicodeString& appendTo) const { // Note that any error information is just lost. That's okay // for this convenience method. - FieldPosition fpos(0); + FieldPosition fpos(FieldPosition::DONT_CARE); return format(date, appendTo, fpos); } diff --git a/deps/icu-small/source/i18n/dayperiodrules.cpp b/deps/icu-small/source/i18n/dayperiodrules.cpp index fb8ae8147f..30414823ef 100644 --- a/deps/icu-small/source/i18n/dayperiodrules.cpp +++ b/deps/icu-small/source/i18n/dayperiodrules.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2016, International Business Machines @@ -42,129 +44,90 @@ enum CutoffType { } // namespace -struct DayPeriodRulesDataSink : public ResourceTableSink { - // Initialize sub-sinks. - DayPeriodRulesDataSink() : - rulesSink(*this), ruleSetSink(*this), periodSink(*this), cutoffSink(*this) { +struct DayPeriodRulesDataSink : public ResourceSink { + DayPeriodRulesDataSink() { for (int32_t i = 0; i < UPRV_LENGTHOF(cutoffs); ++i) { cutoffs[i] = 0; } } virtual ~DayPeriodRulesDataSink(); - // Entry point. - virtual ResourceTableSink *getOrCreateTableSink(const char *key, int32_t, UErrorCode &errorCode) { - if (U_FAILURE(errorCode)) { return NULL; } - - if (uprv_strcmp(key, "locales") == 0) { - return &localesSink; - } else if (uprv_strcmp(key, "rules") == 0) { - // Allocate one more than needed to skip [0]. See comment in parseSetNum(). - data->rules = new DayPeriodRules[data->maxRuleSetNum + 1]; - if (data->rules == NULL) { - errorCode = U_MEMORY_ALLOCATION_ERROR; - return NULL; - } else { - return &rulesSink; + virtual void put(const char *key, ResourceValue &value, UBool, UErrorCode &errorCode) { + ResourceTable dayPeriodData = value.getTable(errorCode); + if (U_FAILURE(errorCode)) { return; } + + for (int32_t i = 0; dayPeriodData.getKeyAndValue(i, key, value); ++i) { + if (uprv_strcmp(key, "locales") == 0) { + ResourceTable locales = value.getTable(errorCode); + if (U_FAILURE(errorCode)) { return; } + + for (int32_t j = 0; locales.getKeyAndValue(j, key, value); ++j) { + UnicodeString setNum_str = value.getUnicodeString(errorCode); + int32_t setNum = parseSetNum(setNum_str, errorCode); + uhash_puti(data->localeToRuleSetNumMap, const_cast<char *>(key), setNum, &errorCode); + } + } else if (uprv_strcmp(key, "rules") == 0) { + // Allocate one more than needed to skip [0]. See comment in parseSetNum(). + data->rules = new DayPeriodRules[data->maxRuleSetNum + 1]; + if (data->rules == NULL) { + errorCode = U_MEMORY_ALLOCATION_ERROR; + return; + } + ResourceTable rules = value.getTable(errorCode); + processRules(rules, key, value, errorCode); + if (U_FAILURE(errorCode)) { return; } } } - return NULL; } - // Data root -> locales. - struct LocalesSink : public ResourceTableSink { - virtual ~LocalesSink(); + void processRules(const ResourceTable &rules, const char *key, + ResourceValue &value, UErrorCode &errorCode) { + if (U_FAILURE(errorCode)) { return; } - virtual void put(const char *key, const ResourceValue &value, UErrorCode &errorCode) { + for (int32_t i = 0; rules.getKeyAndValue(i, key, value); ++i) { + ruleSetNum = parseSetNum(key, errorCode); + ResourceTable ruleSet = value.getTable(errorCode); if (U_FAILURE(errorCode)) { return; } - UnicodeString setNum_str = value.getUnicodeString(errorCode); - int32_t setNum = parseSetNum(setNum_str, errorCode); - uhash_puti(data->localeToRuleSetNumMap, const_cast<char *>(key), setNum, &errorCode); - } - } localesSink; - - // Data root -> rules. - struct RulesSink : public ResourceTableSink { - DayPeriodRulesDataSink &outer; - RulesSink(DayPeriodRulesDataSink &outer) : outer(outer) {} - virtual ~RulesSink(); - - virtual ResourceTableSink *getOrCreateTableSink(const char *key, int32_t, UErrorCode &errorCode) { - if (U_FAILURE(errorCode)) { return NULL; } - - outer.ruleSetNum = parseSetNum(key, errorCode); - return &outer.ruleSetSink; - } - } rulesSink; - - // Data root -> rules -> a rule set. - struct RuleSetSink : public ResourceTableSink { - DayPeriodRulesDataSink &outer; - RuleSetSink(DayPeriodRulesDataSink &outer) : outer(outer) {} - virtual ~RuleSetSink(); - - virtual ResourceTableSink *getOrCreateTableSink(const char *key, int32_t, UErrorCode &errorCode) { - if (U_FAILURE(errorCode)) { return NULL; } - - outer.period = DayPeriodRules::getDayPeriodFromString(key); - if (outer.period == DayPeriodRules::DAYPERIOD_UNKNOWN) { - errorCode = U_INVALID_FORMAT_ERROR; - return NULL; + for (int32_t j = 0; ruleSet.getKeyAndValue(j, key, value); ++j) { + period = DayPeriodRules::getDayPeriodFromString(key); + if (period == DayPeriodRules::DAYPERIOD_UNKNOWN) { + errorCode = U_INVALID_FORMAT_ERROR; + return; + } + ResourceTable periodDefinition = value.getTable(errorCode); + if (U_FAILURE(errorCode)) { return; } + + for (int32_t k = 0; periodDefinition.getKeyAndValue(k, key, value); ++k) { + if (value.getType() == URES_STRING) { + // Key-value pairs (e.g. before{6:00}). + CutoffType type = getCutoffTypeFromString(key); + addCutoff(type, value.getUnicodeString(errorCode), errorCode); + if (U_FAILURE(errorCode)) { return; } + } else { + // Arrays (e.g. before{6:00, 24:00}). + cutoffType = getCutoffTypeFromString(key); + ResourceArray cutoffArray = value.getArray(errorCode); + if (U_FAILURE(errorCode)) { return; } + + int32_t length = cutoffArray.getSize(); + for (int32_t l = 0; l < length; ++l) { + cutoffArray.getValue(l, value); + addCutoff(cutoffType, value.getUnicodeString(errorCode), errorCode); + if (U_FAILURE(errorCode)) { return; } + } + } + } + setDayPeriodForHoursFromCutoffs(errorCode); + for (int32_t k = 0; k < UPRV_LENGTHOF(cutoffs); ++k) { + cutoffs[k] = 0; + } } - return &outer.periodSink; - } - - virtual void leave(UErrorCode &errorCode) { - if (U_FAILURE(errorCode)) { return; } - - if (!data->rules[outer.ruleSetNum].allHoursAreSet()) { + if (!data->rules[ruleSetNum].allHoursAreSet()) { errorCode = U_INVALID_FORMAT_ERROR; + return; } } - } ruleSetSink; - - // Data root -> rules -> a rule set -> a period (e.g. "morning1"). - // Key-value pairs (e.g. before{6:00}) will be captured here. - // Arrays (e.g. before{6:00, 24:00}) will be redirected to the next sink. - struct PeriodSink : public ResourceTableSink { - DayPeriodRulesDataSink &outer; - PeriodSink(DayPeriodRulesDataSink &outer) : outer(outer) {} - virtual ~PeriodSink(); - - virtual void put(const char *key, const ResourceValue &value, UErrorCode &errorCode) { - if (U_FAILURE(errorCode)) { return; } - - CutoffType type = getCutoffTypeFromString(key); - outer.addCutoff(type, value.getUnicodeString(errorCode), errorCode); - } - - virtual ResourceArraySink *getOrCreateArraySink(const char *key, int32_t, UErrorCode &errorCode) { - if (U_FAILURE(errorCode)) { return NULL; } - outer.cutoffType = getCutoffTypeFromString(key); - return &outer.cutoffSink; - } - - virtual void leave(UErrorCode &errorCode) { - if (U_FAILURE(errorCode)) { return; } - - outer.setDayPeriodForHoursFromCutoffs(errorCode); - for (int32_t i = 0; i < UPRV_LENGTHOF(outer.cutoffs); ++i) { - outer.cutoffs[i] = 0; - } - } - } periodSink; - - // Data root -> rules -> a rule set -> a period -> a cutoff type. - // Will enter this sink if 2+ times appear in a single cutoff type (e.g. before{6:00, 24:00}). - struct CutoffSink : public ResourceArraySink { - DayPeriodRulesDataSink &outer; - CutoffSink(DayPeriodRulesDataSink &outer) : outer(outer) {} - virtual ~CutoffSink(); - - virtual void put(int32_t, const ResourceValue &value, UErrorCode &errorCode) { - outer.addCutoff(outer.cutoffType, value.getUnicodeString(errorCode), errorCode); - } - } cutoffSink; + } // Members. int32_t cutoffs[25]; // [0] thru [24]: 24 is allowed in "before 24". @@ -316,35 +279,31 @@ struct DayPeriodRulesDataSink : public ResourceTableSink { } }; // struct DayPeriodRulesDataSink -struct DayPeriodRulesCountSink : public ResourceTableSink { +struct DayPeriodRulesCountSink : public ResourceSink { virtual ~DayPeriodRulesCountSink(); - virtual ResourceTableSink *getOrCreateTableSink(const char *key, int32_t, UErrorCode &errorCode) { - if (U_FAILURE(errorCode)) { return NULL; } - int32_t setNum = DayPeriodRulesDataSink::parseSetNum(key, errorCode); - if (setNum > data->maxRuleSetNum) { - data->maxRuleSetNum = setNum; - } + virtual void put(const char *key, ResourceValue &value, UBool, UErrorCode &errorCode) { + ResourceTable rules = value.getTable(errorCode); + if (U_FAILURE(errorCode)) { return; } - return NULL; + for (int32_t i = 0; rules.getKeyAndValue(i, key, value); ++i) { + int32_t setNum = DayPeriodRulesDataSink::parseSetNum(key, errorCode); + if (setNum > data->maxRuleSetNum) { + data->maxRuleSetNum = setNum; + } + } } }; // Out-of-line virtual destructors. -DayPeriodRulesDataSink::LocalesSink::~LocalesSink() {} -DayPeriodRulesDataSink::CutoffSink::~CutoffSink() {} -DayPeriodRulesDataSink::PeriodSink::~PeriodSink() {} -DayPeriodRulesDataSink::RuleSetSink::~RuleSetSink() {} -DayPeriodRulesDataSink::RulesSink::~RulesSink() {} DayPeriodRulesDataSink::~DayPeriodRulesDataSink() {} - DayPeriodRulesCountSink::~DayPeriodRulesCountSink() {} namespace { UInitOnce initOnce = U_INITONCE_INITIALIZER; -UBool dayPeriodRulesCleanup() { +U_CFUNC UBool U_CALLCONV dayPeriodRulesCleanup() { delete[] data->rules; uhash_close(data->localeToRuleSetNumMap); delete data; @@ -354,7 +313,7 @@ UBool dayPeriodRulesCleanup() { } // namespace -void DayPeriodRules::load(UErrorCode &errorCode) { +void U_CALLCONV DayPeriodRules::load(UErrorCode &errorCode) { if (U_FAILURE(errorCode)) { return; } @@ -365,11 +324,11 @@ void DayPeriodRules::load(UErrorCode &errorCode) { // Get the largest rule set number (so we allocate enough objects). DayPeriodRulesCountSink countSink; - ures_getAllTableItemsWithFallback(rb_dayPeriods.getAlias(), "rules", countSink, errorCode); + ures_getAllItemsWithFallback(rb_dayPeriods.getAlias(), "rules", countSink, errorCode); // Populate rules. DayPeriodRulesDataSink sink; - ures_getAllTableItemsWithFallback(rb_dayPeriods.getAlias(), "", sink, errorCode); + ures_getAllItemsWithFallback(rb_dayPeriods.getAlias(), "", sink, errorCode); ucln_i18n_registerCleanup(UCLN_I18N_DAYPERIODRULES, dayPeriodRulesCleanup); } diff --git a/deps/icu-small/source/i18n/dayperiodrules.h b/deps/icu-small/source/i18n/dayperiodrules.h index 5491f7c1ff..3c006cdc2f 100644 --- a/deps/icu-small/source/i18n/dayperiodrules.h +++ b/deps/icu-small/source/i18n/dayperiodrules.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2016, International Business Machines @@ -59,7 +61,7 @@ private: // Translates "morning1" to DAYPERIOD_MORNING1, for example. static DayPeriod getDayPeriodFromString(const char *type_str); - static void load(UErrorCode &errorCode); + static void U_CALLCONV load(UErrorCode &errorCode); // Sets period type for all hours in [startHour, limitHour). void add(int32_t startHour, int32_t limitHour, DayPeriod period); diff --git a/deps/icu-small/source/i18n/dcfmtimp.h b/deps/icu-small/source/i18n/dcfmtimp.h index a827947960..5885872841 100644 --- a/deps/icu-small/source/i18n/dcfmtimp.h +++ b/deps/icu-small/source/i18n/dcfmtimp.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** * Copyright (C) 2012-2014, International Business Machines diff --git a/deps/icu-small/source/i18n/dcfmtsym.cpp b/deps/icu-small/source/i18n/dcfmtsym.cpp index fee9b319ba..b8b9c32a42 100644 --- a/deps/icu-small/source/i18n/dcfmtsym.cpp +++ b/deps/icu-small/source/i18n/dcfmtsym.cpp @@ -1,6 +1,8 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* -* Copyright (C) 1997-2015, International Business Machines Corporation and +* Copyright (C) 1997-2016, International Business Machines Corporation and * others. All Rights Reserved. ******************************************************************************* * @@ -35,6 +37,7 @@ #include "locbased.h" #include "uresimp.h" #include "ureslocs.h" +#include "charstr.h" // ***************************************************************************** // class DecimalFormatSymbols @@ -51,10 +54,45 @@ static const char gAfterCurrencyTag[] = "afterCurrency"; static const char gCurrencyMatchTag[] = "currencyMatch"; static const char gCurrencySudMatchTag[] = "surroundingMatch"; static const char gCurrencyInsertBtnTag[] = "insertBetween"; - +static const char gLatn[] = "latn"; +static const char gSymbols[] = "symbols"; +static const char gNumberElementsLatnSymbols[] = "NumberElements/latn/symbols"; static const UChar INTL_CURRENCY_SYMBOL_STR[] = {0xa4, 0xa4, 0}; +// List of field names to be loaded from the data files. +// These are parallel with the enum ENumberFormatSymbol in unicode/dcfmtsym.h. +static const char *gNumberElementKeys[DecimalFormatSymbols::kFormatSymbolCount] = { + "decimal", + "group", + "list", + "percentSign", + NULL, /* Native zero digit is deprecated from CLDR - get it from the numbering system */ + NULL, /* Pattern digit character is deprecated from CLDR - use # by default always */ + "minusSign", + "plusSign", + NULL, /* currency symbol - Wait until we know the currency before loading from CLDR */ + NULL, /* intl currency symbol - Wait until we know the currency before loading from CLDR */ + "currencyDecimal", + "exponential", + "perMille", + NULL, /* Escape padding character - not in CLDR */ + "infinity", + "nan", + NULL, /* Significant digit symbol - not in CLDR */ + "currencyGroup", + NULL, /* one digit - get it from the numbering system */ + NULL, /* two digit - get it from the numbering system */ + NULL, /* three digit - get it from the numbering system */ + NULL, /* four digit - get it from the numbering system */ + NULL, /* five digit - get it from the numbering system */ + NULL, /* six digit - get it from the numbering system */ + NULL, /* seven digit - get it from the numbering system */ + NULL, /* eight digit - get it from the numbering system */ + NULL, /* nine digit - get it from the numbering system */ + "superscriptingExponent", /* Multiplication (x) symbol for exponents */ +}; + // ------------------------------------- // Initializes this with the decimal format symbols in the default locale. @@ -166,63 +204,149 @@ DecimalFormatSymbols::operator==(const DecimalFormatSymbols& that) const // ------------------------------------- -void -DecimalFormatSymbols::initialize(const Locale& loc, UErrorCode& status, UBool useLastResortData) -{ - static const char *gNumberElementKeys[kFormatSymbolCount] = { - "decimal", - "group", - "list", - "percentSign", - NULL, /* Native zero digit is deprecated from CLDR - get it from the numbering system */ - NULL, /* Pattern digit character is deprecated from CLDR - use # by default always */ - "minusSign", - "plusSign", - NULL, /* currency symbol - We don't really try to load this directly from CLDR until we know the currency */ - NULL, /* intl currency symbol - We don't really try to load this directly from CLDR until we know the currency */ - "currencyDecimal", - "exponential", - "perMille", - NULL, /* Escape padding character - not in CLDR */ - "infinity", - "nan", - NULL, /* Significant digit symbol - not in CLDR */ - "currencyGroup", - NULL, /* one digit - get it from the numbering system */ - NULL, /* two digit - get it from the numbering system */ - NULL, /* three digit - get it from the numbering system */ - NULL, /* four digit - get it from the numbering system */ - NULL, /* five digit - get it from the numbering system */ - NULL, /* six digit - get it from the numbering system */ - NULL, /* seven digit - get it from the numbering system */ - NULL, /* eight digit - get it from the numbering system */ - NULL, /* nine digit - get it from the numbering system */ - "superscriptingExponent", /* Multiplication (x) symbol for exponents */ - }; - - static const char *gLatn = "latn"; - static const char *gSymbols = "symbols"; - const char *nsName; - const UChar *sym = NULL; - int32_t len = 0; +namespace { + +/** + * Sink for enumerating all of the decimal format symbols (more specifically, anything + * under the "NumberElements.symbols" tree). + * + * More specific bundles (en_GB) are enumerated before their parents (en_001, en, root): + * Only store a value if it is still missing, that is, it has not been overridden. + */ +struct DecFmtSymDataSink : public ResourceSink { + + // Destination for data, modified via setters. + DecimalFormatSymbols& dfs; + // Boolean array of whether or not we have seen a particular symbol yet. + // Can't simpy check fSymbols because it is pre-populated with defaults. + UBool seenSymbol[DecimalFormatSymbols::kFormatSymbolCount]; + + // Constructor/Destructor + DecFmtSymDataSink(DecimalFormatSymbols& _dfs) : dfs(_dfs) { + uprv_memset(seenSymbol, FALSE, sizeof(seenSymbol)); + } + virtual ~DecFmtSymDataSink(); + + virtual void put(const char *key, ResourceValue &value, UBool /*noFallback*/, + UErrorCode &errorCode) { + ResourceTable symbolsTable = value.getTable(errorCode); + if (U_FAILURE(errorCode)) { return; } + for (int32_t j = 0; symbolsTable.getKeyAndValue(j, key, value); ++j) { + for (int32_t i=0; i<DecimalFormatSymbols::kFormatSymbolCount; i++) { + if (gNumberElementKeys[i] != NULL && uprv_strcmp(key, gNumberElementKeys[i]) == 0) { + if (!seenSymbol[i]) { + seenSymbol[i] = TRUE; + dfs.setSymbol( + (DecimalFormatSymbols::ENumberFormatSymbol) i, + value.getUnicodeString(errorCode)); + if (U_FAILURE(errorCode)) { return; } + } + break; + } + } + } + } - *validLocale = *actualLocale = 0; - currPattern = NULL; - if (U_FAILURE(status)) - return; + // Returns true if all the symbols have been seen. + UBool seenAll() { + for (int32_t i=0; i<DecimalFormatSymbols::kFormatSymbolCount; i++) { + if (!seenSymbol[i]) { + return FALSE; + } + } + return TRUE; + } - const char* locStr = loc.getName(); - LocalUResourceBundlePointer resource(ures_open(NULL, locStr, &status)); - LocalUResourceBundlePointer numberElementsRes( - ures_getByKeyWithFallback(resource.getAlias(), gNumberElements, NULL, &status)); + // If monetary decimal or grouping were not explicitly set, then set them to be the + // same as their non-monetary counterparts. + void resolveMissingMonetarySeparators(const UnicodeString* fSymbols) { + if (!seenSymbol[DecimalFormatSymbols::kMonetarySeparatorSymbol]) { + dfs.setSymbol( + DecimalFormatSymbols::kMonetarySeparatorSymbol, + fSymbols[DecimalFormatSymbols::kDecimalSeparatorSymbol]); + } + if (!seenSymbol[DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol]) { + dfs.setSymbol( + DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol, + fSymbols[DecimalFormatSymbols::kGroupingSeparatorSymbol]); + } + } +}; + +struct CurrencySpacingSink : public ResourceSink { + DecimalFormatSymbols& dfs; + UBool hasBeforeCurrency; + UBool hasAfterCurrency; + + CurrencySpacingSink(DecimalFormatSymbols& _dfs) + : dfs(_dfs), hasBeforeCurrency(FALSE), hasAfterCurrency(FALSE) {} + virtual ~CurrencySpacingSink(); + + virtual void put(const char *key, ResourceValue &value, UBool /*noFallback*/, + UErrorCode &errorCode) { + ResourceTable spacingTypesTable = value.getTable(errorCode); + for (int32_t i = 0; spacingTypesTable.getKeyAndValue(i, key, value); ++i) { + UBool beforeCurrency; + if (uprv_strcmp(key, gBeforeCurrencyTag) == 0) { + beforeCurrency = TRUE; + hasBeforeCurrency = TRUE; + } else if (uprv_strcmp(key, gAfterCurrencyTag) == 0) { + beforeCurrency = FALSE; + hasAfterCurrency = TRUE; + } else { + continue; + } - if (U_FAILURE(status)) { - if ( useLastResortData ) { - status = U_USING_DEFAULT_WARNING; - initialize(); + ResourceTable patternsTable = value.getTable(errorCode); + for (int32_t j = 0; patternsTable.getKeyAndValue(j, key, value); ++j) { + UCurrencySpacing pattern; + if (uprv_strcmp(key, gCurrencyMatchTag) == 0) { + pattern = UNUM_CURRENCY_MATCH; + } else if (uprv_strcmp(key, gCurrencySudMatchTag) == 0) { + pattern = UNUM_CURRENCY_SURROUNDING_MATCH; + } else if (uprv_strcmp(key, gCurrencyInsertBtnTag) == 0) { + pattern = UNUM_CURRENCY_INSERT; + } else { + continue; + } + + const UnicodeString& current = dfs.getPatternForCurrencySpacing( + pattern, beforeCurrency, errorCode); + if (current.isEmpty()) { + dfs.setPatternForCurrencySpacing( + pattern, beforeCurrency, value.getUnicodeString(errorCode)); + } + } + } + } + + void resolveMissing() { + // For consistency with Java, this method overwrites everything with the defaults unless + // both beforeCurrency and afterCurrency were found in CLDR. + static const char* defaults[] = { "[:letter:]", "[:digit:]", " " }; + if (!hasBeforeCurrency || !hasAfterCurrency) { + for (UBool beforeCurrency = 0; beforeCurrency <= TRUE; beforeCurrency++) { + for (int32_t pattern = 0; pattern < UNUM_CURRENCY_SPACING_COUNT; pattern++) { + dfs.setPatternForCurrencySpacing((UCurrencySpacing)pattern, + beforeCurrency, UnicodeString(defaults[pattern], -1, US_INV)); + } + } } - return; } +}; + +// Virtual destructors must be defined out of line. +DecFmtSymDataSink::~DecFmtSymDataSink() {} +CurrencySpacingSink::~CurrencySpacingSink() {} + +} // namespace + +void +DecimalFormatSymbols::initialize(const Locale& loc, UErrorCode& status, UBool useLastResortData) +{ + if (U_FAILURE(status)) { return; } + *validLocale = *actualLocale = 0; + currPattern = NULL; // First initialize all the symbols to the fallbacks for anything we can't find initialize(); @@ -231,8 +355,8 @@ DecimalFormatSymbols::initialize(const Locale& loc, UErrorCode& status, UBool us // Next get the numbering system for this locale and set zero digit // and the digit string based on the numbering system for the locale // - LocalPointer<NumberingSystem> ns(NumberingSystem::createInstance(loc, status)); + const char *nsName; if (U_SUCCESS(status) && ns->getRadix() == 10 && !ns->isAlgorithmic()) { nsName = ns->getName(); UnicodeString digitString(ns->getDescription()); @@ -248,61 +372,61 @@ DecimalFormatSymbols::initialize(const Locale& loc, UErrorCode& status, UBool us nsName = gLatn; } - UBool isLatn = !uprv_strcmp(nsName,gLatn); + // Open resource bundles + const char* locStr = loc.getName(); + LocalUResourceBundlePointer resource(ures_open(NULL, locStr, &status)); + LocalUResourceBundlePointer numberElementsRes( + ures_getByKeyWithFallback(resource.getAlias(), gNumberElements, NULL, &status)); - UErrorCode nlStatus = U_ZERO_ERROR; - LocalUResourceBundlePointer nonLatnSymbols; - if ( !isLatn ) { - nonLatnSymbols.adoptInstead( - ures_getByKeyWithFallback(numberElementsRes.getAlias(), nsName, NULL, &nlStatus)); - ures_getByKeyWithFallback(nonLatnSymbols.getAlias(), gSymbols, nonLatnSymbols.getAlias(), &nlStatus); + if (U_FAILURE(status)) { + if ( useLastResortData ) { + status = U_USING_DEFAULT_WARNING; + initialize(); + } + return; } - LocalUResourceBundlePointer latnSymbols( - ures_getByKeyWithFallback(numberElementsRes.getAlias(), gLatn, NULL, &status)); - ures_getByKeyWithFallback(latnSymbols.getAlias(), gSymbols, latnSymbols.getAlias(), &status); - - UBool kMonetaryDecimalSet = FALSE; - UBool kMonetaryGroupingSet = FALSE; - for(int32_t i = 0; i<kFormatSymbolCount; i++) { - if ( gNumberElementKeys[i] != NULL ) { - UErrorCode localStatus = U_ZERO_ERROR; - if ( !isLatn ) { - sym = ures_getStringByKeyWithFallback(nonLatnSymbols.getAlias(), - gNumberElementKeys[i], &len, &localStatus); - // If we can't find the symbol in the numbering system specific resources, - // use the "latn" numbering system as the fallback. - if ( U_FAILURE(localStatus) ) { - localStatus = U_ZERO_ERROR; - sym = ures_getStringByKeyWithFallback(latnSymbols.getAlias(), - gNumberElementKeys[i], &len, &localStatus); - } - } else { - sym = ures_getStringByKeyWithFallback(latnSymbols.getAlias(), - gNumberElementKeys[i], &len, &localStatus); - } - - if ( U_SUCCESS(localStatus) ) { - setSymbol((ENumberFormatSymbol)i, UnicodeString(TRUE, sym, len)); - if ( i == kMonetarySeparatorSymbol ) { - kMonetaryDecimalSet = TRUE; - } else if ( i == kMonetaryGroupingSeparatorSymbol ) { - kMonetaryGroupingSet = TRUE; - } - } + // Set locale IDs + // TODO: Is there a way to do this without depending on the resource bundle instance? + U_LOCALE_BASED(locBased, *this); + locBased.setLocaleIDs( + ures_getLocaleByType( + numberElementsRes.getAlias(), + ULOC_VALID_LOCALE, &status), + ures_getLocaleByType( + numberElementsRes.getAlias(), + ULOC_ACTUAL_LOCALE, &status)); + + // Now load the rest of the data from the data sink. + // Start with loading this nsName if it is not Latin. + DecFmtSymDataSink sink(*this); + if (uprv_strcmp(nsName, gLatn) != 0) { + CharString path; + path.append(gNumberElements, status) + .append('/', status) + .append(nsName, status) + .append('/', status) + .append(gSymbols, status); + ures_getAllItemsWithFallback(resource.getAlias(), path.data(), sink, status); + + // If no symbols exist for the given nsName and resource bundle, silently ignore + // and fall back to Latin. + if (status == U_MISSING_RESOURCE_ERROR) { + status = U_ZERO_ERROR; + } else if (U_FAILURE(status)) { + return; } } - // If monetary decimal or grouping were not explicitly set, then set them to be the - // same as their non-monetary counterparts. - - if ( !kMonetaryDecimalSet ) { - setSymbol(kMonetarySeparatorSymbol,fSymbols[kDecimalSeparatorSymbol]); - } - if ( !kMonetaryGroupingSet ) { - setSymbol(kMonetaryGroupingSeparatorSymbol,fSymbols[kGroupingSeparatorSymbol]); + // Continue with Latin if necessary. + if (!sink.seenAll()) { + ures_getAllItemsWithFallback(resource.getAlias(), gNumberElementsLatnSymbols, sink, status); + if (U_FAILURE(status)) { return; } } + // Let the monetary number separators equal the default number separators if necessary. + sink.resolveMissingMonetarySeparators(fSymbols); + // Obtain currency data from the currency API. This is strictly // for backward compatibility; we don't use DecimalFormatSymbols // for currency data anymore. @@ -318,12 +442,6 @@ DecimalFormatSymbols::initialize(const Locale& loc, UErrorCode& status, UBool us } /* else use the default values. */ - U_LOCALE_BASED(locBased, *this); - locBased.setLocaleIDs(ures_getLocaleByType(numberElementsRes.getAlias(), - ULOC_VALID_LOCALE, &status), - ures_getLocaleByType(numberElementsRes.getAlias(), - ULOC_ACTUAL_LOCALE, &status)); - //load the currency data UChar ucc[4]={0}; //Currency Codes are always 3 chars long int32_t uccLen = 4; @@ -361,38 +479,11 @@ DecimalFormatSymbols::initialize(const Locale& loc, UErrorCode& status, UBool us // else ignore the error if no currency // Currency Spacing. - localStatus = U_ZERO_ERROR; - LocalUResourceBundlePointer currencyResource(ures_open(U_ICUDATA_CURR, locStr, &localStatus)); - LocalUResourceBundlePointer currencySpcRes( - ures_getByKeyWithFallback(currencyResource.getAlias(), - gCurrencySpacingTag, NULL, &localStatus)); - - if (localStatus == U_USING_FALLBACK_WARNING || U_SUCCESS(localStatus)) { - const char* keywords[UNUM_CURRENCY_SPACING_COUNT] = { - gCurrencyMatchTag, gCurrencySudMatchTag, gCurrencyInsertBtnTag - }; - localStatus = U_ZERO_ERROR; - LocalUResourceBundlePointer dataRes( - ures_getByKeyWithFallback(currencySpcRes.getAlias(), - gBeforeCurrencyTag, NULL, &localStatus)); - if (localStatus == U_USING_FALLBACK_WARNING || U_SUCCESS(localStatus)) { - localStatus = U_ZERO_ERROR; - for (int32_t i = 0; i < UNUM_CURRENCY_SPACING_COUNT; i++) { - currencySpcBeforeSym[i] = - ures_getUnicodeStringByKey(dataRes.getAlias(), keywords[i], &localStatus); - } - } - dataRes.adoptInstead( - ures_getByKeyWithFallback(currencySpcRes.getAlias(), - gAfterCurrencyTag, NULL, &localStatus)); - if (localStatus == U_USING_FALLBACK_WARNING || U_SUCCESS(localStatus)) { - localStatus = U_ZERO_ERROR; - for (int32_t i = 0; i < UNUM_CURRENCY_SPACING_COUNT; i++) { - currencySpcAfterSym[i] = - ures_getUnicodeStringByKey(dataRes.getAlias(), keywords[i], &localStatus); - } - } - } + LocalUResourceBundlePointer currencyResource(ures_open(U_ICUDATA_CURR, locStr, &status)); + CurrencySpacingSink currencySink(*this); + ures_getAllItemsWithFallback(currencyResource.getAlias(), gCurrencySpacingTag, currencySink, status); + currencySink.resolveMissing(); + if (U_FAILURE(status)) { return; } } void diff --git a/deps/icu-small/source/i18n/decContext.c b/deps/icu-small/source/i18n/decContext.c index e4726550e0..498e1fede9 100644 --- a/deps/icu-small/source/i18n/decContext.c +++ b/deps/icu-small/source/i18n/decContext.c @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ------------------------------------------------------------------ */ /* Decimal Context module */ /* ------------------------------------------------------------------ */ diff --git a/deps/icu-small/source/i18n/decContext.h b/deps/icu-small/source/i18n/decContext.h index cb7f2c2dbf..62123ff440 100644 --- a/deps/icu-small/source/i18n/decContext.h +++ b/deps/icu-small/source/i18n/decContext.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ------------------------------------------------------------------ */ /* Decimal Context module header */ /* ------------------------------------------------------------------ */ diff --git a/deps/icu-small/source/i18n/decNumber.c b/deps/icu-small/source/i18n/decNumber.c index b128457253..b25845e0aa 100644 --- a/deps/icu-small/source/i18n/decNumber.c +++ b/deps/icu-small/source/i18n/decNumber.c @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ------------------------------------------------------------------ */ /* Decimal Number arithmetic module */ /* ------------------------------------------------------------------ */ diff --git a/deps/icu-small/source/i18n/decNumber.h b/deps/icu-small/source/i18n/decNumber.h index cc9c8c3652..90269d9f66 100644 --- a/deps/icu-small/source/i18n/decNumber.h +++ b/deps/icu-small/source/i18n/decNumber.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ------------------------------------------------------------------ */ /* Decimal Number arithmetic module header */ /* ------------------------------------------------------------------ */ diff --git a/deps/icu-small/source/i18n/decNumberLocal.h b/deps/icu-small/source/i18n/decNumberLocal.h index c6e542d0c2..294d5f519d 100644 --- a/deps/icu-small/source/i18n/decNumberLocal.h +++ b/deps/icu-small/source/i18n/decNumberLocal.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ------------------------------------------------------------------ */ /* decNumber package local type, tuning, and macro definitions */ /* ------------------------------------------------------------------ */ diff --git a/deps/icu-small/source/i18n/decfmtst.cpp b/deps/icu-small/source/i18n/decfmtst.cpp index 743804ceee..4af7587877 100644 --- a/deps/icu-small/source/i18n/decfmtst.cpp +++ b/deps/icu-small/source/i18n/decfmtst.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2009-2016, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/decfmtst.h b/deps/icu-small/source/i18n/decfmtst.h index 3c774a3249..719f0aa976 100644 --- a/deps/icu-small/source/i18n/decfmtst.h +++ b/deps/icu-small/source/i18n/decfmtst.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2009-2016, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/decimalformatpattern.cpp b/deps/icu-small/source/i18n/decimalformatpattern.cpp index 9d170ccb21..ca90e968a1 100644 --- a/deps/icu-small/source/i18n/decimalformatpattern.cpp +++ b/deps/icu-small/source/i18n/decimalformatpattern.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 1997-2015, International Business Machines Corporation and * diff --git a/deps/icu-small/source/i18n/decimalformatpattern.h b/deps/icu-small/source/i18n/decimalformatpattern.h index 9726b37050..2ebbdf9ffc 100644 --- a/deps/icu-small/source/i18n/decimalformatpattern.h +++ b/deps/icu-small/source/i18n/decimalformatpattern.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 1997-2015, International Business Machines Corporation and * @@ -28,7 +30,7 @@ enum CurrencySignCount { class DecimalFormatSymbols; -struct DecimalFormatPattern : UMemory { +struct DecimalFormatPattern : public UMemory { enum EPadPosition { kPadBeforePrefix, kPadAfterPrefix, @@ -71,7 +73,7 @@ struct DecimalFormatPattern : UMemory { EPadPosition fPadPosition; }; -class DecimalFormatPatternParser : UMemory { +class DecimalFormatPatternParser : public UMemory { public: DecimalFormatPatternParser(); void useSymbols(const DecimalFormatSymbols& symbols); diff --git a/deps/icu-small/source/i18n/decimalformatpatternimpl.h b/deps/icu-small/source/i18n/decimalformatpatternimpl.h index 4b563042d1..67bc96db61 100644 --- a/deps/icu-small/source/i18n/decimalformatpatternimpl.h +++ b/deps/icu-small/source/i18n/decimalformatpatternimpl.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** * Copyright (C) 2015, International Business Machines diff --git a/deps/icu-small/source/i18n/decimfmt.cpp b/deps/icu-small/source/i18n/decimfmt.cpp index 0b67e63be9..440adf5a6b 100644 --- a/deps/icu-small/source/i18n/decimfmt.cpp +++ b/deps/icu-small/source/i18n/decimfmt.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 1997-2015, International Business Machines Corporation and * @@ -445,13 +447,25 @@ DecimalFormat::construct(UErrorCode& status, if (patternUsed->indexOf(kCurrencySign) != -1) { // initialize for currency, not only for plural format, // but also for mix parsing - if (fCurrencyPluralInfo == NULL) { - fCurrencyPluralInfo = new CurrencyPluralInfo(fImpl->fSymbols->getLocale(), status); - if (U_FAILURE(status)) { - return; - } - } - // need it for mix parsing + handleCurrencySignInPattern(status); + } +} + +void +DecimalFormat::handleCurrencySignInPattern(UErrorCode& status) { + // initialize for currency, not only for plural format, + // but also for mix parsing + if (U_FAILURE(status)) { + return; + } + if (fCurrencyPluralInfo == NULL) { + fCurrencyPluralInfo = new CurrencyPluralInfo(fImpl->fSymbols->getLocale(), status); + if (U_FAILURE(status)) { + return; + } + } + // need it for mix parsing + if (fAffixPatternsForCurrency == NULL) { setupCurrencyAffixPatterns(status); } } @@ -828,7 +842,7 @@ DecimalFormat::format( double number, UnicodeString& -DecimalFormat::format(const StringPiece &number, +DecimalFormat::format(StringPiece number, UnicodeString &toAppendTo, FieldPositionIterator *posIter, UErrorCode &status) const @@ -1643,7 +1657,7 @@ UBool DecimalFormat::subparse(const UnicodeString& text, // if we didn't see a decimal and it is required, check to see if the pattern had one if(!sawDecimal && isDecimalPatternMatchRequired()) { - if(formatPattern.indexOf(DecimalFormatSymbols::kDecimalSeparatorSymbol) != 0) + if(formatPattern.indexOf(kPatternDecimalSeparator) != -1) { parsePosition.setIndex(oldStart); parsePosition.setErrorIndex(position); @@ -1769,7 +1783,7 @@ printf("PP -> %d, SLOW = [%s]! pp=%d, os=%d, err=%s\n", position, parsedNum.d // check if we missed a required decimal point if(fastParseOk && isDecimalPatternMatchRequired()) { - if(formatPattern.indexOf(DecimalFormatSymbols::kDecimalSeparatorSymbol) != 0) + if(formatPattern.indexOf(kPatternDecimalSeparator) != -1) { parsePosition.setIndex(oldStart); parsePosition.setErrorIndex(position); @@ -2815,6 +2829,9 @@ DecimalFormat::toLocalizedPattern(UnicodeString& result) const void DecimalFormat::applyPattern(const UnicodeString& pattern, UErrorCode& status) { + if (pattern.indexOf(kCurrencySign) != -1) { + handleCurrencySignInPattern(status); + } fImpl->applyPattern(pattern, status); } @@ -2825,6 +2842,9 @@ DecimalFormat::applyPattern(const UnicodeString& pattern, UParseError& parseError, UErrorCode& status) { + if (pattern.indexOf(kCurrencySign) != -1) { + handleCurrencySignInPattern(status); + } fImpl->applyPattern(pattern, parseError, status); } //------------------------------------------------------------------------------ @@ -2832,6 +2852,9 @@ DecimalFormat::applyPattern(const UnicodeString& pattern, void DecimalFormat::applyLocalizedPattern(const UnicodeString& pattern, UErrorCode& status) { + if (pattern.indexOf(kCurrencySign) != -1) { + handleCurrencySignInPattern(status); + } fImpl->applyLocalizedPattern(pattern, status); } @@ -2842,6 +2865,9 @@ DecimalFormat::applyLocalizedPattern(const UnicodeString& pattern, UParseError& parseError, UErrorCode& status) { + if (pattern.indexOf(kCurrencySign) != -1) { + handleCurrencySignInPattern(status); + } fImpl->applyLocalizedPattern(pattern, parseError, status); } diff --git a/deps/icu-small/source/i18n/decimfmtimpl.cpp b/deps/icu-small/source/i18n/decimfmtimpl.cpp index d0c96493a9..342ce5b5e4 100644 --- a/deps/icu-small/source/i18n/decimfmtimpl.cpp +++ b/deps/icu-small/source/i18n/decimfmtimpl.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* * Copyright (C) 2015, International Business Machines * Corporation and others. All Rights Reserved. @@ -241,9 +243,9 @@ DecimalFormatImpl::setMultiplierScale(int32_t scale) { if (scale == 0) { // Needed to preserve equality. fMultiplier == 0 means // multiplier is 1. - fMultiplier.set(0); + fMultiplier.set((int32_t)0); } else { - fMultiplier.set(1); + fMultiplier.set((int32_t)1); fMultiplier.shiftDecimalRight(scale); } } @@ -425,7 +427,7 @@ DecimalFormatImpl::format( UnicodeString & DecimalFormatImpl::format( - const StringPiece &number, + StringPiece number, UnicodeString &appendTo, FieldPositionIterator *posIter, UErrorCode &status) const { @@ -706,7 +708,7 @@ DecimalFormatImpl::getMultiplier() const { void DecimalFormatImpl::setMultiplier(int32_t m) { if (m == 0 || m == 1) { - fMultiplier.set(0); + fMultiplier.set((int32_t)0); } else { fMultiplier.set(m); } @@ -1481,7 +1483,7 @@ DecimalFormatImpl::toNumberPattern( } } else { if (i < roundingIncrementUpperExp && i >= roundingIncrementLowerExp) { - result.append(fEffPrecision.fMantissa.fRoundingIncrement.getDigitByExponent(i) + kPatternZeroDigit); + result.append((UChar)(fEffPrecision.fMantissa.fRoundingIncrement.getDigitByExponent(i) + kPatternZeroDigit)); } else if (minInterval.contains(i)) { result.append(kPatternZeroDigit); } else { diff --git a/deps/icu-small/source/i18n/decimfmtimpl.h b/deps/icu-small/source/i18n/decimfmtimpl.h index d55a4eca2f..537107c6f7 100644 --- a/deps/icu-small/source/i18n/decimfmtimpl.h +++ b/deps/icu-small/source/i18n/decimfmtimpl.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** * Copyright (C) 2015, International Business Machines @@ -217,7 +219,7 @@ UnicodeString &format( FieldPositionIterator *posIter, UErrorCode &status) const; UnicodeString &format( - const StringPiece &number, + StringPiece number, UnicodeString &appendTo, FieldPositionIterator *posIter, UErrorCode &status) const; diff --git a/deps/icu-small/source/i18n/digitaffix.cpp b/deps/icu-small/source/i18n/digitaffix.cpp index d73d40121a..262bc49427 100644 --- a/deps/icu-small/source/i18n/digitaffix.cpp +++ b/deps/icu-small/source/i18n/digitaffix.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* * Copyright (C) 2015, International Business Machines * Corporation and others. All Rights Reserved. diff --git a/deps/icu-small/source/i18n/digitaffix.h b/deps/icu-small/source/i18n/digitaffix.h index d5b545a3d7..a1a100654f 100644 --- a/deps/icu-small/source/i18n/digitaffix.h +++ b/deps/icu-small/source/i18n/digitaffix.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2015, International Business Machines diff --git a/deps/icu-small/source/i18n/digitaffixesandpadding.cpp b/deps/icu-small/source/i18n/digitaffixesandpadding.cpp index d941a573de..716ab4a32e 100644 --- a/deps/icu-small/source/i18n/digitaffixesandpadding.cpp +++ b/deps/icu-small/source/i18n/digitaffixesandpadding.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* * Copyright (C) 2015, International Business Machines * Corporation and others. All Rights Reserved. diff --git a/deps/icu-small/source/i18n/digitaffixesandpadding.h b/deps/icu-small/source/i18n/digitaffixesandpadding.h index 3586371094..e837e07c8f 100644 --- a/deps/icu-small/source/i18n/digitaffixesandpadding.h +++ b/deps/icu-small/source/i18n/digitaffixesandpadding.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2015, International Business Machines diff --git a/deps/icu-small/source/i18n/digitformatter.cpp b/deps/icu-small/source/i18n/digitformatter.cpp index 837dcb4d9e..d1a88f95ee 100644 --- a/deps/icu-small/source/i18n/digitformatter.cpp +++ b/deps/icu-small/source/i18n/digitformatter.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* * Copyright (C) 2015, International Business Machines * Corporation and others. All Rights Reserved. diff --git a/deps/icu-small/source/i18n/digitformatter.h b/deps/icu-small/source/i18n/digitformatter.h index cf339f598d..d92d425151 100644 --- a/deps/icu-small/source/i18n/digitformatter.h +++ b/deps/icu-small/source/i18n/digitformatter.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2015, International Business Machines diff --git a/deps/icu-small/source/i18n/digitgrouping.cpp b/deps/icu-small/source/i18n/digitgrouping.cpp index 0a340cdc4a..0d96b407c5 100644 --- a/deps/icu-small/source/i18n/digitgrouping.cpp +++ b/deps/icu-small/source/i18n/digitgrouping.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* * Copyright (C) 2015, International Business Machines * Corporation and others. All Rights Reserved. diff --git a/deps/icu-small/source/i18n/digitgrouping.h b/deps/icu-small/source/i18n/digitgrouping.h index e075ae204b..33835ff665 100644 --- a/deps/icu-small/source/i18n/digitgrouping.h +++ b/deps/icu-small/source/i18n/digitgrouping.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2015, International Business Machines diff --git a/deps/icu-small/source/i18n/digitinterval.cpp b/deps/icu-small/source/i18n/digitinterval.cpp index bf78c19aab..b1ba811606 100644 --- a/deps/icu-small/source/i18n/digitinterval.cpp +++ b/deps/icu-small/source/i18n/digitinterval.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* * Copyright (C) 2015, International Business Machines * Corporation and others. All Rights Reserved. diff --git a/deps/icu-small/source/i18n/digitinterval.h b/deps/icu-small/source/i18n/digitinterval.h index 174f797fa4..5dbf3f9a29 100644 --- a/deps/icu-small/source/i18n/digitinterval.h +++ b/deps/icu-small/source/i18n/digitinterval.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2015, International Business Machines diff --git a/deps/icu-small/source/i18n/digitlst.cpp b/deps/icu-small/source/i18n/digitlst.cpp index 54aebbb632..8bb470c8f0 100644 --- a/deps/icu-small/source/i18n/digitlst.cpp +++ b/deps/icu-small/source/i18n/digitlst.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 1997-2015, International Business Machines @@ -24,9 +26,14 @@ ****************************************************************************** */ +#if defined(__CYGWIN__) && !defined(_GNU_SOURCE) +#define _GNU_SOURCE +#endif + #include "digitlst.h" #if !UCONFIG_NO_FORMATTING + #include "unicode/putil.h" #include "charstr.h" #include "cmemory.h" @@ -35,12 +42,32 @@ #include "putilimp.h" #include "uassert.h" #include "digitinterval.h" +#include "ucln_in.h" +#include "umutex.h" #include <stdlib.h> #include <limits.h> #include <string.h> #include <stdio.h> #include <limits> +#if !defined(U_USE_STRTOD_L) +# if U_PLATFORM_USES_ONLY_WIN32_API +# define U_USE_STRTOD_L 1 +# elif defined(U_HAVE_STRTOD_L) +# define U_USE_STRTOD_L U_HAVE_STRTOD_L +# else +# define U_USE_STRTOD_L 0 +# endif +#endif + +#if U_USE_STRTOD_L && !U_PLATFORM_USES_ONLY_WIN32_API +# if U_PLATFORM == U_PF_CYGWIN +# include <locale.h> +# else +# include <xlocale.h> +# endif +#endif + // *************************************************************************** // class DigitList // A wrapper onto decNumber. @@ -395,27 +422,6 @@ DigitList::append(char digit) internalClear(); } -char DigitList::getStrtodDecimalSeparator() { - // TODO: maybe use andy's pthread once. - static char gDecimal = 0; - char result; - { - Mutex mutex; - result = gDecimal;; - if (result == 0) { - // We need to know the decimal separator character that will be used with strtod(). - // Depends on the C runtime global locale. - // Most commonly is '.' - // TODO: caching could fail if the global locale is changed on the fly. - char rep[MAX_DIGITS]; - sprintf(rep, "%+1.1f", 1.0); - result = rep[2]; - gDecimal = result;; - } - } - return result; -} - // ------------------------------------- /** @@ -428,24 +434,11 @@ char DigitList::getStrtodDecimalSeparator() { double DigitList::getDouble() const { - static char gDecimal = 0; - char decimalSeparator; { Mutex mutex; if (fHave == kDouble) { return fUnion.fDouble; } - decimalSeparator = gDecimal; - } - - if (decimalSeparator == 0) { - // We need to know the decimal separator character that will be used with strtod(). - // Depends on the C runtime global locale. - // Most commonly is '.' - // TODO: caching could fail if the global locale is changed on the fly. - char rep[MAX_DIGITS]; - sprintf(rep, "%+1.1f", 1.0); - decimalSeparator = rep[2]; } double tDouble = 0.0; @@ -483,24 +476,71 @@ DigitList::getDouble() const } U_ASSERT(uprv_strlen(&s[0]) < MAX_DBL_DIGITS+18); - if (decimalSeparator != '.') { - char *decimalPt = strchr(s.getAlias(), '.'); - if (decimalPt != NULL) { - *decimalPt = decimalSeparator; - } - } char *end = NULL; - tDouble = uprv_strtod(s.getAlias(), &end); + tDouble = decimalStrToDouble(s.getAlias(), &end); } { Mutex mutex; DigitList *nonConstThis = const_cast<DigitList *>(this); nonConstThis->internalSetDouble(tDouble); - gDecimal = decimalSeparator; } return tDouble; } +#if U_USE_STRTOD_L && U_PLATFORM_USES_ONLY_WIN32_API +# define locale_t _locale_t +# define freelocale _free_locale +# define strtod_l _strtod_l +#endif + +#if U_USE_STRTOD_L +static locale_t gCLocale = (locale_t)0; +#endif +static icu::UInitOnce gCLocaleInitOnce = U_INITONCE_INITIALIZER; + +U_CDECL_BEGIN +// Cleanup callback func +static UBool U_CALLCONV digitList_cleanup(void) +{ +#if U_USE_STRTOD_L + if (gCLocale != (locale_t)0) { + freelocale(gCLocale); + } +#endif + return TRUE; +} +// C Locale initialization func +static void U_CALLCONV initCLocale(void) { + ucln_i18n_registerCleanup(UCLN_I18N_DIGITLIST, digitList_cleanup); +#if U_USE_STRTOD_L +# if U_PLATFORM_USES_ONLY_WIN32_API + gCLocale = _create_locale(LC_ALL, "C"); +# else + gCLocale = newlocale(LC_ALL_MASK, "C", (locale_t)0); +# endif +#endif +} +U_CDECL_END + +double +DigitList::decimalStrToDouble(char *decstr, char **end) { + umtx_initOnce(gCLocaleInitOnce, &initCLocale); +#if U_USE_STRTOD_L + return strtod_l(decstr, end, gCLocale); +#else + char *decimalPt = strchr(decstr, '.'); + if (decimalPt) { + // We need to know the decimal separator character that will be used with strtod(). + // Depends on the C runtime global locale. + // Most commonly is '.' + char rep[MAX_DIGITS]; + sprintf(rep, "%+1.1f", 1.0); + *decimalPt = rep[2]; + } + return uprv_strtod(decstr, end); +#endif +} + // ------------------------------------- /** @@ -734,7 +774,7 @@ DigitList::set(int64_t source) * be acceptable for a public API. */ void -DigitList::set(const StringPiece &source, UErrorCode &status, uint32_t /*fastpathBits*/) { +DigitList::set(StringPiece source, UErrorCode &status, uint32_t /*fastpathBits*/) { if (U_FAILURE(status)) { return; } diff --git a/deps/icu-small/source/i18n/digitlst.h b/deps/icu-small/source/i18n/digitlst.h index 6cea007cb8..27e6e8c410 100644 --- a/deps/icu-small/source/i18n/digitlst.h +++ b/deps/icu-small/source/i18n/digitlst.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * @@ -267,7 +269,7 @@ public: * @param source The value to be set. The string must be nul-terminated. * @param fastpathBits special flags for fast parsing */ - void set(const StringPiece &source, UErrorCode &status, uint32_t fastpathBits = 0); + void set(StringPiece source, UErrorCode &status, uint32_t fastpathBits = 0); /** * Multiply this = this * arg @@ -493,7 +495,8 @@ private: static inline void * U_EXPORT2 operator new(size_t size) U_NO_THROW { return ::operator new(size); }; static inline void U_EXPORT2 operator delete(void *ptr ) U_NO_THROW { ::operator delete(ptr); }; #endif - static char U_EXPORT2 getStrtodDecimalSeparator(); + + static double U_EXPORT2 decimalStrToDouble(char *decstr, char **end); /** * Placement new for stack usage diff --git a/deps/icu-small/source/i18n/dt_impl.h b/deps/icu-small/source/i18n/dt_impl.h new file mode 100644 index 0000000000..9b01bad79e --- /dev/null +++ b/deps/icu-small/source/i18n/dt_impl.h @@ -0,0 +1,92 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html +/* +******************************************************************************* +* Copyright (C) 2007-2016, International Business Machines Corporation and +* others. All Rights Reserved. +******************************************************************************* +* +* File dt_impl.h +* +******************************************************************************* +*/ + + +#ifndef DT_IMPL_H__ +#define DT_IMPL_H__ + +/** + * \file + * \brief C++ API: Defines macros for interval format implementation + */ + +#if !UCONFIG_NO_FORMATTING + +#include "unicode/unistr.h" + + +#define QUOTE ((UChar)0x0027) +#define LOW_LINE ((UChar)0x005F) +#define COLON ((UChar)0x003A) +#define LEFT_CURLY_BRACKET ((UChar)0x007B) +#define RIGHT_CURLY_BRACKET ((UChar)0x007D) +#define SPACE ((UChar)0x0020) +#define EN_DASH ((UChar)0x2013) +#define SOLIDUS ((UChar)0x002F) +#define PERCENT ((UChar)0x0025) + +#define DIGIT_ZERO ((UChar)0x0030) +#define DIGIT_ONE ((UChar)0x0031) + +#define LOW_A ((UChar)0x0061) +#define LOW_B ((UChar)0x0062) +#define LOW_C ((UChar)0x0063) +#define LOW_D ((UChar)0x0064) +#define LOW_E ((UChar)0x0065) +#define LOW_F ((UChar)0x0066) +#define LOW_G ((UChar)0x0067) +#define LOW_H ((UChar)0x0068) +#define LOW_I ((UChar)0x0069) +#define LOW_J ((UChar)0x006a) +#define LOW_K ((UChar)0x006B) +#define LOW_L ((UChar)0x006C) +#define LOW_M ((UChar)0x006D) +#define LOW_N ((UChar)0x006E) +#define LOW_O ((UChar)0x006F) +#define LOW_P ((UChar)0x0070) +#define LOW_Q ((UChar)0x0071) +#define LOW_R ((UChar)0x0072) +#define LOW_S ((UChar)0x0073) +#define LOW_T ((UChar)0x0074) +#define LOW_U ((UChar)0x0075) +#define LOW_V ((UChar)0x0076) +#define LOW_W ((UChar)0x0077) +#define LOW_Y ((UChar)0x0079) +#define LOW_Z ((UChar)0x007A) + +#define CAP_A ((UChar)0x0041) +#define CAP_C ((UChar)0x0043) +#define CAP_D ((UChar)0x0044) +#define CAP_E ((UChar)0x0045) +#define CAP_F ((UChar)0x0046) +#define CAP_G ((UChar)0x0047) +#define CAP_H ((UChar)0x0048) +#define CAP_K ((UChar)0x004B) +#define CAP_L ((UChar)0x004C) +#define CAP_M ((UChar)0x004D) +#define CAP_N ((UChar)0x004E) +#define CAP_O ((UChar)0x004F) +#define CAP_P ((UChar)0x0050) +#define CAP_Q ((UChar)0x0051) +#define CAP_S ((UChar)0x0053) +#define CAP_T ((UChar)0x0054) +#define CAP_U ((UChar)0x0055) +#define CAP_V ((UChar)0x0056) +#define CAP_W ((UChar)0x0057) +#define CAP_Y ((UChar)0x0059) +#define CAP_Z ((UChar)0x005A) + +#endif /* #if !UCONFIG_NO_FORMATTING */ + +#endif +//eof diff --git a/deps/icu-small/source/i18n/dtfmtsym.cpp b/deps/icu-small/source/i18n/dtfmtsym.cpp index 206d7a26a9..c412c5be05 100644 --- a/deps/icu-small/source/i18n/dtfmtsym.cpp +++ b/deps/icu-small/source/i18n/dtfmtsym.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 1997-2016, International Business Machines Corporation and * @@ -33,11 +35,15 @@ #include "umutex.h" #include "cmemory.h" #include "cstring.h" +#include "charstr.h" +#include "dt_impl.h" #include "locbased.h" #include "gregoimp.h" #include "hash.h" +#include "uassert.h" #include "uresimp.h" #include "ureslocs.h" +#include "uvector.h" #include "shareddateformatsymbols.h" #include "unicode/calendar.h" #include "unifiedcache.h" @@ -194,6 +200,8 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(DateFormatSymbols) * These are the tags we expect to see in normal resource bundle files associated * with a locale and calendar */ +static const char gCalendarTag[]="calendar"; +static const char gGregorianTag[]="gregorian"; static const char gErasTag[]="eras"; static const char gCyclicNameSetsTag[]="cyclicNameSets"; static const char gNameSetYearsTag[]="years"; @@ -206,11 +214,11 @@ static const char gNamesAbbrTag[]="abbreviated"; static const char gNamesShortTag[]="short"; static const char gNamesNarrowTag[]="narrow"; static const char gNamesAllTag[]="all"; -static const char gNamesLeapTag[]="leap"; static const char gNamesFormatTag[]="format"; static const char gNamesStandaloneTag[]="stand-alone"; static const char gNamesNumericTag[]="numeric"; static const char gAmPmMarkersTag[]="AmPmMarkers"; +static const char gAmPmMarkersAbbrTag[]="AmPmMarkersAbbr"; static const char gAmPmMarkersNarrowTag[]="AmPmMarkersNarrow"; static const char gQuartersTag[]="quarters"; static const char gNumberElementsTag[]="NumberElements"; @@ -293,8 +301,8 @@ DateFormatSymbols::assignArray(UnicodeString*& dstArray, const UnicodeString* srcArray, int32_t srcCount) { - // assignArray() is only called by copyData(), which in turn implements the - // copy constructor and the assignment operator. + // assignArray() is only called by copyData() and initializeData(), which in turn + // implements the copy constructor and the assignment operator. // All strings in a DateFormatSymbols object are created in one of the following // three ways that all allow to safely use UnicodeString::fastCopyFrom(): // - readonly-aliases from resource bundles @@ -1271,6 +1279,12 @@ DateFormatSymbols::initZoneStringsArray(void) { TimeZoneNames *tzNames = NULL; int32_t rows = 0; + static const UTimeZoneNameType TYPES[] = { + UTZNM_LONG_STANDARD, UTZNM_SHORT_STANDARD, + UTZNM_LONG_DAYLIGHT, UTZNM_SHORT_DAYLIGHT + }; + static const int32_t NUM_TYPES = 4; + do { // dummy do-while tzids = TimeZone::createTimeZoneIDEnumeration(ZONE_SET, NULL, NULL, status); @@ -1289,6 +1303,8 @@ DateFormatSymbols::initZoneStringsArray(void) { uprv_memset(zarray, 0, size); tzNames = TimeZoneNames::createInstance(fZSFLocale, status); + tzNames->loadAllDisplayNames(status); + if (U_FAILURE(status)) { break; } const UnicodeString *tzid; int32_t i = 0; @@ -1307,10 +1323,7 @@ DateFormatSymbols::initZoneStringsArray(void) { } zarray[i][0].setTo(*tzid); - zarray[i][1].setTo(tzNames->getDisplayName(*tzid, UTZNM_LONG_STANDARD, now, tzDispName)); - zarray[i][2].setTo(tzNames->getDisplayName(*tzid, UTZNM_SHORT_STANDARD, now, tzDispName)); - zarray[i][3].setTo(tzNames->getDisplayName(*tzid, UTZNM_LONG_DAYLIGHT, now, tzDispName)); - zarray[i][4].setTo(tzNames->getDisplayName(*tzid, UTZNM_SHORT_DAYLIGHT, now, tzDispName)); + tzNames->getDisplayNames(*tzid, TYPES, NUM_TYPES, now, zarray[i]+1, status); i++; } @@ -1324,6 +1337,7 @@ DateFormatSymbols::initZoneStringsArray(void) { } } uprv_free(zarray); + zarray = NULL; } } @@ -1336,7 +1350,7 @@ DateFormatSymbols::initZoneStringsArray(void) { fLocaleZoneStrings = zarray; fZoneStringsRowCount = rows; - fZoneStringsColCount = 5; + fZoneStringsColCount = 1 + NUM_TYPES; } void @@ -1431,25 +1445,409 @@ DateFormatSymbols::setLocalPatternChars(const UnicodeString& newLocalPatternChar //------------------------------------------------------ -static void -initField(UnicodeString **field, int32_t& length, const UResourceBundle *data, UErrorCode &status) { - if (U_SUCCESS(status)) { - int32_t strLen = 0; - length = ures_getSize(data); - *field = newUnicodeStringArray(length); - if (*field) { - for(int32_t i = 0; i<length; i++) { - const UChar *resStr = ures_getStringByIndex(data, i, &strLen, &status); - // setTo() - see assignArray comments - (*(field)+i)->setTo(TRUE, resStr, strLen); +namespace { + +// Constants declarations +static const UChar kCalendarAliasPrefixUChar[] = { + SOLIDUS, CAP_L, CAP_O, CAP_C, CAP_A, CAP_L, CAP_E, SOLIDUS, + LOW_C, LOW_A, LOW_L, LOW_E, LOW_N, LOW_D, LOW_A, LOW_R, SOLIDUS +}; +static const UChar kGregorianTagUChar[] = { + LOW_G, LOW_R, LOW_E, LOW_G, LOW_O, LOW_R, LOW_I, LOW_A, LOW_N +}; +static const UChar kVariantTagUChar[] = { + PERCENT, LOW_V, LOW_A, LOW_R, LOW_I, LOW_A, LOW_N, LOW_T +}; +static const UChar kLeapTagUChar[] = { + LOW_L, LOW_E, LOW_A, LOW_P +}; +static const UChar kCyclicNameSetsTagUChar[] = { + LOW_C, LOW_Y, LOW_C, LOW_L, LOW_I, LOW_C, CAP_N, LOW_A, LOW_M, LOW_E, CAP_S, LOW_E, LOW_T, LOW_S +}; +static const UChar kYearsTagUChar[] = { + SOLIDUS, LOW_Y, LOW_E, LOW_A, LOW_R, LOW_S +}; +static const UChar kZodiacsUChar[] = { + SOLIDUS, LOW_Z, LOW_O, LOW_D, LOW_I, LOW_A, LOW_C, LOW_S +}; +static const UChar kDayPartsTagUChar[] = { + SOLIDUS, LOW_D, LOW_A, LOW_Y, CAP_P, LOW_A, LOW_R, LOW_T, LOW_S +}; +static const UChar kFormatTagUChar[] = { + SOLIDUS, LOW_F, LOW_O, LOW_R, LOW_M, LOW_A, LOW_T +}; +static const UChar kAbbrTagUChar[] = { + SOLIDUS, LOW_A, LOW_B, LOW_B, LOW_R, LOW_E, LOW_V, LOW_I, LOW_A, LOW_T, LOW_E, LOW_D +}; + +// ResourceSink to enumerate all calendar resources +struct CalendarDataSink : public ResourceSink { + + // Enum which specifies the type of alias received, or no alias + enum AliasType { + SAME_CALENDAR, + DIFFERENT_CALENDAR, + GREGORIAN, + NONE + }; + + // Data structures to store resources from the current resource bundle + Hashtable arrays; + Hashtable arraySizes; + Hashtable maps; + /** + * Whenever there are aliases, the same object will be added twice to 'map'. + * To avoid double deletion, 'maps' won't take ownership of the objects. Instead, + * 'mapRefs' will own them and will delete them when CalendarDataSink is deleted. + */ + UVector mapRefs; + + // Paths and the aliases they point to + UVector aliasPathPairs; + + // Current and next calendar resource table which should be loaded + UnicodeString currentCalendarType; + UnicodeString nextCalendarType; + + // Resources to visit when enumerating fallback calendars + LocalPointer<UVector> resourcesToVisit; + + // Alias' relative path populated whenever an alias is read + UnicodeString aliasRelativePath; + + // Initializes CalendarDataSink with default values + CalendarDataSink(UErrorCode& status) + : arrays(FALSE, status), arraySizes(FALSE, status), maps(FALSE, status), + mapRefs(deleteHashtable, NULL, 10, status), + aliasPathPairs(uprv_deleteUObject, uhash_compareUnicodeString, status), + currentCalendarType(), nextCalendarType(), + resourcesToVisit(NULL), aliasRelativePath() { + if (U_FAILURE(status)) { return; } + } + virtual ~CalendarDataSink(); + + // Configure the CalendarSink to visit all the resources + void visitAllResources() { + resourcesToVisit.adoptInstead(NULL); + } + + // Actions to be done before enumerating + void preEnumerate(const UnicodeString &calendarType) { + currentCalendarType = calendarType; + nextCalendarType.setToBogus(); + aliasPathPairs.removeAllElements(); + } + + virtual void put(const char *key, ResourceValue &value, UBool, UErrorCode &errorCode) { + if (U_FAILURE(errorCode)) { return; } + U_ASSERT(!currentCalendarType.isEmpty()); + + // Stores the resources to visit on the next calendar. + LocalPointer<UVector> resourcesToVisitNext(NULL); + ResourceTable calendarData = value.getTable(errorCode); + if (U_FAILURE(errorCode)) { return; } + + // Enumerate all resources for this calendar + for (int i = 0; calendarData.getKeyAndValue(i, key, value); i++) { + UnicodeString keyUString(key, -1, US_INV); + + // == Handle aliases == + AliasType aliasType = processAliasFromValue(keyUString, value, errorCode); + if (U_FAILURE(errorCode)) { return; } + if (aliasType == GREGORIAN) { + // Ignore aliases to the gregorian calendar, all of its resources will be loaded anyway. + continue; + + } else if (aliasType == DIFFERENT_CALENDAR) { + // Whenever an alias to the next calendar (except gregorian) is encountered, register the + // calendar type it's pointing to + if (resourcesToVisitNext.isNull()) { + resourcesToVisitNext + .adoptInsteadAndCheckErrorCode(new UVector(uprv_deleteUObject, uhash_compareUnicodeString, errorCode), + errorCode); + if (U_FAILURE(errorCode)) { return; } + } + LocalPointer<UnicodeString> aliasRelativePathCopy(new UnicodeString(aliasRelativePath), errorCode); + resourcesToVisitNext->addElement(aliasRelativePathCopy.getAlias(), errorCode); + if (U_FAILURE(errorCode)) { return; } + // Only release ownership after resourcesToVisitNext takes it (no error happened): + aliasRelativePathCopy.orphan(); + continue; + + } else if (aliasType == SAME_CALENDAR) { + // Register same-calendar alias + if (arrays.get(aliasRelativePath) == NULL && maps.get(aliasRelativePath) == NULL) { + LocalPointer<UnicodeString> aliasRelativePathCopy(new UnicodeString(aliasRelativePath), errorCode); + aliasPathPairs.addElement(aliasRelativePathCopy.getAlias(), errorCode); + if (U_FAILURE(errorCode)) { return; } + // Only release ownership after aliasPathPairs takes it (no error happened): + aliasRelativePathCopy.orphan(); + LocalPointer<UnicodeString> keyUStringCopy(new UnicodeString(keyUString), errorCode); + aliasPathPairs.addElement(keyUStringCopy.getAlias(), errorCode); + if (U_FAILURE(errorCode)) { return; } + // Only release ownership after aliasPathPairs takes it (no error happened): + keyUStringCopy.orphan(); + } + continue; + } + + // Only visit the resources that were referenced by an alias on the previous calendar + // (AmPmMarkersAbbr is an exception). + if (!resourcesToVisit.isNull() && !resourcesToVisit->isEmpty() && !resourcesToVisit->contains(&keyUString) + && uprv_strcmp(key, gAmPmMarkersAbbrTag) != 0) { continue; } + + // == Handle data == + if (uprv_strcmp(key, gAmPmMarkersTag) == 0 + || uprv_strcmp(key, gAmPmMarkersAbbrTag) == 0 + || uprv_strcmp(key, gAmPmMarkersNarrowTag) == 0) { + if (arrays.get(keyUString) == NULL) { + ResourceArray resourceArray = value.getArray(errorCode); + int32_t arraySize = resourceArray.getSize(); + LocalArray<UnicodeString> stringArray(new UnicodeString[arraySize], errorCode); + value.getStringArray(stringArray.getAlias(), arraySize, errorCode); + arrays.put(keyUString, stringArray.orphan(), errorCode); + arraySizes.puti(keyUString, arraySize, errorCode); + if (U_FAILURE(errorCode)) { return; } + } + } else if (uprv_strcmp(key, gErasTag) == 0 + || uprv_strcmp(key, gDayNamesTag) == 0 + || uprv_strcmp(key, gMonthNamesTag) == 0 + || uprv_strcmp(key, gQuartersTag) == 0 + || uprv_strcmp(key, gDayPeriodTag) == 0 + || uprv_strcmp(key, gMonthPatternsTag) == 0 + || uprv_strcmp(key, gCyclicNameSetsTag) == 0) { + processResource(keyUString, key, value, errorCode); } } - else { - length = 0; - status = U_MEMORY_ALLOCATION_ERROR; + + // Apply same-calendar aliases + UBool modified; + do { + modified = false; + for (int32_t i = 0; i < aliasPathPairs.size();) { + UBool mod = false; + UnicodeString *alias = (UnicodeString*)aliasPathPairs[i]; + UnicodeString *aliasArray; + Hashtable *aliasMap; + if ((aliasArray = (UnicodeString*)arrays.get(*alias)) != NULL) { + // Clone the array + int32_t aliasArraySize = arraySizes.geti(*alias); + LocalArray<UnicodeString> aliasArrayCopy(new UnicodeString[aliasArraySize], errorCode); + if (U_FAILURE(errorCode)) { return; } + uprv_arrayCopy(aliasArray, aliasArrayCopy.getAlias(), aliasArraySize); + // Put the array on the 'arrays' map + UnicodeString *path = (UnicodeString*)aliasPathPairs[i + 1]; + arrays.put(*path, aliasArrayCopy.orphan(), errorCode); + arraySizes.puti(*path, aliasArraySize, errorCode); + if (U_FAILURE(errorCode)) { return; } + mod = true; + } else if ((aliasMap = (Hashtable*)maps.get(*alias)) != NULL) { + UnicodeString *path = (UnicodeString*)aliasPathPairs[i + 1]; + maps.put(*path, aliasMap, errorCode); + if (U_FAILURE(errorCode)) { return; } + mod = true; + } + if (mod) { + aliasPathPairs.removeElementAt(i + 1); + aliasPathPairs.removeElementAt(i); + modified = true; + } else { + i += 2; + } + } + } while (modified && !aliasPathPairs.isEmpty()); + + // Set the resources to visit on the next calendar + if (!resourcesToVisitNext.isNull()) { + resourcesToVisit.moveFrom(resourcesToVisitNext); + } + } + + // Process the nested resource bundle tables + void processResource(UnicodeString &path, const char *key, ResourceValue &value, UErrorCode &errorCode) { + if (U_FAILURE(errorCode)) return; + + ResourceTable table = value.getTable(errorCode); + if (U_FAILURE(errorCode)) return; + Hashtable* stringMap = NULL; + + // Iterate over all the elements of the table and add them to the map + for (int i = 0; table.getKeyAndValue(i, key, value); i++) { + UnicodeString keyUString(key, -1, US_INV); + + // Ignore '%variant' keys + if (keyUString.endsWith(kVariantTagUChar, UPRV_LENGTHOF(kVariantTagUChar))) { + continue; + } + + // == Handle String elements == + if (value.getType() == URES_STRING) { + // We are on a leaf, store the map elements into the stringMap + if (i == 0) { + LocalPointer<Hashtable> stringMapPtr(new Hashtable(FALSE, errorCode), errorCode); + stringMap = stringMapPtr.getAlias(); + maps.put(path, stringMap, errorCode); + // mapRefs will take ownership of 'stringMap': + mapRefs.addElement(stringMap, errorCode); + if (U_FAILURE(errorCode)) { return; } + // Only release ownership after mapRefs takes it (no error happened): + stringMapPtr.orphan(); + stringMap->setValueDeleter(uprv_deleteUObject); + } + U_ASSERT(stringMap != NULL); + int32_t valueStringSize; + const UChar *valueString = value.getString(valueStringSize, errorCode); + if (U_FAILURE(errorCode)) { return; } + LocalPointer<UnicodeString> valueUString(new UnicodeString(TRUE, valueString, valueStringSize), errorCode); + stringMap->put(keyUString, valueUString.orphan(), errorCode); + if (U_FAILURE(errorCode)) { return; } + continue; + } + U_ASSERT(stringMap == NULL); + + // Store the current path's length and append the current key to the path. + int32_t pathLength = path.length(); + path.append(SOLIDUS).append(keyUString); + + // In cyclicNameSets ignore everything but years/format/abbreviated + // and zodiacs/format/abbreviated + if (path.startsWith(kCyclicNameSetsTagUChar, UPRV_LENGTHOF(kCyclicNameSetsTagUChar))) { + UBool skip = TRUE; + int32_t startIndex = UPRV_LENGTHOF(kCyclicNameSetsTagUChar); + int32_t length = 0; + if (startIndex == path.length() + || path.compare(startIndex, (length = UPRV_LENGTHOF(kZodiacsUChar)), kZodiacsUChar, 0, UPRV_LENGTHOF(kZodiacsUChar)) == 0 + || path.compare(startIndex, (length = UPRV_LENGTHOF(kYearsTagUChar)), kYearsTagUChar, 0, UPRV_LENGTHOF(kYearsTagUChar)) == 0 + || path.compare(startIndex, (length = UPRV_LENGTHOF(kDayPartsTagUChar)), kDayPartsTagUChar, 0, UPRV_LENGTHOF(kDayPartsTagUChar)) == 0) { + startIndex += length; + length = 0; + if (startIndex == path.length() + || path.compare(startIndex, (length = UPRV_LENGTHOF(kFormatTagUChar)), kFormatTagUChar, 0, UPRV_LENGTHOF(kFormatTagUChar)) == 0) { + startIndex += length; + length = 0; + if (startIndex == path.length() + || path.compare(startIndex, (length = UPRV_LENGTHOF(kAbbrTagUChar)), kAbbrTagUChar, 0, UPRV_LENGTHOF(kAbbrTagUChar)) == 0) { + skip = FALSE; + } + } + } + if (skip) { + // Drop the latest key on the path and continue + path.retainBetween(0, pathLength); + continue; + } + } + + // == Handle aliases == + if (arrays.get(path) != NULL || maps.get(path) != NULL) { + // Drop the latest key on the path and continue + path.retainBetween(0, pathLength); + continue; + } + + AliasType aliasType = processAliasFromValue(path, value, errorCode); + if (U_FAILURE(errorCode)) { return; } + if (aliasType == SAME_CALENDAR) { + // Store the alias path and the current path on aliasPathPairs + LocalPointer<UnicodeString> aliasRelativePathCopy(new UnicodeString(aliasRelativePath), errorCode); + aliasPathPairs.addElement(aliasRelativePathCopy.getAlias(), errorCode); + if (U_FAILURE(errorCode)) { return; } + // Only release ownership after aliasPathPairs takes it (no error happened): + aliasRelativePathCopy.orphan(); + LocalPointer<UnicodeString> pathCopy(new UnicodeString(path), errorCode); + aliasPathPairs.addElement(pathCopy.getAlias(), errorCode); + if (U_FAILURE(errorCode)) { return; } + // Only release ownership after aliasPathPairs takes it (no error happened): + pathCopy.orphan(); + + // Drop the latest key on the path and continue + path.retainBetween(0, pathLength); + continue; + } + U_ASSERT(aliasType == NONE); + + // == Handle data == + if (value.getType() == URES_ARRAY) { + // We are on a leaf, store the array + ResourceArray rDataArray = value.getArray(errorCode); + int32_t dataArraySize = rDataArray.getSize(); + LocalArray<UnicodeString> dataArray(new UnicodeString[dataArraySize], errorCode); + value.getStringArray(dataArray.getAlias(), dataArraySize, errorCode); + arrays.put(path, dataArray.orphan(), errorCode); + arraySizes.puti(path, dataArraySize, errorCode); + if (U_FAILURE(errorCode)) { return; } + } else if (value.getType() == URES_TABLE) { + // We are not on a leaf, recursively process the subtable. + processResource(path, key, value, errorCode); + if (U_FAILURE(errorCode)) { return; } + } + + // Drop the latest key on the path + path.retainBetween(0, pathLength); } } + + // Populates an AliasIdentifier with the alias information contained on the UResource.Value. + AliasType processAliasFromValue(UnicodeString ¤tRelativePath, ResourceValue &value, + UErrorCode &errorCode) { + if (U_FAILURE(errorCode)) { return NONE; } + + if (value.getType() == URES_ALIAS) { + int32_t aliasPathSize; + const UChar* aliasPathUChar = value.getAliasString(aliasPathSize, errorCode); + if (U_FAILURE(errorCode)) { return NONE; } + UnicodeString aliasPath(aliasPathUChar, aliasPathSize); + const int32_t aliasPrefixLength = UPRV_LENGTHOF(kCalendarAliasPrefixUChar); + if (aliasPath.startsWith(kCalendarAliasPrefixUChar, aliasPrefixLength) + && aliasPath.length() > aliasPrefixLength) { + int32_t typeLimit = aliasPath.indexOf(SOLIDUS, aliasPrefixLength); + if (typeLimit > aliasPrefixLength) { + const UnicodeString aliasCalendarType = + aliasPath.tempSubStringBetween(aliasPrefixLength, typeLimit); + aliasRelativePath.setTo(aliasPath, typeLimit + 1, aliasPath.length()); + + if (currentCalendarType == aliasCalendarType + && currentRelativePath != aliasRelativePath) { + // If we have an alias to the same calendar, the path to the resource must be different + return SAME_CALENDAR; + + } else if (currentCalendarType != aliasCalendarType + && currentRelativePath == aliasRelativePath) { + // If we have an alias to a different calendar, the path to the resource must be the same + if (aliasCalendarType.compare(kGregorianTagUChar, UPRV_LENGTHOF(kGregorianTagUChar)) == 0) { + return GREGORIAN; + } else if (nextCalendarType.isBogus()) { + nextCalendarType = aliasCalendarType; + return DIFFERENT_CALENDAR; + } else if (nextCalendarType == aliasCalendarType) { + return DIFFERENT_CALENDAR; + } + } + } + } + errorCode = U_INTERNAL_PROGRAM_ERROR; + return NONE; + } + return NONE; + } + + // Deleter function to be used by 'arrays' + static void U_CALLCONV deleteUnicodeStringArray(void *uArray) { + delete[] static_cast<UnicodeString *>(uArray); + } + + // Deleter function to be used by 'maps' + static void U_CALLCONV deleteHashtable(void *table) { + delete static_cast<Hashtable *>(table); + } +}; +// Virtual destructors have to be defined out of line +CalendarDataSink::~CalendarDataSink() { + arrays.setValueDeleter(deleteUnicodeStringArray); } +} + +//------------------------------------------------------ static void initField(UnicodeString **field, int32_t& length, const UChar *data, LastResortSize numStr, LastResortSize strLen, UErrorCode &status) { @@ -1471,16 +1869,89 @@ initField(UnicodeString **field, int32_t& length, const UChar *data, LastResortS } static void -initLeapMonthPattern(UnicodeString *field, int32_t index, const UResourceBundle *data, UErrorCode &status) { +initField(UnicodeString **field, int32_t& length, CalendarDataSink &sink, CharString &key, UErrorCode &status) { + if (U_SUCCESS(status)) { + UnicodeString keyUString(key.data(), -1, US_INV); + UnicodeString* array = static_cast<UnicodeString*>(sink.arrays.get(keyUString)); + + if (array != NULL) { + length = sink.arraySizes.geti(keyUString); + *field = array; + // DateFormatSymbols takes ownership of the array: + sink.arrays.remove(keyUString); + } else { + length = 0; + status = U_MISSING_RESOURCE_ERROR; + } + } +} + +static void +initField(UnicodeString **field, int32_t& length, CalendarDataSink &sink, CharString &key, int32_t arrayOffset, UErrorCode &status) { + if (U_SUCCESS(status)) { + UnicodeString keyUString(key.data(), -1, US_INV); + UnicodeString* array = static_cast<UnicodeString*>(sink.arrays.get(keyUString)); + + if (array != NULL) { + int32_t arrayLength = sink.arraySizes.geti(keyUString); + length = arrayLength + arrayOffset; + *field = new UnicodeString[length]; + if (*field == NULL) { + status = U_MEMORY_ALLOCATION_ERROR; + return; + } + uprv_arrayCopy(array, 0, *field, arrayOffset, arrayLength); + } else { + length = 0; + status = U_MISSING_RESOURCE_ERROR; + } + } +} + +static void +initLeapMonthPattern(UnicodeString *field, int32_t index, CalendarDataSink &sink, CharString &path, UErrorCode &status) { field[index].remove(); if (U_SUCCESS(status)) { - int32_t strLen = 0; - const UChar *resStr = ures_getStringByKey(data, gNamesLeapTag, &strLen, &status); - if (U_SUCCESS(status)) { - field[index].setTo(TRUE, resStr, strLen); + UnicodeString pathUString(path.data(), -1, US_INV); + Hashtable *leapMonthTable = static_cast<Hashtable*>(sink.maps.get(pathUString)); + if (leapMonthTable != NULL) { + UnicodeString leapLabel(FALSE, kLeapTagUChar, UPRV_LENGTHOF(kLeapTagUChar)); + UnicodeString *leapMonthPattern = static_cast<UnicodeString*>(leapMonthTable->get(leapLabel)); + if (leapMonthPattern != NULL) { + field[index].fastCopyFrom(*leapMonthPattern); + } else { + field[index].setToBogus(); + } + return; } + status = U_MISSING_RESOURCE_ERROR; } - status = U_ZERO_ERROR; +} + +static CharString +&buildResourcePath(CharString &path, const char* segment1, UErrorCode &errorCode) { + return path.clear().append(segment1, -1, errorCode); +} + +static CharString +&buildResourcePath(CharString &path, const char* segment1, const char* segment2, + UErrorCode &errorCode) { + return buildResourcePath(path, segment1, errorCode).append('/', errorCode) + .append(segment2, -1, errorCode); +} + +static CharString +&buildResourcePath(CharString &path, const char* segment1, const char* segment2, + const char* segment3, UErrorCode &errorCode) { + return buildResourcePath(path, segment1, segment2, errorCode).append('/', errorCode) + .append(segment3, -1, errorCode); +} + +static CharString +&buildResourcePath(CharString &path, const char* segment1, const char* segment2, + const char* segment3, const char* segment4, UErrorCode &errorCode) { + return buildResourcePath(path, segment1, segment2, segment3, errorCode).append('/', errorCode) + .append(segment4, -1, errorCode); } typedef struct { @@ -1513,41 +1984,43 @@ static const char *dayPeriodKeys[] = {"midnight", "noon", "morning1", "afternoon1", "evening1", "night1", "morning2", "afternoon2", "evening2", "night2"}; -UnicodeString* loadDayPeriodStrings(CalendarData &calData, const char *tag, UBool standalone, +UnicodeString* loadDayPeriodStrings(CalendarDataSink &sink, CharString &path, int32_t &stringCount, UErrorCode &status) { - if (U_FAILURE(status)) { - return NULL; - } - - UResourceBundle *dayPeriodData; + if (U_FAILURE(status)) { return NULL; } - if (standalone) { - dayPeriodData = calData.getByKey3(gDayPeriodTag, gNamesStandaloneTag, tag, status); - } else { - dayPeriodData = calData.getByKey2(gDayPeriodTag, tag, status); - } + UnicodeString pathUString(path.data(), -1, US_INV); + Hashtable* map = static_cast<Hashtable*>(sink.maps.get(pathUString)); stringCount = UPRV_LENGTHOF(dayPeriodKeys); UnicodeString *strings = new UnicodeString[stringCount]; - for (int32_t i = 0; i < stringCount; ++i) { - //TODO: Check if there are fallbacks/aliases defined in the data; e.g., if there - //is no wide string, then use the narrow one? - strings[i].fastCopyFrom(ures_getUnicodeStringByKey(dayPeriodData, dayPeriodKeys[i], &status)); - if (U_FAILURE(status)) { - // string[i] will be bogus if ures_getUnicodeString() returns with an error, - // which is just the behavior we want. Simply reset the error code. - status = U_ZERO_ERROR; + if (strings == NULL) { + status = U_MEMORY_ALLOCATION_ERROR; + return NULL; + } + + if (map != NULL) { + for (int32_t i = 0; i < stringCount; ++i) { + UnicodeString dayPeriodKey(dayPeriodKeys[i], -1, US_INV); + UnicodeString *dayPeriod = static_cast<UnicodeString*>(map->get(dayPeriodKey)); + if (dayPeriod != NULL) { + strings[i].fastCopyFrom(*dayPeriod); + } else { + strings[i].setToBogus(); + } + } + } else { + for (int32_t i = 0; i < stringCount; i++) { + strings[i].setToBogus(); } } return strings; } + void DateFormatSymbols::initializeData(const Locale& locale, const char *type, UErrorCode& status, UBool useLastResortData) { - int32_t i; int32_t len = 0; - const UChar *resStr; /* In case something goes wrong, initialize all of the data to NULL. */ fEras = NULL; fErasCount = 0; @@ -1628,97 +2101,107 @@ DateFormatSymbols::initializeData(const Locale& locale, const char *type, UError if (U_FAILURE(status)) return; - /** - * Retrieve the string arrays we need from the resource bundle file. - * We cast away const here, but that's okay; we won't delete any of - * these. - */ - CalendarData calData(locale, type, status); + // Create a CalendarDataSink to process this data and the resouce bundles + CalendarDataSink calendarSink(status); + UResourceBundle *rb = ures_open(NULL, locale.getBaseName(), &status); + UResourceBundle *cb = ures_getByKey(rb, gCalendarTag, NULL, &status); - // load the first data item - UResourceBundle *erasMain = calData.getByKey(gErasTag, status); - UResourceBundle *eras = ures_getByKeyWithFallback(erasMain, gNamesAbbrTag, NULL, &status); - UErrorCode oldStatus = status; - UResourceBundle *eraNames = ures_getByKeyWithFallback(erasMain, gNamesWideTag, NULL, &status); - if ( status == U_MISSING_RESOURCE_ERROR ) { // Workaround because eras/wide was omitted from CLDR 1.3 - status = oldStatus; - eraNames = ures_getByKeyWithFallback(erasMain, gNamesAbbrTag, NULL, &status); - } - // current ICU4J falls back to abbreviated if narrow eras are missing, so we will too - oldStatus = status; - UResourceBundle *narrowEras = ures_getByKeyWithFallback(erasMain, gNamesNarrowTag, NULL, &status); - if ( status == U_MISSING_RESOURCE_ERROR ) { - status = oldStatus; - narrowEras = ures_getByKeyWithFallback(erasMain, gNamesAbbrTag, NULL, &status); - } - - UErrorCode tempStatus = U_ZERO_ERROR; - UResourceBundle *monthPatterns = calData.getByKey(gMonthPatternsTag, tempStatus); - if (U_SUCCESS(tempStatus) && monthPatterns != NULL) { - fLeapMonthPatterns = newUnicodeStringArray(kMonthPatternsCount); - if (fLeapMonthPatterns) { - initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternFormatWide, calData.getByKey2(gMonthPatternsTag, gNamesWideTag, tempStatus), tempStatus); - initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternFormatAbbrev, calData.getByKey2(gMonthPatternsTag, gNamesAbbrTag, tempStatus), tempStatus); - initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternFormatNarrow, calData.getByKey2(gMonthPatternsTag, gNamesNarrowTag, tempStatus), tempStatus); - initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternStandaloneWide, calData.getByKey3(gMonthPatternsTag, gNamesStandaloneTag, gNamesWideTag, tempStatus), tempStatus); - initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternStandaloneAbbrev, calData.getByKey3(gMonthPatternsTag, gNamesStandaloneTag, gNamesAbbrTag, tempStatus), tempStatus); - initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternStandaloneNarrow, calData.getByKey3(gMonthPatternsTag, gNamesStandaloneTag, gNamesNarrowTag, tempStatus), tempStatus); - initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternNumeric, calData.getByKey3(gMonthPatternsTag, gNamesNumericTag, gNamesAllTag, tempStatus), tempStatus); - if (U_SUCCESS(tempStatus)) { - // Hack to fix bad C inheritance for dangi monthPatterns (OK in J); this should be handled by aliases in root, but isn't. - // The ordering of the following statements is important. - if (fLeapMonthPatterns[kLeapMonthPatternFormatAbbrev].isEmpty()) { - fLeapMonthPatterns[kLeapMonthPatternFormatAbbrev].setTo(fLeapMonthPatterns[kLeapMonthPatternFormatWide]); - }; - if (fLeapMonthPatterns[kLeapMonthPatternFormatNarrow].isEmpty()) { - fLeapMonthPatterns[kLeapMonthPatternFormatNarrow].setTo(fLeapMonthPatterns[kLeapMonthPatternStandaloneNarrow]); - }; - if (fLeapMonthPatterns[kLeapMonthPatternStandaloneWide].isEmpty()) { - fLeapMonthPatterns[kLeapMonthPatternStandaloneWide].setTo(fLeapMonthPatterns[kLeapMonthPatternFormatWide]); - }; - if (fLeapMonthPatterns[kLeapMonthPatternStandaloneAbbrev].isEmpty()) { - fLeapMonthPatterns[kLeapMonthPatternStandaloneAbbrev].setTo(fLeapMonthPatterns[kLeapMonthPatternFormatAbbrev]); - }; - // end of hack - fLeapMonthPatternsCount = kMonthPatternsCount; - } else { - delete[] fLeapMonthPatterns; - fLeapMonthPatterns = NULL; + if (U_FAILURE(status)) return; + + // Iterate over the resource bundle data following the fallbacks through different calendar types + UnicodeString calendarType((type != NULL && *type != '\0')? type : gGregorianTag, -1, US_INV); + while (!calendarType.isBogus()) { + CharString calendarTypeBuffer; + calendarTypeBuffer.appendInvariantChars(calendarType, status); + if (U_FAILURE(status)) { return; } + const char *calendarTypeCArray = calendarTypeBuffer.data(); + + // Enumerate this calendar type. If the calendar is not found fallback to gregorian + UErrorCode oldStatus = status; + UResourceBundle *ctb = ures_getByKeyWithFallback(cb, calendarTypeCArray, NULL, &status); + if (status == U_MISSING_RESOURCE_ERROR) { + ures_close(ctb); + if (uprv_strcmp(calendarTypeCArray, gGregorianTag) != 0) { + calendarType.setTo(FALSE, kGregorianTagUChar, UPRV_LENGTHOF(kGregorianTagUChar)); + calendarSink.visitAllResources(); + status = oldStatus; + continue; } + return; } - } - tempStatus = U_ZERO_ERROR; - UResourceBundle *cyclicNameSets= calData.getByKey(gCyclicNameSetsTag, tempStatus); - if (U_SUCCESS(tempStatus) && cyclicNameSets != NULL) { - UResourceBundle *nameSetYears = ures_getByKeyWithFallback(cyclicNameSets, gNameSetYearsTag, NULL, &tempStatus); - if (U_SUCCESS(tempStatus)) { - UResourceBundle *nameSetYearsFmt = ures_getByKeyWithFallback(nameSetYears, gNamesFormatTag, NULL, &tempStatus); - if (U_SUCCESS(tempStatus)) { - UResourceBundle *nameSetYearsFmtAbbrev = ures_getByKeyWithFallback(nameSetYearsFmt, gNamesAbbrTag, NULL, &tempStatus); - if (U_SUCCESS(tempStatus)) { - initField(&fShortYearNames, fShortYearNamesCount, nameSetYearsFmtAbbrev, tempStatus); - ures_close(nameSetYearsFmtAbbrev); - } - ures_close(nameSetYearsFmt); - } - ures_close(nameSetYears); + calendarSink.preEnumerate(calendarType); + ures_getAllItemsWithFallback(ctb, "", calendarSink, status); + ures_close(ctb); + if (U_FAILURE(status)) break; + + // Stop loading when gregorian was loaded + if (uprv_strcmp(calendarTypeCArray, gGregorianTag) == 0) { + break; } - UResourceBundle *nameSetZodiacs = ures_getByKeyWithFallback(cyclicNameSets, gNameSetZodiacsTag, NULL, &tempStatus); + + // Get the next calendar type to process from the sink + calendarType = calendarSink.nextCalendarType; + + // Gregorian is always the last fallback + if (calendarType.isBogus()) { + calendarType.setTo(FALSE, kGregorianTagUChar, UPRV_LENGTHOF(kGregorianTagUChar)); + calendarSink.visitAllResources(); + } + } + + // CharString object to build paths + CharString path; + + // Load Leap Month Patterns + UErrorCode tempStatus = status; + fLeapMonthPatterns = newUnicodeStringArray(kMonthPatternsCount); + if (fLeapMonthPatterns) { + initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternFormatWide, calendarSink, + buildResourcePath(path, gMonthPatternsTag, gNamesFormatTag, gNamesWideTag, tempStatus), tempStatus); + initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternFormatAbbrev, calendarSink, + buildResourcePath(path, gMonthPatternsTag, gNamesFormatTag, gNamesAbbrTag, tempStatus), tempStatus); + initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternFormatNarrow, calendarSink, + buildResourcePath(path, gMonthPatternsTag, gNamesFormatTag, gNamesNarrowTag, tempStatus), tempStatus); + initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternStandaloneWide, calendarSink, + buildResourcePath(path, gMonthPatternsTag, gNamesStandaloneTag, gNamesWideTag, tempStatus), tempStatus); + initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternStandaloneAbbrev, calendarSink, + buildResourcePath(path, gMonthPatternsTag, gNamesStandaloneTag, gNamesAbbrTag, tempStatus), tempStatus); + initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternStandaloneNarrow, calendarSink, + buildResourcePath(path, gMonthPatternsTag, gNamesStandaloneTag, gNamesNarrowTag, tempStatus), tempStatus); + initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternNumeric, calendarSink, + buildResourcePath(path, gMonthPatternsTag, gNamesNumericTag, gNamesAllTag, tempStatus), tempStatus); if (U_SUCCESS(tempStatus)) { - UResourceBundle *nameSetZodiacsFmt = ures_getByKeyWithFallback(nameSetZodiacs, gNamesFormatTag, NULL, &tempStatus); - if (U_SUCCESS(tempStatus)) { - UResourceBundle *nameSetZodiacsFmtAbbrev = ures_getByKeyWithFallback(nameSetZodiacsFmt, gNamesAbbrTag, NULL, &tempStatus); - if (U_SUCCESS(tempStatus)) { - initField(&fShortZodiacNames, fShortZodiacNamesCount, nameSetZodiacsFmtAbbrev, tempStatus); - ures_close(nameSetZodiacsFmtAbbrev); - } - ures_close(nameSetZodiacsFmt); - } - ures_close(nameSetZodiacs); + // Hack to fix bad C inheritance for dangi monthPatterns (OK in J); this should be handled by aliases in root, but isn't. + // The ordering of the following statements is important. + if (fLeapMonthPatterns[kLeapMonthPatternFormatAbbrev].isEmpty()) { + fLeapMonthPatterns[kLeapMonthPatternFormatAbbrev].setTo(fLeapMonthPatterns[kLeapMonthPatternFormatWide]); + }; + if (fLeapMonthPatterns[kLeapMonthPatternFormatNarrow].isEmpty()) { + fLeapMonthPatterns[kLeapMonthPatternFormatNarrow].setTo(fLeapMonthPatterns[kLeapMonthPatternStandaloneNarrow]); + }; + if (fLeapMonthPatterns[kLeapMonthPatternStandaloneWide].isEmpty()) { + fLeapMonthPatterns[kLeapMonthPatternStandaloneWide].setTo(fLeapMonthPatterns[kLeapMonthPatternFormatWide]); + }; + if (fLeapMonthPatterns[kLeapMonthPatternStandaloneAbbrev].isEmpty()) { + fLeapMonthPatterns[kLeapMonthPatternStandaloneAbbrev].setTo(fLeapMonthPatterns[kLeapMonthPatternFormatAbbrev]); + }; + // end of hack + fLeapMonthPatternsCount = kMonthPatternsCount; + } else { + delete[] fLeapMonthPatterns; + fLeapMonthPatterns = NULL; } } + // Load cyclic names sets + tempStatus = status; + initField(&fShortYearNames, fShortYearNamesCount, calendarSink, + buildResourcePath(path, gCyclicNameSetsTag, gNameSetYearsTag, gNamesFormatTag, gNamesAbbrTag, tempStatus), tempStatus); + initField(&fShortZodiacNames, fShortZodiacNamesCount, calendarSink, + buildResourcePath(path, gCyclicNameSetsTag, gNameSetZodiacsTag, gNamesFormatTag, gNamesAbbrTag, tempStatus), tempStatus); + + // Load context transforms and capitalization tempStatus = U_ZERO_ERROR; UResourceBundle *localeBundle = ures_open(NULL, locale.getName(), &tempStatus); if (U_SUCCESS(tempStatus)) { @@ -1775,126 +2258,108 @@ DateFormatSymbols::initializeData(const Locale& locale, const char *type, UError fTimeSeparator.setTo(DateFormatSymbols::DEFAULT_TIME_SEPARATOR); } - fWideDayPeriods = loadDayPeriodStrings(calData, gNamesWideTag, FALSE, - fWideDayPeriodsCount, status); - fNarrowDayPeriods = loadDayPeriodStrings(calData, gNamesNarrowTag, FALSE, - fNarrowDayPeriodsCount, status); - fAbbreviatedDayPeriods = loadDayPeriodStrings(calData, gNamesAbbrTag, FALSE, - fAbbreviatedDayPeriodsCount, status); - fStandaloneWideDayPeriods = loadDayPeriodStrings(calData, gNamesWideTag, TRUE, - fStandaloneWideDayPeriodsCount, status); - fStandaloneNarrowDayPeriods = loadDayPeriodStrings(calData, gNamesNarrowTag, TRUE, - fStandaloneNarrowDayPeriodsCount, status); - fStandaloneAbbreviatedDayPeriods = loadDayPeriodStrings(calData, gNamesAbbrTag, TRUE, - fStandaloneAbbreviatedDayPeriodsCount, status); - - UResourceBundle *weekdaysData = NULL; // Data closed by calData - UResourceBundle *abbrWeekdaysData = NULL; // Data closed by calData - UResourceBundle *shorterWeekdaysData = NULL; // Data closed by calData - UResourceBundle *narrowWeekdaysData = NULL; // Data closed by calData - UResourceBundle *standaloneWeekdaysData = NULL; // Data closed by calData - UResourceBundle *standaloneAbbrWeekdaysData = NULL; // Data closed by calData - UResourceBundle *standaloneShorterWeekdaysData = NULL; // Data closed by calData - UResourceBundle *standaloneNarrowWeekdaysData = NULL; // Data closed by calData + // Load day periods + fWideDayPeriods = loadDayPeriodStrings(calendarSink, + buildResourcePath(path, gDayPeriodTag, gNamesFormatTag, gNamesWideTag, status), + fWideDayPeriodsCount, status); + fNarrowDayPeriods = loadDayPeriodStrings(calendarSink, + buildResourcePath(path, gDayPeriodTag, gNamesFormatTag, gNamesNarrowTag, status), + fNarrowDayPeriodsCount, status); + fAbbreviatedDayPeriods = loadDayPeriodStrings(calendarSink, + buildResourcePath(path, gDayPeriodTag, gNamesFormatTag, gNamesAbbrTag, status), + fAbbreviatedDayPeriodsCount, status); + fStandaloneWideDayPeriods = loadDayPeriodStrings(calendarSink, + buildResourcePath(path, gDayPeriodTag, gNamesStandaloneTag, gNamesWideTag, status), + fStandaloneWideDayPeriodsCount, status); + fStandaloneNarrowDayPeriods = loadDayPeriodStrings(calendarSink, + buildResourcePath(path, gDayPeriodTag, gNamesStandaloneTag, gNamesNarrowTag, status), + fStandaloneNarrowDayPeriodsCount, status); + fStandaloneAbbreviatedDayPeriods = loadDayPeriodStrings(calendarSink, + buildResourcePath(path, gDayPeriodTag, gNamesStandaloneTag, gNamesAbbrTag, status), + fStandaloneAbbreviatedDayPeriodsCount, status); U_LOCALE_BASED(locBased, *this); - if (U_FAILURE(status)) - { - if (useLastResortData) - { - // Handle the case in which there is no resource data present. - // We don't have to generate usable patterns in this situation; - // we just need to produce something that will be semi-intelligible - // in most locales. - - status = U_USING_FALLBACK_WARNING; - - initField(&fEras, fErasCount, (const UChar *)gLastResortEras, kEraNum, kEraLen, status); - initField(&fEraNames, fEraNamesCount, (const UChar *)gLastResortEras, kEraNum, kEraLen, status); - initField(&fNarrowEras, fNarrowErasCount, (const UChar *)gLastResortEras, kEraNum, kEraLen, status); - initField(&fMonths, fMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status); - initField(&fShortMonths, fShortMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status); - initField(&fNarrowMonths, fNarrowMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status); - initField(&fStandaloneMonths, fStandaloneMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status); - initField(&fStandaloneShortMonths, fStandaloneShortMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status); - initField(&fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status); - initField(&fWeekdays, fWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status); - initField(&fShortWeekdays, fShortWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status); - initField(&fShorterWeekdays, fShorterWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status); - initField(&fNarrowWeekdays, fNarrowWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status); - initField(&fStandaloneWeekdays, fStandaloneWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status); - initField(&fStandaloneShortWeekdays, fStandaloneShortWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status); - initField(&fStandaloneShorterWeekdays, fStandaloneShorterWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status); - initField(&fStandaloneNarrowWeekdays, fStandaloneNarrowWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status); - initField(&fAmPms, fAmPmsCount, (const UChar *)gLastResortAmPmMarkers, kAmPmNum, kAmPmLen, status); - initField(&fNarrowAmPms, fNarrowAmPmsCount, (const UChar *)gLastResortAmPmMarkers, kAmPmNum, kAmPmLen, status); - initField(&fQuarters, fQuartersCount, (const UChar *)gLastResortQuarters, kQuarterNum, kQuarterLen, status); - initField(&fShortQuarters, fShortQuartersCount, (const UChar *)gLastResortQuarters, kQuarterNum, kQuarterLen, status); - initField(&fStandaloneQuarters, fStandaloneQuartersCount, (const UChar *)gLastResortQuarters, kQuarterNum, kQuarterLen, status); - initField(&fStandaloneShortQuarters, fStandaloneShortQuartersCount, (const UChar *)gLastResortQuarters, kQuarterNum, kQuarterLen, status); - fLocalPatternChars.setTo(TRUE, gPatternChars, PATTERN_CHARS_LEN); - } - goto cleanup; - } - // if we make it to here, the resource data is cool, and we can get everything out // of it that we need except for the time-zone and localized-pattern data, which // are stored in a separate file - locBased.setLocaleIDs(ures_getLocaleByType(eras, ULOC_VALID_LOCALE, &status), - ures_getLocaleByType(eras, ULOC_ACTUAL_LOCALE, &status)); + locBased.setLocaleIDs(ures_getLocaleByType(cb, ULOC_VALID_LOCALE, &status), + ures_getLocaleByType(cb, ULOC_ACTUAL_LOCALE, &status)); - initField(&fEras, fErasCount, eras, status); - initField(&fEraNames, fEraNamesCount, eraNames, status); - initField(&fNarrowEras, fNarrowErasCount, narrowEras, status); - - initField(&fMonths, fMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesWideTag, status), status); - initField(&fShortMonths, fShortMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesAbbrTag, status), status); - - initField(&fNarrowMonths, fNarrowMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesNarrowTag, status), status); - if(status == U_MISSING_RESOURCE_ERROR) { - status = U_ZERO_ERROR; - initField(&fNarrowMonths, fNarrowMonthsCount, calData.getByKey3(gMonthNamesTag, gNamesStandaloneTag, gNamesNarrowTag, status), status); - } - if ( status == U_MISSING_RESOURCE_ERROR ) { /* If format/narrow not available, use format/abbreviated */ - status = U_ZERO_ERROR; - initField(&fNarrowMonths, fNarrowMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesAbbrTag, status), status); - } - - initField(&fStandaloneMonths, fStandaloneMonthsCount, calData.getByKey3(gMonthNamesTag, gNamesStandaloneTag, gNamesWideTag, status), status); - if ( status == U_MISSING_RESOURCE_ERROR ) { /* If standalone/wide not available, use format/wide */ - status = U_ZERO_ERROR; - initField(&fStandaloneMonths, fStandaloneMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesWideTag, status), status); - } - initField(&fStandaloneShortMonths, fStandaloneShortMonthsCount, calData.getByKey3(gMonthNamesTag, gNamesStandaloneTag, gNamesAbbrTag, status), status); - if ( status == U_MISSING_RESOURCE_ERROR ) { /* If standalone/abbreviated not available, use format/abbreviated */ - status = U_ZERO_ERROR; - initField(&fStandaloneShortMonths, fStandaloneShortMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesAbbrTag, status), status); + // Load eras + initField(&fEras, fErasCount, calendarSink, buildResourcePath(path, gErasTag, gNamesAbbrTag, status), status); + UErrorCode oldStatus = status; + initField(&fEraNames, fEraNamesCount, calendarSink, buildResourcePath(path, gErasTag, gNamesWideTag, status), status); + if (status == U_MISSING_RESOURCE_ERROR) { // Workaround because eras/wide was omitted from CLDR 1.3 + status = oldStatus; + assignArray(fEraNames, fEraNamesCount, fEras, fErasCount); } - initField(&fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, calData.getByKey3(gMonthNamesTag, gNamesStandaloneTag, gNamesNarrowTag, status), status); - if ( status == U_MISSING_RESOURCE_ERROR ) { /* if standalone/narrow not availabe, try format/narrow */ - status = U_ZERO_ERROR; - initField(&fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesNarrowTag, status), status); - if ( status == U_MISSING_RESOURCE_ERROR ) { /* if still not there, use format/abbreviated */ - status = U_ZERO_ERROR; - initField(&fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesAbbrTag, status), status); - } + // current ICU4J falls back to abbreviated if narrow eras are missing, so we will too + oldStatus = status; + initField(&fNarrowEras, fNarrowErasCount, calendarSink, buildResourcePath(path, gErasTag, gNamesNarrowTag, status), status); + if (status == U_MISSING_RESOURCE_ERROR) { // Workaround because eras/wide was omitted from CLDR 1.3 + status = oldStatus; + assignArray(fNarrowEras, fNarrowErasCount, fEras, fErasCount); + } + + // Load month names + initField(&fMonths, fMonthsCount, calendarSink, + buildResourcePath(path, gMonthNamesTag, gNamesFormatTag, gNamesWideTag, status), status); + initField(&fShortMonths, fShortMonthsCount, calendarSink, + buildResourcePath(path, gMonthNamesTag, gNamesFormatTag, gNamesAbbrTag, status), status); + initField(&fStandaloneMonths, fStandaloneMonthsCount, calendarSink, + buildResourcePath(path, gMonthNamesTag, gNamesStandaloneTag, gNamesWideTag, status), status); + if (status == U_MISSING_RESOURCE_ERROR) { /* If standalone/wide not available, use format/wide */ + status = U_ZERO_ERROR; + assignArray(fStandaloneMonths, fStandaloneMonthsCount, fMonths, fMonthsCount); } - initField(&fAmPms, fAmPmsCount, calData.getByKey(gAmPmMarkersTag, status), status); - initField(&fNarrowAmPms, fNarrowAmPmsCount, calData.getByKey(gAmPmMarkersNarrowTag, status), status); - - initField(&fQuarters, fQuartersCount, calData.getByKey2(gQuartersTag, gNamesWideTag, status), status); - initField(&fShortQuarters, fShortQuartersCount, calData.getByKey2(gQuartersTag, gNamesAbbrTag, status), status); - - initField(&fStandaloneQuarters, fStandaloneQuartersCount, calData.getByKey3(gQuartersTag, gNamesStandaloneTag, gNamesWideTag, status), status); + initField(&fStandaloneShortMonths, fStandaloneShortMonthsCount, calendarSink, + buildResourcePath(path, gMonthNamesTag, gNamesStandaloneTag, gNamesAbbrTag, status), status); + if (status == U_MISSING_RESOURCE_ERROR) { /* If standalone/abbreviated not available, use format/abbreviated */ + status = U_ZERO_ERROR; + assignArray(fStandaloneShortMonths, fStandaloneShortMonthsCount, fShortMonths, fShortMonthsCount); + } + + UErrorCode narrowMonthsEC = status; + UErrorCode standaloneNarrowMonthsEC = status; + initField(&fNarrowMonths, fNarrowMonthsCount, calendarSink, + buildResourcePath(path, gMonthNamesTag, gNamesFormatTag, gNamesNarrowTag, narrowMonthsEC), narrowMonthsEC); + initField(&fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, calendarSink, + buildResourcePath(path, gMonthNamesTag, gNamesStandaloneTag, gNamesNarrowTag, narrowMonthsEC), standaloneNarrowMonthsEC); + if (narrowMonthsEC == U_MISSING_RESOURCE_ERROR && standaloneNarrowMonthsEC != U_MISSING_RESOURCE_ERROR) { + // If format/narrow not available, use standalone/narrow + assignArray(fNarrowMonths, fNarrowMonthsCount, fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount); + } else if (narrowMonthsEC != U_MISSING_RESOURCE_ERROR && standaloneNarrowMonthsEC == U_MISSING_RESOURCE_ERROR) { + // If standalone/narrow not availabe, use format/narrow + assignArray(fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, fNarrowMonths, fNarrowMonthsCount); + } else if (narrowMonthsEC == U_MISSING_RESOURCE_ERROR && standaloneNarrowMonthsEC == U_MISSING_RESOURCE_ERROR) { + // If neither is available, use format/abbreviated + assignArray(fNarrowMonths, fNarrowMonthsCount, fShortMonths, fShortMonthsCount); + assignArray(fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, fShortMonths, fShortMonthsCount); + } + + // Load AM/PM markers + initField(&fAmPms, fAmPmsCount, calendarSink, + buildResourcePath(path, gAmPmMarkersTag, status), status); + initField(&fNarrowAmPms, fNarrowAmPmsCount, calendarSink, + buildResourcePath(path, gAmPmMarkersNarrowTag, status), status); + + // Load quarters + initField(&fQuarters, fQuartersCount, calendarSink, + buildResourcePath(path, gQuartersTag, gNamesFormatTag, gNamesWideTag, status), status); + initField(&fShortQuarters, fShortQuartersCount, calendarSink, + buildResourcePath(path, gQuartersTag, gNamesFormatTag, gNamesAbbrTag, status), status); + + initField(&fStandaloneQuarters, fStandaloneQuartersCount, calendarSink, + buildResourcePath(path, gQuartersTag, gNamesStandaloneTag, gNamesWideTag, status), status); if(status == U_MISSING_RESOURCE_ERROR) { status = U_ZERO_ERROR; - initField(&fStandaloneQuarters, fStandaloneQuartersCount, calData.getByKey2(gQuartersTag, gNamesWideTag, status), status); + assignArray(fStandaloneQuarters, fStandaloneQuartersCount, fQuarters, fQuartersCount); } - - initField(&fStandaloneShortQuarters, fStandaloneShortQuartersCount, calData.getByKey3(gQuartersTag, gNamesStandaloneTag, gNamesAbbrTag, status), status); + initField(&fStandaloneShortQuarters, fStandaloneShortQuartersCount, calendarSink, + buildResourcePath(path, gQuartersTag, gNamesStandaloneTag, gNamesAbbrTag, status), status); if(status == U_MISSING_RESOURCE_ERROR) { status = U_ZERO_ERROR; - initField(&fStandaloneShortQuarters, fStandaloneShortQuartersCount, calData.getByKey2(gQuartersTag, gNamesAbbrTag, status), status); + assignArray(fStandaloneShortQuarters, fStandaloneShortQuartersCount, fShortQuarters, fShortQuartersCount); } // ICU 3.8 or later version no longer uses localized date-time pattern characters by default (ticket#5597) @@ -1912,177 +2377,108 @@ DateFormatSymbols::initializeData(const Locale& locale, const char *type, UError // Format wide weekdays -> fWeekdays // {sfb} fixed to handle 1-based weekdays - weekdaysData = calData.getByKey2(gDayNamesTag, gNamesWideTag, status); - fWeekdaysCount = ures_getSize(weekdaysData); - fWeekdays = new UnicodeString[fWeekdaysCount+1]; - /* pin the blame on system. If we cannot get a chunk of memory .. the system is dying!*/ - if (fWeekdays == NULL) { - status = U_MEMORY_ALLOCATION_ERROR; - goto cleanup; - } - // leave fWeekdays[0] empty - for(i = 0; i<fWeekdaysCount; i++) { - resStr = ures_getStringByIndex(weekdaysData, i, &len, &status); - // setTo() - see assignArray comments - fWeekdays[i+1].setTo(TRUE, resStr, len); - } - fWeekdaysCount++; + initField(&fWeekdays, fWeekdaysCount, calendarSink, + buildResourcePath(path, gDayNamesTag, gNamesFormatTag, gNamesWideTag, status), 1, status); // Format abbreviated weekdays -> fShortWeekdays - abbrWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesAbbrTag, status); - fShortWeekdaysCount = ures_getSize(abbrWeekdaysData); - fShortWeekdays = new UnicodeString[fShortWeekdaysCount+1]; - /* test for NULL */ - if (fShortWeekdays == 0) { - status = U_MEMORY_ALLOCATION_ERROR; - goto cleanup; - } - // leave fShortWeekdays[0] empty - for(i = 0; i<fShortWeekdaysCount; i++) { - resStr = ures_getStringByIndex(abbrWeekdaysData, i, &len, &status); - // setTo() - see assignArray comments - fShortWeekdays[i+1].setTo(TRUE, resStr, len); - } - fShortWeekdaysCount++; - - // Format short weekdays -> fShorterWeekdays (fall back to abbreviated) - shorterWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesShortTag, status); - if ( status == U_MISSING_RESOURCE_ERROR ) { - status = U_ZERO_ERROR; - shorterWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesAbbrTag, status); - } - fShorterWeekdaysCount = ures_getSize(shorterWeekdaysData); - fShorterWeekdays = new UnicodeString[fShorterWeekdaysCount+1]; - /* test for NULL */ - if (fShorterWeekdays == 0) { - status = U_MEMORY_ALLOCATION_ERROR; - goto cleanup; - } - // leave fShorterWeekdays[0] empty - for(i = 0; i<fShorterWeekdaysCount; i++) { - resStr = ures_getStringByIndex(shorterWeekdaysData, i, &len, &status); - // setTo() - see assignArray comments - fShorterWeekdays[i+1].setTo(TRUE, resStr, len); - } - fShorterWeekdaysCount++; + initField(&fShortWeekdays, fShortWeekdaysCount, calendarSink, + buildResourcePath(path, gDayNamesTag, gNamesFormatTag, gNamesAbbrTag, status), 1, status); - // Format narrow weekdays -> fNarrowWeekdays - narrowWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesNarrowTag, status); - if(status == U_MISSING_RESOURCE_ERROR) { + // Format short weekdays -> fShorterWeekdays (fall back to abbreviated) + initField(&fShorterWeekdays, fShorterWeekdaysCount, calendarSink, + buildResourcePath(path, gDayNamesTag, gNamesFormatTag, gNamesShortTag, status), 1, status); + if (status == U_MISSING_RESOURCE_ERROR) { status = U_ZERO_ERROR; - narrowWeekdaysData = calData.getByKey3(gDayNamesTag, gNamesStandaloneTag, gNamesNarrowTag, status); - } - if ( status == U_MISSING_RESOURCE_ERROR ) { - status = U_ZERO_ERROR; - narrowWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesAbbrTag, status); + assignArray(fShorterWeekdays, fShorterWeekdaysCount, fShortWeekdays, fShortWeekdaysCount); } - fNarrowWeekdaysCount = ures_getSize(narrowWeekdaysData); - fNarrowWeekdays = new UnicodeString[fNarrowWeekdaysCount+1]; - /* test for NULL */ - if (fNarrowWeekdays == 0) { - status = U_MEMORY_ALLOCATION_ERROR; - goto cleanup; - } - // leave fNarrowWeekdays[0] empty - for(i = 0; i<fNarrowWeekdaysCount; i++) { - resStr = ures_getStringByIndex(narrowWeekdaysData, i, &len, &status); - // setTo() - see assignArray comments - fNarrowWeekdays[i+1].setTo(TRUE, resStr, len); - } - fNarrowWeekdaysCount++; - - // Stand-alone wide weekdays -> fStandaloneWeekdays - standaloneWeekdaysData = calData.getByKey3(gDayNamesTag, gNamesStandaloneTag, gNamesWideTag, status); - if ( status == U_MISSING_RESOURCE_ERROR ) { - status = U_ZERO_ERROR; - standaloneWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesWideTag, status); - } - fStandaloneWeekdaysCount = ures_getSize(standaloneWeekdaysData); - fStandaloneWeekdays = new UnicodeString[fStandaloneWeekdaysCount+1]; - /* test for NULL */ - if (fStandaloneWeekdays == 0) { - status = U_MEMORY_ALLOCATION_ERROR; - goto cleanup; - } - // leave fStandaloneWeekdays[0] empty - for(i = 0; i<fStandaloneWeekdaysCount; i++) { - resStr = ures_getStringByIndex(standaloneWeekdaysData, i, &len, &status); - // setTo() - see assignArray comments - fStandaloneWeekdays[i+1].setTo(TRUE, resStr, len); - } - fStandaloneWeekdaysCount++; - - // Stand-alone abbreviated weekdays -> fStandaloneShortWeekdays - standaloneAbbrWeekdaysData = calData.getByKey3(gDayNamesTag, gNamesStandaloneTag, gNamesAbbrTag, status); - if ( status == U_MISSING_RESOURCE_ERROR ) { - status = U_ZERO_ERROR; - standaloneAbbrWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesAbbrTag, status); - } - fStandaloneShortWeekdaysCount = ures_getSize(standaloneAbbrWeekdaysData); - fStandaloneShortWeekdays = new UnicodeString[fStandaloneShortWeekdaysCount+1]; - /* test for NULL */ - if (fStandaloneShortWeekdays == 0) { - status = U_MEMORY_ALLOCATION_ERROR; - goto cleanup; + + // Stand-alone wide weekdays -> fStandaloneWeekdays + initField(&fStandaloneWeekdays, fStandaloneWeekdaysCount, calendarSink, + buildResourcePath(path, gDayNamesTag, gNamesStandaloneTag, gNamesWideTag, status), 1, status); + if (status == U_MISSING_RESOURCE_ERROR) { /* If standalone/wide is not available, use format/wide */ + status = U_ZERO_ERROR; + assignArray(fStandaloneWeekdays, fStandaloneWeekdaysCount, fWeekdays, fWeekdaysCount); } - // leave fStandaloneShortWeekdays[0] empty - for(i = 0; i<fStandaloneShortWeekdaysCount; i++) { - resStr = ures_getStringByIndex(standaloneAbbrWeekdaysData, i, &len, &status); - // setTo() - see assignArray comments - fStandaloneShortWeekdays[i+1].setTo(TRUE, resStr, len); + + // Stand-alone abbreviated weekdays -> fStandaloneShortWeekdays + initField(&fStandaloneShortWeekdays, fStandaloneShortWeekdaysCount, calendarSink, + buildResourcePath(path, gDayNamesTag, gNamesStandaloneTag, gNamesAbbrTag, status), 1, status); + if (status == U_MISSING_RESOURCE_ERROR) { /* If standalone/abbreviated is not available, use format/abbreviated */ + status = U_ZERO_ERROR; + assignArray(fStandaloneShortWeekdays, fStandaloneShortWeekdaysCount, fShortWeekdays, fShortWeekdaysCount); } - fStandaloneShortWeekdaysCount++; // Stand-alone short weekdays -> fStandaloneShorterWeekdays (fall back to format abbreviated) - standaloneShorterWeekdaysData = calData.getByKey3(gDayNamesTag, gNamesStandaloneTag, gNamesShortTag, status); - if ( status == U_MISSING_RESOURCE_ERROR ) { - status = U_ZERO_ERROR; - standaloneShorterWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesAbbrTag, status); - } - fStandaloneShorterWeekdaysCount = ures_getSize(standaloneShorterWeekdaysData); - fStandaloneShorterWeekdays = new UnicodeString[fStandaloneShorterWeekdaysCount+1]; - /* test for NULL */ - if (fStandaloneShorterWeekdays == 0) { - status = U_MEMORY_ALLOCATION_ERROR; - goto cleanup; - } - // leave fStandaloneShorterWeekdays[0] empty - for(i = 0; i<fStandaloneShorterWeekdaysCount; i++) { - resStr = ures_getStringByIndex(standaloneShorterWeekdaysData, i, &len, &status); - // setTo() - see assignArray comments - fStandaloneShorterWeekdays[i+1].setTo(TRUE, resStr, len); + initField(&fStandaloneShorterWeekdays, fStandaloneShorterWeekdaysCount, calendarSink, + buildResourcePath(path, gDayNamesTag, gNamesStandaloneTag, gNamesShortTag, status), 1, status); + if (status == U_MISSING_RESOURCE_ERROR) { /* If standalone/short is not available, use format/short */ + status = U_ZERO_ERROR; + assignArray(fStandaloneShorterWeekdays, fStandaloneShorterWeekdaysCount, fShorterWeekdays, fShorterWeekdaysCount); } - fStandaloneShorterWeekdaysCount++; + // Format narrow weekdays -> fNarrowWeekdays + UErrorCode narrowWeeksEC = status; + initField(&fNarrowWeekdays, fNarrowWeekdaysCount, calendarSink, + buildResourcePath(path, gDayNamesTag, gNamesFormatTag, gNamesNarrowTag, status), 1, narrowWeeksEC); // Stand-alone narrow weekdays -> fStandaloneNarrowWeekdays - standaloneNarrowWeekdaysData = calData.getByKey3(gDayNamesTag, gNamesStandaloneTag, gNamesNarrowTag, status); - if ( status == U_MISSING_RESOURCE_ERROR ) { - status = U_ZERO_ERROR; - standaloneNarrowWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesNarrowTag, status); - if ( status == U_MISSING_RESOURCE_ERROR ) { - status = U_ZERO_ERROR; - standaloneNarrowWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesAbbrTag, status); - } - } - fStandaloneNarrowWeekdaysCount = ures_getSize(standaloneNarrowWeekdaysData); - fStandaloneNarrowWeekdays = new UnicodeString[fStandaloneNarrowWeekdaysCount+1]; - /* test for NULL */ - if (fStandaloneNarrowWeekdays == 0) { - status = U_MEMORY_ALLOCATION_ERROR; - goto cleanup; - } - // leave fStandaloneNarrowWeekdays[0] empty - for(i = 0; i<fStandaloneNarrowWeekdaysCount; i++) { - resStr = ures_getStringByIndex(standaloneNarrowWeekdaysData, i, &len, &status); - // setTo() - see assignArray comments - fStandaloneNarrowWeekdays[i+1].setTo(TRUE, resStr, len); + UErrorCode standaloneNarrowWeeksEC = status; + initField(&fStandaloneNarrowWeekdays, fStandaloneNarrowWeekdaysCount, calendarSink, + buildResourcePath(path, gDayNamesTag, gNamesStandaloneTag, gNamesNarrowTag, status), 1, standaloneNarrowWeeksEC); + + if (narrowWeeksEC == U_MISSING_RESOURCE_ERROR && standaloneNarrowWeeksEC != U_MISSING_RESOURCE_ERROR) { + // If format/narrow not available, use standalone/narrow + assignArray(fNarrowWeekdays, fNarrowWeekdaysCount, fStandaloneNarrowWeekdays, fStandaloneNarrowWeekdaysCount); + } else if (narrowWeeksEC != U_MISSING_RESOURCE_ERROR && standaloneNarrowWeeksEC == U_MISSING_RESOURCE_ERROR) { + // If standalone/narrow not available, use format/narrow + assignArray(fStandaloneNarrowWeekdays, fStandaloneNarrowWeekdaysCount, fNarrowWeekdays, fNarrowWeekdaysCount); + } else if (narrowWeeksEC == U_MISSING_RESOURCE_ERROR && standaloneNarrowWeeksEC == U_MISSING_RESOURCE_ERROR ) { + // If neither is available, use format/abbreviated + assignArray(fNarrowWeekdays, fNarrowWeekdaysCount, fShortWeekdays, fShortWeekdaysCount); + assignArray(fStandaloneNarrowWeekdays, fStandaloneNarrowWeekdaysCount, fShortWeekdays, fShortWeekdaysCount); + } + + // Last resort fallback in case previous data wasn't loaded + if (U_FAILURE(status)) + { + if (useLastResortData) + { + // Handle the case in which there is no resource data present. + // We don't have to generate usable patterns in this situation; + // we just need to produce something that will be semi-intelligible + // in most locales. + + status = U_USING_FALLBACK_WARNING; + //TODO(fabalbon): make sure we are storing las resort data for all fields in here. + initField(&fEras, fErasCount, (const UChar *)gLastResortEras, kEraNum, kEraLen, status); + initField(&fEraNames, fEraNamesCount, (const UChar *)gLastResortEras, kEraNum, kEraLen, status); + initField(&fNarrowEras, fNarrowErasCount, (const UChar *)gLastResortEras, kEraNum, kEraLen, status); + initField(&fMonths, fMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status); + initField(&fShortMonths, fShortMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status); + initField(&fNarrowMonths, fNarrowMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status); + initField(&fStandaloneMonths, fStandaloneMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status); + initField(&fStandaloneShortMonths, fStandaloneShortMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status); + initField(&fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status); + initField(&fWeekdays, fWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status); + initField(&fShortWeekdays, fShortWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status); + initField(&fShorterWeekdays, fShorterWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status); + initField(&fNarrowWeekdays, fNarrowWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status); + initField(&fStandaloneWeekdays, fStandaloneWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status); + initField(&fStandaloneShortWeekdays, fStandaloneShortWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status); + initField(&fStandaloneShorterWeekdays, fStandaloneShorterWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status); + initField(&fStandaloneNarrowWeekdays, fStandaloneNarrowWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status); + initField(&fAmPms, fAmPmsCount, (const UChar *)gLastResortAmPmMarkers, kAmPmNum, kAmPmLen, status); + initField(&fNarrowAmPms, fNarrowAmPmsCount, (const UChar *)gLastResortAmPmMarkers, kAmPmNum, kAmPmLen, status); + initField(&fQuarters, fQuartersCount, (const UChar *)gLastResortQuarters, kQuarterNum, kQuarterLen, status); + initField(&fShortQuarters, fShortQuartersCount, (const UChar *)gLastResortQuarters, kQuarterNum, kQuarterLen, status); + initField(&fStandaloneQuarters, fStandaloneQuartersCount, (const UChar *)gLastResortQuarters, kQuarterNum, kQuarterLen, status); + initField(&fStandaloneShortQuarters, fStandaloneShortQuartersCount, (const UChar *)gLastResortQuarters, kQuarterNum, kQuarterLen, status); + fLocalPatternChars.setTo(TRUE, gPatternChars, PATTERN_CHARS_LEN); + } } - fStandaloneNarrowWeekdaysCount++; -cleanup: - ures_close(eras); - ures_close(eraNames); - ures_close(narrowEras); + // Close resources + ures_close(cb); + ures_close(rb); } Locale diff --git a/deps/icu-small/source/i18n/dtitv_impl.h b/deps/icu-small/source/i18n/dtitv_impl.h index 302221d438..7e5d53921e 100644 --- a/deps/icu-small/source/i18n/dtitv_impl.h +++ b/deps/icu-small/source/i18n/dtitv_impl.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2007-2016, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/dtitvfmt.cpp b/deps/icu-small/source/i18n/dtitvfmt.cpp index c5d977d5f7..48068d3cc2 100644 --- a/deps/icu-small/source/i18n/dtitvfmt.cpp +++ b/deps/icu-small/source/i18n/dtitvfmt.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /******************************************************************************* * Copyright (C) 2008-2016, International Business Machines Corporation and * others. All Rights Reserved. @@ -24,8 +26,8 @@ #include "cmemory.h" #include "cstring.h" #include "dtitv_impl.h" -#include "gregoimp.h" #include "mutex.h" +#include "uresimp.h" #ifdef DTITVFMT_DEBUG #include <iostream> @@ -51,7 +53,9 @@ static const UChar gDateFormatSkeleton[][11] = { {LOW_Y, CAP_M, LOW_D, 0} }; -static const char gDateTimePatternsTag[]="DateTimePatterns"; +static const char gCalendarTag[] = "calendar"; +static const char gGregorianTag[] = "gregorian"; +static const char gDateTimePatternsTag[] = "DateTimePatterns"; // latestFirst: @@ -217,15 +221,9 @@ DateIntervalFormat::operator==(const Format& other) const { Mutex lock(&gFormatterMutex); if (fDateFormat != fmt->fDateFormat && (fDateFormat == NULL || fmt->fDateFormat == NULL)) {return FALSE;} if (fDateFormat && fmt->fDateFormat && (*fDateFormat != *fmt->fDateFormat)) {return FALSE;} - - // TODO: should operator == ignore the From and ToCalendar? They hold transient values during - // formatting of a DateInterval. - if (fFromCalendar != fmt->fFromCalendar && (fFromCalendar == NULL || fmt->fFromCalendar == NULL)) {return FALSE;} - if (fFromCalendar && fmt->fFromCalendar && !fFromCalendar->isEquivalentTo(*fmt->fFromCalendar)) {return FALSE;} - - if (fToCalendar != fmt->fToCalendar && (fToCalendar == NULL || fmt->fToCalendar == NULL)) {return FALSE;} - if (fToCalendar && fmt->fToCalendar && !fToCalendar->isEquivalentTo(*fmt->fToCalendar)) {return FALSE;} } + // note: fFromCalendar and fToCalendar hold no persistent state, and therefore do not participate in operator ==. + // fDateFormat has the master calendar for the DateIntervalFormat. if (fSkeleton != fmt->fSkeleton) {return FALSE;} if (fDatePattern != fmt->fDatePattern && (fDatePattern == NULL || fmt->fDatePattern == NULL)) {return FALSE;} if (fDatePattern && fmt->fDatePattern && (*fDatePattern != *fmt->fDatePattern)) {return FALSE;} @@ -657,27 +655,22 @@ DateIntervalFormat::initializePattern(UErrorCode& status) { // with the time interval. // The date/time pattern ( such as {0} {1} ) is saved in // calendar, that is why need to get the CalendarData here. - CalendarData* calData = new CalendarData(locale, NULL, status); - if ( U_FAILURE(status) ) { - delete calData; - return; - } - if ( calData == NULL ) { - status = U_MEMORY_ALLOCATION_ERROR; - return; - } + LocalUResourceBundlePointer dateTimePatternsRes(ures_open(NULL, locale.getBaseName(), &status)); + ures_getByKey(dateTimePatternsRes.getAlias(), gCalendarTag, + dateTimePatternsRes.getAlias(), &status); + ures_getByKeyWithFallback(dateTimePatternsRes.getAlias(), gGregorianTag, + dateTimePatternsRes.getAlias(), &status); + ures_getByKeyWithFallback(dateTimePatternsRes.getAlias(), gDateTimePatternsTag, + dateTimePatternsRes.getAlias(), &status); - const UResourceBundle* dateTimePatternsRes = calData->getByKey( - gDateTimePatternsTag, status); int32_t dateTimeFormatLength; const UChar* dateTimeFormat = ures_getStringByIndex( - dateTimePatternsRes, + dateTimePatternsRes.getAlias(), (int32_t)DateFormat::kDateTime, &dateTimeFormatLength, &status); if ( U_SUCCESS(status) && dateTimeFormatLength >= 3 ) { fDateTimeFormat = new UnicodeString(dateTimeFormat, dateTimeFormatLength); } - delete calData; } UBool found = setSeparateDateTimePtn(normalizedDateSkeleton, @@ -1274,11 +1267,11 @@ DateIntervalFormat::splitPatternInto2Part(const UnicodeString& intervalPattern) } count = 0; } - if (ch == '\'') { + if (ch == 0x0027 /*'*/) { // Consecutive single quotes are a single quote literal, // either outside of quotes or between quotes if ((i+1) < intervalPattern.length() && - intervalPattern.charAt(i+1) == '\'') { + intervalPattern.charAt(i+1) == 0x0027 /*'*/) { ++i; } else { inQuote = ! inQuote; @@ -1478,10 +1471,10 @@ DateIntervalFormat::adjustFieldWidth(const UnicodeString& inputSkeleton, } count = 0; } - if (ch == '\'') { + if (ch == 0x0027 /*'*/) { // Consecutive single quotes are a single quote literal, // either outside of quotes or between quotes - if ((i+1) < adjustedPtn.length() && adjustedPtn.charAt(i+1) == '\'') { + if ((i+1) < adjustedPtn.length() && adjustedPtn.charAt(i+1) == 0x0027 /* ' */) { ++i; } else { inQuote = ! inQuote; diff --git a/deps/icu-small/source/i18n/dtitvinf.cpp b/deps/icu-small/source/i18n/dtitvinf.cpp index 4553159e6c..07129db928 100644 --- a/deps/icu-small/source/i18n/dtitvinf.cpp +++ b/deps/icu-small/source/i18n/dtitvinf.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /******************************************************************************* * Copyright (C) 2008-2016, International Business Machines Corporation and * others. All Rights Reserved. @@ -222,131 +224,83 @@ static const UChar PATH_SUFFIX[] = {SOLIDUS, LOW_I, LOW_N, LOW_T, LOW_E, LOW_R, /** * Sink for enumerating all of the date interval skeletons. - * Contains inner sink structs, each one corresponding to a type of resource table. - * The outer struct finds the dateInterval table or an alias. */ -struct DateIntervalSink : public ResourceTableSink { +struct DateIntervalInfo::DateIntervalSink : public ResourceSink { - /** - * Sink to handle each skeleton table. - */ - struct SkeletonSink : public ResourceTableSink { - SkeletonSink(DateIntervalSink &sink) : outer(sink) {} - virtual ~SkeletonSink(); - - virtual ResourceTableSink *getOrCreateTableSink( - const char *key, int32_t, UErrorCode &errorCode) { - if (U_SUCCESS(errorCode)) { - outer.currentSkeleton = key; - return &outer.patternSink; - } - return NULL; - } - - DateIntervalSink &outer; - } skeletonSink; - - /** - * Sink to store the date interval pattern for each skeleton pattern character. - */ - struct PatternSink : public ResourceTableSink { - PatternSink(DateIntervalSink &sink) : outer(sink) {} - virtual ~PatternSink(); - - virtual void put(const char *key, const ResourceValue &value, UErrorCode &errorCode) { - if (U_FAILURE(errorCode)) { return; } - - // Process the key - UCalendarDateFields calendarField = validateAndProcessPatternLetter(key); - - // If the calendar field has a valid value - if (calendarField < UCAL_FIELD_COUNT) { - // Set the interval pattern - setIntervalPatternIfAbsent(calendarField, value, errorCode); - } else { - errorCode = U_INVALID_FORMAT_ERROR; - } - } - - UCalendarDateFields validateAndProcessPatternLetter(const char *patternLetter) { - // Check that patternLetter is just one letter - char c0; - if ((c0 = patternLetter[0]) != 0 && patternLetter[1] == 0) { - // Check that the pattern letter is accepted - if (c0 == 'y') { - return UCAL_YEAR; - } else if (c0 == 'M') { - return UCAL_MONTH; - } else if (c0 == 'd') { - return UCAL_DATE; - } else if (c0 == 'a') { - return UCAL_AM_PM; - } else if (c0 == 'h' || c0 == 'H') { - return UCAL_HOUR; - } else if (c0 == 'm') { - return UCAL_MINUTE; - }// TODO(ticket:12190): Why icu4c doesn't accept the calendar field "s" but icu4j does? - } - return UCAL_FIELD_COUNT; - } - - /** - * Stores the interval pattern for the current skeleton in the internal data structure - * if it's not present. - */ - void setIntervalPatternIfAbsent(UCalendarDateFields lrgDiffCalUnit, - const ResourceValue &value, UErrorCode &errorCode) { - // Check if the pattern has already been stored on the data structure - DateIntervalInfo::IntervalPatternIndex index = - outer.dateIntervalInfo.calendarFieldToIntervalIndex(lrgDiffCalUnit, errorCode); - if (U_FAILURE(errorCode)) { return; } - - UnicodeString skeleton(outer.currentSkeleton, -1, US_INV); - UnicodeString* patternsOfOneSkeleton = - (UnicodeString*)(outer.dateIntervalInfo.fIntervalPatterns->get(skeleton)); - - if (patternsOfOneSkeleton == NULL || patternsOfOneSkeleton[index].isEmpty()) { - UnicodeString pattern = value.getUnicodeString(errorCode); - outer.dateIntervalInfo.setIntervalPatternInternally(skeleton, lrgDiffCalUnit, - pattern, errorCode); - } - } - - DateIntervalSink &outer; - } patternSink; + // Output data + DateIntervalInfo &dateIntervalInfo; + // Next calendar type + UnicodeString nextCalendarType; DateIntervalSink(DateIntervalInfo &diInfo, const char *currentCalendarType) - : skeletonSink(*this), patternSink(*this), dateIntervalInfo(diInfo), - nextCalendarType(currentCalendarType, -1, US_INV), currentSkeleton(NULL) { } + : dateIntervalInfo(diInfo), nextCalendarType(currentCalendarType, -1, US_INV) { } virtual ~DateIntervalSink(); - virtual void put(const char *key, const ResourceValue &value, UErrorCode &errorCode) { - // Check if it's an alias of intervalFormats - if (U_FAILURE(errorCode) || value.getType() != URES_ALIAS - || uprv_strcmp(key, gIntervalDateTimePatternTag) != 0) { - return; - } + virtual void put(const char *key, ResourceValue &value, UBool /*noFallback*/, UErrorCode &errorCode) { + if (U_FAILURE(errorCode)) { return; } - // Get the calendar type for the alias path. - const UnicodeString &aliasPath = value.getAliasUnicodeString(errorCode); + // Iterate over all the calendar entries and only pick the 'intervalFormats' table. + ResourceTable dateIntervalData = value.getTable(errorCode); if (U_FAILURE(errorCode)) { return; } + for (int32_t i = 0; dateIntervalData.getKeyAndValue(i, key, value); i++) { + if (uprv_strcmp(key, gIntervalDateTimePatternTag) != 0) { + continue; + } - nextCalendarType.remove(); - getCalendarTypeFromPath(aliasPath, nextCalendarType, errorCode); + // Handle aliases and tables. Ignore the rest. + if (value.getType() == URES_ALIAS) { + // Get the calendar type for the alias path. + const UnicodeString &aliasPath = value.getAliasUnicodeString(errorCode); + if (U_FAILURE(errorCode)) { return; } - if (U_FAILURE(errorCode)) { - resetNextCalendarType(); + nextCalendarType.remove(); + getCalendarTypeFromPath(aliasPath, nextCalendarType, errorCode); + + if (U_FAILURE(errorCode)) { + resetNextCalendarType(); + } + break; + + } else if (value.getType() == URES_TABLE) { + // Iterate over all the skeletons in the 'intervalFormat' table. + ResourceTable skeletonData = value.getTable(errorCode); + if (U_FAILURE(errorCode)) { return; } + for (int32_t j = 0; skeletonData.getKeyAndValue(j, key, value); j++) { + if (value.getType() == URES_TABLE) { + // Process the skeleton + processSkeletonTable(key, value, errorCode); + if (U_FAILURE(errorCode)) { return; } + } + } + break; + } } } - virtual ResourceTableSink *getOrCreateTableSink( - const char *key, int32_t, UErrorCode &errorCode) { - // Check if it's the intervalFormat table - if (U_SUCCESS(errorCode) && uprv_strcmp(key, gIntervalDateTimePatternTag) == 0) { - return &skeletonSink; + /** + * Processes the patterns for a skeleton table + */ + void processSkeletonTable(const char *key, ResourceValue &value, UErrorCode &errorCode) { + if (U_FAILURE(errorCode)) { return; } + + // Iterate over all the patterns in the current skeleton table + const char *currentSkeleton = key; + ResourceTable patternData = value.getTable(errorCode); + if (U_FAILURE(errorCode)) { return; } + for (int32_t k = 0; patternData.getKeyAndValue(k, key, value); k++) { + if (value.getType() == URES_STRING) { + // Process the key + UCalendarDateFields calendarField = validateAndProcessPatternLetter(key); + + // If the calendar field has a valid value + if (calendarField < UCAL_FIELD_COUNT) { + // Set the interval pattern + setIntervalPatternIfAbsent(currentSkeleton, calendarField, value, errorCode); + if (U_FAILURE(errorCode)) { return; } + } + } } - return NULL; } /** @@ -364,6 +318,53 @@ struct DateIntervalSink : public ResourceTableSink { path.extractBetween(PATH_PREFIX_LENGTH, path.length() - PATH_SUFFIX_LENGTH, calendarType); } + /** + * Validates and processes the pattern letter + */ + UCalendarDateFields validateAndProcessPatternLetter(const char *patternLetter) { + // Check that patternLetter is just one letter + char c0; + if ((c0 = patternLetter[0]) != 0 && patternLetter[1] == 0) { + // Check that the pattern letter is accepted + if (c0 == 'y') { + return UCAL_YEAR; + } else if (c0 == 'M') { + return UCAL_MONTH; + } else if (c0 == 'd') { + return UCAL_DATE; + } else if (c0 == 'a') { + return UCAL_AM_PM; + } else if (c0 == 'h' || c0 == 'H') { + return UCAL_HOUR; + } else if (c0 == 'm') { + return UCAL_MINUTE; + }// TODO(ticket:12190): Why icu4c doesn't accept the calendar field "s" but icu4j does? + } + return UCAL_FIELD_COUNT; + } + + /** + * Stores the interval pattern for the current skeleton in the internal data structure + * if it's not present. + */ + void setIntervalPatternIfAbsent(const char *currentSkeleton, UCalendarDateFields lrgDiffCalUnit, + const ResourceValue &value, UErrorCode &errorCode) { + // Check if the pattern has already been stored on the data structure + IntervalPatternIndex index = + dateIntervalInfo.calendarFieldToIntervalIndex(lrgDiffCalUnit, errorCode); + if (U_FAILURE(errorCode)) { return; } + + UnicodeString skeleton(currentSkeleton, -1, US_INV); + UnicodeString* patternsOfOneSkeleton = + (UnicodeString*)(dateIntervalInfo.fIntervalPatterns->get(skeleton)); + + if (patternsOfOneSkeleton == NULL || patternsOfOneSkeleton[index].isEmpty()) { + UnicodeString pattern = value.getUnicodeString(errorCode); + dateIntervalInfo.setIntervalPatternInternally(skeleton, lrgDiffCalUnit, + pattern, errorCode); + } + } + const UnicodeString &getNextCalendarType() { return nextCalendarType; } @@ -371,22 +372,10 @@ struct DateIntervalSink : public ResourceTableSink { void resetNextCalendarType() { nextCalendarType.setToBogus(); } - - - // Output data - DateIntervalInfo &dateIntervalInfo; - - // Next calendar type - UnicodeString nextCalendarType; - - // Current skeleton table being enumerated - const char *currentSkeleton; }; // Virtual destructors must be defined out of line. -DateIntervalSink::SkeletonSink::~SkeletonSink() {} -DateIntervalSink::PatternSink::~PatternSink() {} -DateIntervalSink::~DateIntervalSink() {} +DateIntervalInfo::DateIntervalSink::~DateIntervalSink() {} @@ -472,7 +461,7 @@ DateIntervalInfo::initializeData(const Locale& locale, UErrorCode& status) sink.resetNextCalendarType(); // Get all resources for this calendar type - ures_getAllTableItemsWithFallback(calBundle, calType, sink, status); + ures_getAllItemsWithFallback(calBundle, calType, sink, status); } } } diff --git a/deps/icu-small/source/i18n/dtptngen.cpp b/deps/icu-small/source/i18n/dtptngen.cpp index 2a6b35b511..17e7ec7cde 100644 --- a/deps/icu-small/source/i18n/dtptngen.cpp +++ b/deps/icu-small/source/i18n/dtptngen.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2007-2016, International Business Machines Corporation and @@ -31,13 +33,13 @@ #include "cmemory.h" #include "cstring.h" #include "locbased.h" -#include "gregoimp.h" #include "hash.h" #include "uhash.h" #include "uresimp.h" #include "dtptngen_impl.h" #include "ucln_in.h" #include "charstr.h" +#include "uassert.h" #if U_CHARSET_FAMILY==U_EBCDIC_FAMILY /** @@ -221,10 +223,6 @@ static const char* const CLDR_FIELD_NAME[] = { "hour", "minute", "second", "*", "zone" }; -static const char* const Resource_Fields[] = { - "day", "dayperiod", "era", "hour", "minute", "month", "second", "week", - "weekday", "year", "zone", "quarter" }; - // For appendItems static const UChar UDATPG_ItemFormat[]= {0x7B, 0x30, 0x7D, 0x20, 0x251C, 0x7B, 0x32, 0x7D, 0x3A, 0x20, 0x7B, 0x31, 0x7D, 0x2524, 0}; // {0} \u251C{2}: {1}\u2524 @@ -392,12 +390,12 @@ UInitOnce initOnce = U_INITONCE_INITIALIZER; UHashtable *localeToAllowedHourFormatsMap = NULL; // Value deleter for hashmap. -void deleteAllowedHourFormats(void *ptr) { +U_CFUNC void U_CALLCONV deleteAllowedHourFormats(void *ptr) { uprv_free(ptr); } // Close hashmap at cleanup. -UBool allowedHourFormatsCleanup() { +U_CFUNC UBool U_CALLCONV allowedHourFormatsCleanup() { uhash_close(localeToAllowedHourFormatsMap); return TRUE; } @@ -420,11 +418,8 @@ DateTimePatternGenerator::initData(const Locale& locale, UErrorCode &status) { skipMatcher = NULL; fAvailableFormatKeyHash=NULL; - addCanonicalItems(); + addCanonicalItems(status); addICUPatterns(locale, status); - if (U_FAILURE(status)) { - return; - } addCLDRData(locale, status); setDateTimeFromCalendar(locale, status); setDecimalSymbols(locale, status); @@ -434,80 +429,51 @@ DateTimePatternGenerator::initData(const Locale& locale, UErrorCode &status) { namespace { -struct AllowedHourFormatsSink : public ResourceTableSink { +struct AllowedHourFormatsSink : public ResourceSink { // Initialize sub-sinks. - AllowedHourFormatsSink() : localeSink(*this), allowedListSink(*this) {} + AllowedHourFormatsSink() {} virtual ~AllowedHourFormatsSink(); - // Entry point. - virtual ResourceTableSink *getOrCreateTableSink(const char *key, int32_t, UErrorCode &status) { - if (U_FAILURE(status)) { return NULL; } - - locale = key; - return &localeSink; - } - - struct LocaleSink : public ResourceTableSink { - AllowedHourFormatsSink &outer; - LocaleSink(AllowedHourFormatsSink &outer) : outer(outer) {} - virtual ~LocaleSink(); - - virtual void put(const char *key, const ResourceValue &value, UErrorCode &status) { - if (U_FAILURE(status)) { return; } - - if (uprv_strcmp(key, "allowed") == 0) { - outer.allowedFormats = static_cast<int32_t *>(uprv_malloc(2 * sizeof(int32_t))); - outer.allowedFormatsLength = 1; - if (outer.allowedFormats == NULL) { - status = U_MEMORY_ALLOCATION_ERROR; - return; - } - outer.allowedFormats[0] = outer.getHourFormatFromUnicodeString( - value.getUnicodeString(status)); - } - } - - virtual ResourceArraySink *getOrCreateArraySink(const char *key, int32_t size, UErrorCode &status) { - if (U_FAILURE(status)) { return NULL; } - - if (uprv_strcmp(key, "allowed") == 0) { - outer.allowedFormats = static_cast<int32_t *>(uprv_malloc((size + 1) * sizeof(int32_t))); - outer.allowedFormatsLength = size; - if (outer.allowedFormats == NULL) { - status = U_MEMORY_ALLOCATION_ERROR; - return NULL; - } else { - return &outer.allowedListSink; + virtual void put(const char *key, ResourceValue &value, UBool /*noFallback*/, + UErrorCode &errorCode) { + ResourceTable timeData = value.getTable(errorCode); + if (U_FAILURE(errorCode)) { return; } + for (int32_t i = 0; timeData.getKeyAndValue(i, key, value); ++i) { + const char *regionOrLocale = key; + ResourceTable formatList = value.getTable(errorCode); + if (U_FAILURE(errorCode)) { return; } + for (int32_t j = 0; formatList.getKeyAndValue(j, key, value); ++j) { + if (uprv_strcmp(key, "allowed") == 0) { // Ignore "preferred" list. + LocalMemory<int32_t> list; + int32_t length; + if (value.getType() == URES_STRING) { + if (list.allocateInsteadAndReset(2) == NULL) { + errorCode = U_MEMORY_ALLOCATION_ERROR; + return; + } + list[0] = getHourFormatFromUnicodeString(value.getUnicodeString(errorCode)); + length = 1; + } + else { + ResourceArray allowedFormats = value.getArray(errorCode); + length = allowedFormats.getSize(); + if (list.allocateInsteadAndReset(length + 1) == NULL) { + errorCode = U_MEMORY_ALLOCATION_ERROR; + return; + } + for (int32_t k = 0; k < length; ++k) { + allowedFormats.getValue(k, value); + list[k] = getHourFormatFromUnicodeString(value.getUnicodeString(errorCode)); + } + } + list[length] = ALLOWED_HOUR_FORMAT_UNKNOWN; + uhash_put(localeToAllowedHourFormatsMap, + const_cast<char *>(regionOrLocale), list.orphan(), &errorCode); + if (U_FAILURE(errorCode)) { return; } } } - return NULL; - } - - virtual void leave(UErrorCode &status) { - if (U_FAILURE(status) || outer.allowedFormats == NULL) { return; } - - outer.allowedFormats[outer.allowedFormatsLength] = ALLOWED_HOUR_FORMAT_UNKNOWN; - uhash_put(localeToAllowedHourFormatsMap, const_cast<char *>(outer.locale), outer.allowedFormats, &status); - outer.allowedFormats = NULL; } - } localeSink; - - struct AllowedListSink : public ResourceArraySink { - AllowedHourFormatsSink &outer; - AllowedListSink(AllowedHourFormatsSink &outer) : outer(outer) {} - virtual ~AllowedListSink(); - - virtual void put(int32_t index, const ResourceValue &value, UErrorCode &status) { - if (U_FAILURE(status)) { return; } - - outer.allowedFormats[index] = outer.getHourFormatFromUnicodeString( - value.getUnicodeString(status)); - } - } allowedListSink; - - const char *locale; - int32_t *allowedFormats; - int32_t allowedFormatsLength; + } AllowedHourFormat getHourFormatFromUnicodeString(UnicodeString s) { if (s.length() == 1) { @@ -527,10 +493,8 @@ struct AllowedHourFormatsSink : public ResourceTableSink { } // namespace AllowedHourFormatsSink::~AllowedHourFormatsSink() {} -AllowedHourFormatsSink::LocaleSink::~LocaleSink() {} -AllowedHourFormatsSink::AllowedListSink::~AllowedListSink() {} -void DateTimePatternGenerator::loadAllowedHourFormatsData(UErrorCode &status) { +U_CFUNC void U_CALLCONV DateTimePatternGenerator::loadAllowedHourFormatsData(UErrorCode &status) { if (U_FAILURE(status)) { return; } localeToAllowedHourFormatsMap = uhash_open( uhash_hashChars, uhash_compareChars, NULL, &status); @@ -544,14 +508,13 @@ void DateTimePatternGenerator::loadAllowedHourFormatsData(UErrorCode &status) { // into the hashmap, store 6 single-value sub-arrays right at the beginning of the // vector (at index enum*2) for easy data sharing, copy sub-arrays into runtime // object. Remember to clean up the vector, too. - ures_getAllTableItemsWithFallback(rb.getAlias(), "timeData", sink, status); + ures_getAllItemsWithFallback(rb.getAlias(), "timeData", sink, status); ucln_i18n_registerCleanup(UCLN_I18N_ALLOWED_HOUR_FORMATS, allowedHourFormatsCleanup); } void DateTimePatternGenerator::getAllowedHourFormats(const Locale &locale, UErrorCode &status) { if (U_FAILURE(status)) { return; } - const char *localeID = locale.getName(); char maxLocaleID[ULOC_FULLNAME_CAPACITY]; int32_t length = uloc_addLikelySubtags(localeID, maxLocaleID, ULOC_FULLNAME_CAPACITY, &status); @@ -632,41 +595,38 @@ DateTimePatternGenerator::staticGetBaseSkeleton( void DateTimePatternGenerator::addICUPatterns(const Locale& locale, UErrorCode& status) { + if (U_FAILURE(status)) { return; } UnicodeString dfPattern; UnicodeString conflictingString; DateFormat* df; - if (U_FAILURE(status)) { - return; - } - // Load with ICU patterns for (int32_t i=DateFormat::kFull; i<=DateFormat::kShort; i++) { DateFormat::EStyle style = (DateFormat::EStyle)i; df = DateFormat::createDateInstance(style, locale); SimpleDateFormat* sdf; if (df != NULL && (sdf = dynamic_cast<SimpleDateFormat*>(df)) != NULL) { - addPattern(sdf->toPattern(dfPattern), FALSE, conflictingString, status); + sdf->toPattern(dfPattern); + addPattern(dfPattern, FALSE, conflictingString, status); } // TODO Maybe we should return an error when the date format isn't simple. delete df; - if (U_FAILURE(status)) { - return; - } + if (U_FAILURE(status)) { return; } df = DateFormat::createTimeInstance(style, locale); if (df != NULL && (sdf = dynamic_cast<SimpleDateFormat*>(df)) != NULL) { - addPattern(sdf->toPattern(dfPattern), FALSE, conflictingString, status); - // HACK for hh:ss - if ( i==DateFormat::kMedium ) { - hackPattern = dfPattern; + sdf->toPattern(dfPattern); + addPattern(dfPattern, FALSE, conflictingString, status); + + // TODO: C++ and Java are inconsistent (see #12568). + // C++ uses MEDIUM, but Java uses SHORT. + if ( i==DateFormat::kShort && !dfPattern.isEmpty() ) { + consumeShortTimePattern(dfPattern, status); } } // TODO Maybe we should return an error when the date format isn't simple. delete df; - if (U_FAILURE(status)) { - return; - } + if (U_FAILURE(status)) { return; } } } @@ -721,221 +681,223 @@ DateTimePatternGenerator::hackTimes(const UnicodeString& hackPattern, UErrorCode static const UChar hourFormatChars[] = { CAP_H, LOW_H, CAP_K, LOW_K, 0 }; // HhKk, the hour format characters void -DateTimePatternGenerator::addCLDRData(const Locale& locale, UErrorCode& err) { - UResourceBundle *rb, *calTypeBundle, *calBundle; - UResourceBundle *patBundle, *fieldBundle, *fBundle; - UnicodeString rbPattern, value, field; - UnicodeString conflictingPattern; - const char *key=NULL; - int32_t i; - - UnicodeString defaultItemFormat(TRUE, UDATPG_ItemFormat, UPRV_LENGTHOF(UDATPG_ItemFormat)-1); // Read-only alias. - - err = U_ZERO_ERROR; - - fDefaultHourFormatChar = 0; - for (i=0; i<UDATPG_FIELD_COUNT; ++i ) { - appendItemNames[i]=CAP_F; - if (i<10) { - appendItemNames[i]+=(UChar)(i+0x30); - } - else { - appendItemNames[i]+=(UChar)0x31; - appendItemNames[i]+=(UChar)(i-10 + 0x30); - } - // NUL-terminate for the C API. - appendItemNames[i].getTerminatedBuffer(); - } - - rb = ures_open(NULL, locale.getName(), &err); - if (rb == NULL || U_FAILURE(err)) { - return; - } - const char *curLocaleName=ures_getLocaleByType(rb, ULOC_ACTUAL_LOCALE, &err); - const char * calendarTypeToUse = DT_DateTimeGregorianTag; // initial default - char calendarType[ULOC_KEYWORDS_CAPACITY]; // to be filled in with the type to use, if all goes well +DateTimePatternGenerator::getCalendarTypeToUse(const Locale& locale, CharString& destination, UErrorCode& err) { + destination.clear().append(DT_DateTimeGregorianTag, -1, err); // initial default if ( U_SUCCESS(err) ) { - char localeWithCalendarKey[ULOC_LOCALE_IDENTIFIER_CAPACITY]; + char localeWithCalendarKey[ULOC_LOCALE_IDENTIFIER_CAPACITY]; // obtain a locale that always has the calendar key value that should be used - (void)ures_getFunctionalEquivalent(localeWithCalendarKey, ULOC_LOCALE_IDENTIFIER_CAPACITY, NULL, - "calendar", "calendar", locale.getName(), NULL, FALSE, &err); + ures_getFunctionalEquivalent( + localeWithCalendarKey, + ULOC_LOCALE_IDENTIFIER_CAPACITY, + NULL, + "calendar", + "calendar", + locale.getName(), + NULL, + FALSE, + &err); localeWithCalendarKey[ULOC_LOCALE_IDENTIFIER_CAPACITY-1] = 0; // ensure null termination // now get the calendar key value from that locale - int32_t calendarTypeLen = uloc_getKeywordValue(localeWithCalendarKey, "calendar", calendarType, ULOC_KEYWORDS_CAPACITY, &err); + char calendarType[ULOC_KEYWORDS_CAPACITY]; + int32_t calendarTypeLen = uloc_getKeywordValue( + localeWithCalendarKey, + "calendar", + calendarType, + ULOC_KEYWORDS_CAPACITY, + &err); if (U_SUCCESS(err) && calendarTypeLen < ULOC_KEYWORDS_CAPACITY) { - calendarTypeToUse = calendarType; + destination.clear().append(calendarType, -1, err); + if (U_FAILURE(err)) { return; } } err = U_ZERO_ERROR; } - calBundle = ures_getByKeyWithFallback(rb, DT_DateTimeCalendarTag, NULL, &err); - calTypeBundle = ures_getByKeyWithFallback(calBundle, calendarTypeToUse, NULL, &err); +} - key=NULL; - int32_t dtCount=0; - patBundle = ures_getByKeyWithFallback(calTypeBundle, DT_DateTimePatternsTag, NULL, &err); - while (U_SUCCESS(err)) { - rbPattern = ures_getNextUnicodeString(patBundle, &key, &err); - dtCount++; - if (rbPattern.length()==0 ) { - break; // no more pattern - } - else { - if (dtCount==9) { - setDateTimeFormat(rbPattern); - } else if (dtCount==4) { // short time format - // set fDefaultHourFormatChar to the hour format character from this pattern - int32_t tfIdx, tfLen = rbPattern.length(); - UBool ignoreChars = FALSE; - for (tfIdx = 0; tfIdx < tfLen; tfIdx++) { - UChar tfChar = rbPattern.charAt(tfIdx); - if ( tfChar == SINGLE_QUOTE ) { - ignoreChars = !ignoreChars; // toggle (handle quoted literals & '' for single quote) - } else if ( !ignoreChars && u_strchr(hourFormatChars, tfChar) != NULL ) { - fDefaultHourFormatChar = tfChar; - break; - } - } - } +void +DateTimePatternGenerator::consumeShortTimePattern(const UnicodeString& shortTimePattern, + UErrorCode& status) { + + // set fDefaultHourFormatChar to the hour format character from this pattern + int32_t tfIdx, tfLen = shortTimePattern.length(); + UBool ignoreChars = FALSE; + for (tfIdx = 0; tfIdx < tfLen; tfIdx++) { + UChar tfChar = shortTimePattern.charAt(tfIdx); + if ( tfChar == SINGLE_QUOTE ) { + ignoreChars = !ignoreChars; // toggle (handle quoted literals & '' for single quote) + } else if ( !ignoreChars && u_strchr(hourFormatChars, tfChar) != NULL ) { + fDefaultHourFormatChar = tfChar; + break; } } - ures_close(patBundle); - err = U_ZERO_ERROR; - patBundle = ures_getByKeyWithFallback(calTypeBundle, DT_DateTimeAppendItemsTag, NULL, &err); - key=NULL; - UnicodeString itemKey; - while (U_SUCCESS(err)) { - rbPattern = ures_getNextUnicodeString(patBundle, &key, &err); - if (rbPattern.length()==0 ) { - break; // no more pattern - } - else { - setAppendItemFormat(getAppendFormatNumber(key), rbPattern); + // HACK for hh:ss + hackTimes(shortTimePattern, status); +} + +struct DateTimePatternGenerator::AppendItemFormatsSink : public ResourceSink { + + // Destination for data, modified via setters. + DateTimePatternGenerator& dtpg; + + AppendItemFormatsSink(DateTimePatternGenerator& _dtpg) : dtpg(_dtpg) {} + virtual ~AppendItemFormatsSink(); + + virtual void put(const char *key, ResourceValue &value, UBool /*noFallback*/, + UErrorCode &errorCode) { + ResourceTable itemsTable = value.getTable(errorCode); + if (U_FAILURE(errorCode)) { return; } + for (int32_t i = 0; itemsTable.getKeyAndValue(i, key, value); ++i) { + UDateTimePatternField field = dtpg.getAppendFormatNumber(key); + if (field == UDATPG_FIELD_COUNT) { continue; } + const UnicodeString& valueStr = value.getUnicodeString(errorCode); + if (dtpg.getAppendItemFormat(field).isEmpty() && !valueStr.isEmpty()) { + dtpg.setAppendItemFormat(field, valueStr); + } } } - ures_close(patBundle); - key=NULL; - err = U_ZERO_ERROR; - fBundle = ures_getByKeyWithFallback(rb, DT_DateTimeFieldsTag, NULL, &err); - for (i=0; i<MAX_RESOURCE_FIELD; ++i) { - err = U_ZERO_ERROR; - patBundle = ures_getByKeyWithFallback(fBundle, Resource_Fields[i], NULL, &err); - fieldBundle = ures_getByKeyWithFallback(patBundle, "dn", NULL, &err); - rbPattern = ures_getNextUnicodeString(fieldBundle, &key, &err); - ures_close(fieldBundle); - ures_close(patBundle); - if (rbPattern.length()==0 ) { - continue; - } - else { - setAppendItemName(getAppendNameNumber(Resource_Fields[i]), rbPattern); + void fillInMissing() { + UnicodeString defaultItemFormat(TRUE, UDATPG_ItemFormat, UPRV_LENGTHOF(UDATPG_ItemFormat)-1); // Read-only alias. + for (int32_t i = 0; i < UDATPG_FIELD_COUNT; i++) { + UDateTimePatternField field = (UDateTimePatternField)i; + if (dtpg.getAppendItemFormat(field).isEmpty()) { + dtpg.setAppendItemFormat(field, defaultItemFormat); + } } } - ures_close(fBundle); +}; - // add available formats - UBool firstTimeThrough = TRUE; - err = U_ZERO_ERROR; - initHashtable(err); - UBool override = TRUE; - while (TRUE) { - // At the start of the loop: - // - rb is the open resource bundle for the current locale being processed, - // whose actual name is in curLocaleName. - // - if U_SUCCESS(err), then calBundle and calTypeBundle are open; - // process contents of calTypeBundle, then close calBundle and calTypeBundle. - if (U_SUCCESS(err)) { - // process contents of calTypeBundle - patBundle = ures_getByKeyWithFallback(calTypeBundle, DT_DateTimeAvailableFormatsTag, NULL, &err); - if (U_SUCCESS(err)) { - int32_t numberKeys = ures_getSize(patBundle); - int32_t len; - const UChar *retPattern; - key=NULL; -#if defined(U_USE_ASCII_BUNDLE_ITERATOR) - UResourceBundleAIterator aiter; - ures_a_open(&aiter, patBundle, &err); -#endif - for(i=0; i<numberKeys; ++i) { -#if defined(U_USE_ASCII_BUNDLE_ITERATOR) - retPattern=ures_a_getNextString(&aiter, &len, &key, &err); -#else - retPattern=ures_getNextString(patBundle, &len, &key, &err); -#endif - UnicodeString format=UnicodeString(retPattern); - UnicodeString retKey=UnicodeString(key, -1, US_INV); - if ( firstTimeThrough || !isAvailableFormatSet(retKey) ) { - setAvailableFormat(retKey, err); - // Add pattern with its associated skeleton. Override any duplicate derived from std patterns, - // but not a previous availableFormats entry: - addPatternWithSkeleton(format, &retKey, override, conflictingPattern, err); - } +struct DateTimePatternGenerator::AppendItemNamesSink : public ResourceSink { + + // Destination for data, modified via setters. + DateTimePatternGenerator& dtpg; + + AppendItemNamesSink(DateTimePatternGenerator& _dtpg) : dtpg(_dtpg) {} + virtual ~AppendItemNamesSink(); + + virtual void put(const char *key, ResourceValue &value, UBool /*noFallback*/, + UErrorCode &errorCode) { + ResourceTable itemsTable = value.getTable(errorCode); + if (U_FAILURE(errorCode)) { return; } + for (int32_t i = 0; itemsTable.getKeyAndValue(i, key, value); ++i) { + UDateTimePatternField field = dtpg.getAppendNameNumber(key); + if (field == UDATPG_FIELD_COUNT) { continue; } + ResourceTable detailsTable = value.getTable(errorCode); + if (U_FAILURE(errorCode)) { return; } + for (int32_t j = 0; detailsTable.getKeyAndValue(j, key, value); ++j) { + if (uprv_strcmp(key, "dn") != 0) { continue; } + const UnicodeString& valueStr = value.getUnicodeString(errorCode); + if (dtpg.getAppendItemName(field).isEmpty() && !valueStr.isEmpty()) { + dtpg.setAppendItemName(field, valueStr); } -#if defined(U_USE_ASCII_BUNDLE_ITERATOR) - ures_a_close(&aiter); -#endif - ures_close(patBundle); + break; } - firstTimeThrough = FALSE; - // close calBundle and calTypeBundle - ures_close(calTypeBundle); - ures_close(calBundle); - } - if (uprv_strcmp(curLocaleName,"root")==0 || uprv_strlen(curLocaleName)==0) { - // we just finished handling root, nothing more to check - ures_close(rb); - break; } - // Find the name of the appropriate parent locale (from %%Parent if present, else - // uloc_getParent on the actual locale name) - // (It would be nice to have a ures function that did this...) - err = U_ZERO_ERROR; - char parentLocale[ULOC_FULLNAME_CAPACITY]; - int32_t locNameLen; - const UChar * parentUName = ures_getStringByKey(rb, "%%Parent", &locNameLen, &err); - if (U_SUCCESS(err) && err != U_USING_FALLBACK_WARNING && locNameLen < ULOC_FULLNAME_CAPACITY) { - u_UCharsToChars(parentUName, parentLocale, locNameLen + 1); - } else { - err = U_ZERO_ERROR; - uloc_getParent(curLocaleName, parentLocale, ULOC_FULLNAME_CAPACITY, &err); - if (U_FAILURE(err) || err == U_STRING_NOT_TERMINATED_WARNING) { - // just fallback to root, since we are not already there - parentLocale[0] = 0; - err = U_ZERO_ERROR; + } + + void fillInMissing() { + for (int32_t i = 0; i < UDATPG_FIELD_COUNT; i++) { + UDateTimePatternField field = (UDateTimePatternField)i; + UnicodeString& valueStr = dtpg.getMutableAppendItemName(field); + if (valueStr.isEmpty()) { + valueStr = CAP_F; + U_ASSERT(i < 20); + if (i < 10) { + // F0, F1, ..., F9 + valueStr += (UChar)(i+0x30); + } else { + // F10, F11, ... + valueStr += (UChar)0x31; + valueStr += (UChar)(i-10 + 0x30); + } + // NUL-terminate for the C API. + valueStr.getTerminatedBuffer(); } } - // Close current locale bundle - ures_close(rb); - // And open its parent, which becomes the new current locale being processed - rb = ures_open(NULL, parentLocale, &err); - if ( U_FAILURE(err) ) { - err = U_ZERO_ERROR; - break; - } - // Get the name of the parent / new current locale - curLocaleName=ures_getLocaleByType(rb, ULOC_ACTUAL_LOCALE, &err); - if ( U_FAILURE(err) ) { - curLocaleName = parentLocale; - err = U_ZERO_ERROR; - } - if (uprv_strcmp(curLocaleName,"root")==0 || uprv_strlen(curLocaleName)==0) { - override = FALSE; - } - // Open calBundle and calTypeBundle - calBundle = ures_getByKeyWithFallback(rb, DT_DateTimeCalendarTag, NULL, &err); - if (U_SUCCESS(err)) { - calTypeBundle = ures_getByKeyWithFallback(calBundle, calendarTypeToUse, NULL, &err); - if ( U_FAILURE(err) ) { - ures_close(calBundle); + } +}; + +struct DateTimePatternGenerator::AvailableFormatsSink : public ResourceSink { + + // Destination for data, modified via setters. + DateTimePatternGenerator& dtpg; + + // Temporary variable, required for calling addPatternWithSkeleton. + UnicodeString conflictingPattern; + + AvailableFormatsSink(DateTimePatternGenerator& _dtpg) : dtpg(_dtpg) {} + virtual ~AvailableFormatsSink(); + + virtual void put(const char *key, ResourceValue &value, UBool isRoot, + UErrorCode &errorCode) { + ResourceTable itemsTable = value.getTable(errorCode); + if (U_FAILURE(errorCode)) { return; } + for (int32_t i = 0; itemsTable.getKeyAndValue(i, key, value); ++i) { + const UnicodeString formatKey(key, -1, US_INV); + if (!dtpg.isAvailableFormatSet(formatKey) ) { + dtpg.setAvailableFormat(formatKey, errorCode); + // Add pattern with its associated skeleton. Override any duplicate + // derived from std patterns, but not a previous availableFormats entry: + const UnicodeString& formatValue = value.getUnicodeString(errorCode); + conflictingPattern.remove(); + dtpg.addPatternWithSkeleton(formatValue, &formatKey, !isRoot, conflictingPattern, errorCode); } } - // Go to the top of the loop to process contents of calTypeBundle } +}; - if (hackPattern.length()>0) { - hackTimes(hackPattern, err); - } +// Virtual destructors must be defined out of line. +DateTimePatternGenerator::AppendItemFormatsSink::~AppendItemFormatsSink() {} +DateTimePatternGenerator::AppendItemNamesSink::~AppendItemNamesSink() {} +DateTimePatternGenerator::AvailableFormatsSink::~AvailableFormatsSink() {} + +void +DateTimePatternGenerator::addCLDRData(const Locale& locale, UErrorCode& errorCode) { + if (U_FAILURE(errorCode)) { return; } + UnicodeString rbPattern, value, field; + CharString path; + + LocalUResourceBundlePointer rb(ures_open(NULL, locale.getName(), &errorCode)); + if (U_FAILURE(errorCode)) { return; } + + CharString calendarTypeToUse; // to be filled in with the type to use, if all goes well + getCalendarTypeToUse(locale, calendarTypeToUse, errorCode); + if (U_FAILURE(errorCode)) { return; } + + // Local err to ignore resource not found exceptions + UErrorCode err = U_ZERO_ERROR; + + // Load append item formats. + AppendItemFormatsSink appendItemFormatsSink(*this); + path.clear() + .append(DT_DateTimeCalendarTag, errorCode) + .append('/', errorCode) + .append(calendarTypeToUse, errorCode) + .append('/', errorCode) + .append(DT_DateTimeAppendItemsTag, errorCode); // i.e., calendar/xxx/appendItems + if (U_FAILURE(errorCode)) { return; } + ures_getAllItemsWithFallback(rb.getAlias(), path.data(), appendItemFormatsSink, err); + appendItemFormatsSink.fillInMissing(); + + // Load CLDR item names. + err = U_ZERO_ERROR; + AppendItemNamesSink appendItemNamesSink(*this); + ures_getAllItemsWithFallback(rb.getAlias(), DT_DateTimeFieldsTag, appendItemNamesSink, err); + appendItemNamesSink.fillInMissing(); + + // Load the available formats from CLDR. + err = U_ZERO_ERROR; + initHashtable(errorCode); + if (U_FAILURE(errorCode)) { return; } + AvailableFormatsSink availableFormatsSink(*this); + path.clear() + .append(DT_DateTimeCalendarTag, errorCode) + .append('/', errorCode) + .append(calendarTypeToUse, errorCode) + .append('/', errorCode) + .append(DT_DateTimeAvailableFormatsTag, errorCode); // i.e., calendar/xxx/availableFormats + if (U_FAILURE(errorCode)) { return; } + ures_getAllItemsWithFallback(rb.getAlias(), path.data(), availableFormatsSink, err); } void @@ -949,7 +911,6 @@ DateTimePatternGenerator::initHashtable(UErrorCode& err) { } } - void DateTimePatternGenerator::setAppendItemFormat(UDateTimePatternField field, const UnicodeString& value) { appendItemFormats[field] = value; @@ -970,7 +931,12 @@ DateTimePatternGenerator::setAppendItemName(UDateTimePatternField field, const U } const UnicodeString& -DateTimePatternGenerator:: getAppendItemName(UDateTimePatternField field) const { +DateTimePatternGenerator::getAppendItemName(UDateTimePatternField field) const { + return appendItemNames[field]; +} + +UnicodeString& +DateTimePatternGenerator::getMutableAppendItemName(UDateTimePatternField field) { return appendItemNames[field]; } @@ -1096,12 +1062,15 @@ DateTimePatternGenerator::getDecimal() const { } void -DateTimePatternGenerator::addCanonicalItems() { +DateTimePatternGenerator::addCanonicalItems(UErrorCode& status) { + if (U_FAILURE(status)) { return; } UnicodeString conflictingPattern; - UErrorCode status = U_ZERO_ERROR; for (int32_t i=0; i<UDATPG_FIELD_COUNT; i++) { - addPattern(UnicodeString(Canonical_Items[i]), FALSE, conflictingPattern, status); + if (Canonical_Items[i] > 0) { + addPattern(UnicodeString(Canonical_Items[i]), FALSE, conflictingPattern, status); + } + if (U_FAILURE(status)) { return; } } } @@ -1123,16 +1092,35 @@ DateTimePatternGenerator::setDateTimeFromCalendar(const Locale& locale, UErrorCo int32_t resStrLen = 0; Calendar* fCalendar = Calendar::createInstance(locale, status); - CalendarData calData(locale, fCalendar?fCalendar->getType():NULL, status); - UResourceBundle *dateTimePatterns = calData.getByKey(DT_DateTimePatternsTag, status); - if (U_FAILURE(status)) return; + if (U_FAILURE(status)) { return; } + + LocalUResourceBundlePointer calData(ures_open(NULL, locale.getBaseName(), &status)); + ures_getByKey(calData.getAlias(), DT_DateTimeCalendarTag, calData.getAlias(), &status); - if (ures_getSize(dateTimePatterns) <= DateFormat::kDateTime) + LocalUResourceBundlePointer dateTimePatterns; + if (fCalendar != NULL && fCalendar->getType() != NULL && *fCalendar->getType() != '\0' + && uprv_strcmp(fCalendar->getType(), DT_DateTimeGregorianTag) != 0) { + dateTimePatterns.adoptInstead(ures_getByKeyWithFallback(calData.getAlias(), fCalendar->getType(), + NULL, &status)); + ures_getByKeyWithFallback(dateTimePatterns.getAlias(), DT_DateTimePatternsTag, + dateTimePatterns.getAlias(), &status); + } + + if (dateTimePatterns.isNull() || status == U_MISSING_RESOURCE_ERROR) { + status = U_ZERO_ERROR; + dateTimePatterns.adoptInstead(ures_getByKeyWithFallback(calData.getAlias(), DT_DateTimeGregorianTag, + dateTimePatterns.orphan(), &status)); + ures_getByKeyWithFallback(dateTimePatterns.getAlias(), DT_DateTimePatternsTag, + dateTimePatterns.getAlias(), &status); + } + if (U_FAILURE(status)) { return; } + + if (ures_getSize(dateTimePatterns.getAlias()) <= DateFormat::kDateTime) { status = U_INVALID_FORMAT_ERROR; return; } - resStr = ures_getStringByIndex(dateTimePatterns, (int32_t)DateFormat::kDateTime, &resStrLen, &status); + resStr = ures_getStringByIndex(dateTimePatterns.getAlias(), (int32_t)DateFormat::kDateTime, &resStrLen, &status); setDateTimeFormat(UnicodeString(TRUE, resStr, resStrLen)); delete fCalendar; @@ -1324,8 +1312,8 @@ DateTimePatternGenerator::adjustFieldTypes(const UnicodeString& pattern, } if ((flags & kDTPGFixFractionalSeconds) != 0 && typeValue == UDATPG_SECOND_FIELD) { - UnicodeString newField=dtMatcher->skeleton.original[UDATPG_FRACTIONAL_SECOND_FIELD]; - field = field + decimal + newField; + field += decimal; + dtMatcher->skeleton.original.appendFieldTo(UDATPG_FRACTIONAL_SECOND_FIELD, field); } else if (dtMatcher->skeleton.type[typeValue]!=0) { // Here: // - "reqField" is the field from the originally requested skeleton, with length @@ -1349,9 +1337,9 @@ DateTimePatternGenerator::adjustFieldTypes(const UnicodeString& pattern, // a) The length of the field in the skeleton (skelFieldLen) is equal to reqFieldLen. // b) The pattern field is numeric and the skeleton field is not, or vice versa. - UnicodeString reqField = dtMatcher->skeleton.original[typeValue]; - int32_t reqFieldLen = reqField.length(); - if (reqField.charAt(0) == CAP_E && reqFieldLen < 3) + UChar reqFieldChar = dtMatcher->skeleton.original.getFieldChar(typeValue); + int32_t reqFieldLen = dtMatcher->skeleton.original.getFieldLength(typeValue); + if (reqFieldChar == CAP_E && reqFieldLen < 3) reqFieldLen = 3; // 1-3 for E are equivalent to 3 for c,e int32_t adjFieldLen = reqFieldLen; if ( (typeValue==UDATPG_HOUR_FIELD && (options & UDATPG_MATCH_HOUR_FIELD_LENGTH)==0) || @@ -1359,8 +1347,7 @@ DateTimePatternGenerator::adjustFieldTypes(const UnicodeString& pattern, (typeValue==UDATPG_SECOND_FIELD && (options & UDATPG_MATCH_SECOND_FIELD_LENGTH)==0) ) { adjFieldLen = field.length(); } else if (specifiedSkeleton) { - UnicodeString skelField = specifiedSkeleton->original[typeValue]; - int32_t skelFieldLen = skelField.length(); + int32_t skelFieldLen = specifiedSkeleton->original.getFieldLength(typeValue); UBool patFieldIsNumeric = (row->type > 0); UBool skelFieldIsNumeric = (specifiedSkeleton->type[typeValue] > 0); if (skelFieldLen == reqFieldLen || (patFieldIsNumeric && !skelFieldIsNumeric) || (skelFieldIsNumeric && !patFieldIsNumeric)) { @@ -1368,9 +1355,12 @@ DateTimePatternGenerator::adjustFieldTypes(const UnicodeString& pattern, adjFieldLen = field.length(); } } - UChar c = (typeValue!= UDATPG_HOUR_FIELD && typeValue!= UDATPG_MONTH_FIELD && - typeValue!= UDATPG_WEEKDAY_FIELD && (typeValue!= UDATPG_YEAR_FIELD || reqField.charAt(0)==CAP_Y))? - reqField.charAt(0): field.charAt(0); + UChar c = (typeValue!= UDATPG_HOUR_FIELD + && typeValue!= UDATPG_MONTH_FIELD + && typeValue!= UDATPG_WEEKDAY_FIELD + && (typeValue!= UDATPG_YEAR_FIELD || reqFieldChar==CAP_Y)) + ? reqFieldChar + : field.charAt(0); if (typeValue == UDATPG_HOUR_FIELD && (flags & kDTPGSkeletonUsesCapJ) != 0) { c = fDefaultHourFormatChar; } @@ -1733,36 +1723,19 @@ PatternMap::getPatternFromSkeleton(PtnSkeleton& skeleton, const PtnSkeleton** sp } // find boot entry - UChar baseChar='\0'; - for (int32_t i=0; i<UDATPG_FIELD_COUNT; ++i) { - if (skeleton.baseOriginal[i].length() !=0 ) { - baseChar = skeleton.baseOriginal[i].charAt(0); - break; - } - } - + UChar baseChar = skeleton.getFirstChar(); if ((curElem=getHeader(baseChar))==NULL) { return NULL; // no match } do { - int32_t i=0; + UBool equal; if (specifiedSkeletonPtr != NULL) { // called from DateTimePatternGenerator::getBestRaw or addPattern, use original - for (i=0; i<UDATPG_FIELD_COUNT; ++i) { - if (curElem->skeleton->original[i].compare(skeleton.original[i]) != 0 ) - { - break; - } - } + equal = curElem->skeleton->original == skeleton.original; } else { // called from DateTimePatternGenerator::getRedundants, use baseOriginal - for (i=0; i<UDATPG_FIELD_COUNT; ++i) { - if (curElem->skeleton->baseOriginal[i].compare(skeleton.baseOriginal[i]) != 0 ) - { - break; - } - } + equal = curElem->skeleton->baseOriginal == skeleton.baseOriginal; } - if (i == UDATPG_FIELD_COUNT) { + if (equal) { if (specifiedSkeletonPtr && curElem->skeletonWasSpecified) { *specifiedSkeletonPtr = curElem->skeleton; } @@ -1866,37 +1839,35 @@ void DateTimeMatcher::set(const UnicodeString& pattern, FormatParser* fp, PtnSkeleton& skeletonResult) { int32_t i; for (i=0; i<UDATPG_FIELD_COUNT; ++i) { - skeletonResult.type[i]=NONE; + skeletonResult.type[i] = NONE; } fp->set(pattern); for (i=0; i < fp->itemNumber; i++) { - UnicodeString field = fp->items[i]; - if ( field.charAt(0) == LOW_A ) { + const UnicodeString& value = fp->items[i]; + if ( value.charAt(0) == LOW_A ) { continue; // skip 'a' } - if ( fp->isQuoteLiteral(field) ) { + if ( fp->isQuoteLiteral(value) ) { UnicodeString quoteLiteral; fp->getQuoteLiteral(quoteLiteral, &i); continue; } - int32_t canonicalIndex = fp->getCanonicalIndex(field); + int32_t canonicalIndex = fp->getCanonicalIndex(value); if (canonicalIndex < 0 ) { continue; } const dtTypeElem *row = &dtTypes[canonicalIndex]; - int32_t typeValue = row->field; - skeletonResult.original[typeValue]=field; + int32_t field = row->field; + skeletonResult.original.populate(field, value); UChar repeatChar = row->patternChar; int32_t repeatCount = row->minLen; // #7930 removes cap at 3 - while (repeatCount-- > 0) { - skeletonResult.baseOriginal[typeValue] += repeatChar; - } - int16_t subTypeValue = row->type; + skeletonResult.baseOriginal.populate(field, repeatChar, repeatCount); + int16_t subField = row->type; if ( row->type > 0) { - subTypeValue += field.length(); + subField += value.length(); } - skeletonResult.type[typeValue] = subTypeValue; + skeletonResult.type[field] = subField; } copyFrom(skeletonResult); } @@ -1904,23 +1875,13 @@ DateTimeMatcher::set(const UnicodeString& pattern, FormatParser* fp, PtnSkeleton void DateTimeMatcher::getBasePattern(UnicodeString &result ) { result.remove(); // Reset the result first. - for (int32_t i=0; i<UDATPG_FIELD_COUNT; ++i ) { - if (skeleton.baseOriginal[i].length()!=0) { - result += skeleton.baseOriginal[i]; - } - } + skeleton.baseOriginal.appendTo(result); } UnicodeString DateTimeMatcher::getPattern() { UnicodeString result; - - for (int32_t i=0; i<UDATPG_FIELD_COUNT; ++i ) { - if (skeleton.original[i].length()!=0) { - result += skeleton.original[i]; - } - } - return result; + return skeleton.original.appendTo(result); } int32_t @@ -1953,34 +1914,19 @@ DateTimeMatcher::getDistance(const DateTimeMatcher& other, int32_t includeMask, void DateTimeMatcher::copyFrom(const PtnSkeleton& newSkeleton) { - for (int32_t i=0; i<UDATPG_FIELD_COUNT; ++i) { - this->skeleton.type[i]=newSkeleton.type[i]; - this->skeleton.original[i]=newSkeleton.original[i]; - this->skeleton.baseOriginal[i]=newSkeleton.baseOriginal[i]; - } + skeleton.copyFrom(newSkeleton); } void DateTimeMatcher::copyFrom() { // same as clear - for (int32_t i=0; i<UDATPG_FIELD_COUNT; ++i) { - this->skeleton.type[i]=0; - this->skeleton.original[i].remove(); - this->skeleton.baseOriginal[i].remove(); - } + skeleton.clear(); } UBool DateTimeMatcher::equals(const DateTimeMatcher* other) const { - if (other==NULL) { - return FALSE; - } - for (int32_t i=0; i<UDATPG_FIELD_COUNT; ++i) { - if (this->skeleton.original[i]!=other->skeleton.original[i] ) { - return FALSE; - } - } - return TRUE; + if (other==NULL) { return FALSE; } + return skeleton.original == other->skeleton.original; } int32_t @@ -2074,7 +2020,7 @@ FormatParser::getCanonicalIndex(const UnicodeString& s, UBool strict) { } int32_t i = 0; int32_t bestRow = -1; - while (dtTypes[i].patternChar != '\0') { + while (dtTypes[i].patternChar != 0x0000) { if ( dtTypes[i].patternChar != ch ) { ++i; continue; @@ -2246,52 +2192,116 @@ PatternMapIterator::next() { return *matcher; } -PtnSkeleton::PtnSkeleton() { + +SkeletonFields::SkeletonFields() { + // Set initial values to zero + clear(); } +void SkeletonFields::clear() { + uprv_memset(chars, 0, sizeof(chars)); + uprv_memset(lengths, 0, sizeof(lengths)); +} -PtnSkeleton::PtnSkeleton(const PtnSkeleton& other) { - for (int32_t i=0; i<UDATPG_FIELD_COUNT; ++i) { - this->type[i]=other.type[i]; - this->original[i]=other.original[i]; - this->baseOriginal[i]=other.baseOriginal[i]; +void SkeletonFields::copyFrom(const SkeletonFields& other) { + uprv_memcpy(chars, other.chars, sizeof(chars)); + uprv_memcpy(lengths, other.lengths, sizeof(lengths)); +} + +void SkeletonFields::clearField(int32_t field) { + chars[field] = 0; + lengths[field] = 0; +} + +UChar SkeletonFields::getFieldChar(int32_t field) const { + return chars[field]; +} + +int32_t SkeletonFields::getFieldLength(int32_t field) const { + return lengths[field]; +} + +void SkeletonFields::populate(int32_t field, const UnicodeString& value) { + populate(field, value.charAt(0), value.length()); +} + +void SkeletonFields::populate(int32_t field, UChar ch, int32_t length) { + chars[field] = (int8_t) ch; + lengths[field] = (int8_t) length; +} + +UBool SkeletonFields::isFieldEmpty(int32_t field) const { + return lengths[field] == 0; +} + +UnicodeString& SkeletonFields::appendTo(UnicodeString& string) const { + for (int32_t i = 0; i < UDATPG_FIELD_COUNT; ++i) { + appendFieldTo(i, string); } + return string; } -UBool -PtnSkeleton::equals(const PtnSkeleton& other) { - for (int32_t i=0; i<UDATPG_FIELD_COUNT; ++i) { - if ( (type[i]!= other.type[i]) || - (original[i]!=other.original[i]) || - (baseOriginal[i]!=other.baseOriginal[i]) ) { - return FALSE; +UnicodeString& SkeletonFields::appendFieldTo(int32_t field, UnicodeString& string) const { + UChar ch(chars[field]); + int32_t length = (int32_t) lengths[field]; + + for (int32_t i=0; i<length; i++) { + string += ch; + } + return string; +} + +UChar SkeletonFields::getFirstChar() const { + for (int32_t i = 0; i < UDATPG_FIELD_COUNT; ++i) { + if (lengths[i] != 0) { + return chars[i]; } } - return TRUE; + return '\0'; +} + + +PtnSkeleton::PtnSkeleton() { +} + +PtnSkeleton::PtnSkeleton(const PtnSkeleton& other) { + copyFrom(other); +} + +void PtnSkeleton::copyFrom(const PtnSkeleton& other) { + uprv_memcpy(type, other.type, sizeof(type)); + original.copyFrom(other.original); + baseOriginal.copyFrom(other.baseOriginal); +} + +void PtnSkeleton::clear() { + uprv_memset(type, 0, sizeof(type)); + original.clear(); + baseOriginal.clear(); +} + +UBool +PtnSkeleton::equals(const PtnSkeleton& other) const { + return (original == other.original) + && (baseOriginal == other.baseOriginal) + && (uprv_memcmp(type, other.type, sizeof(type)) == 0); } UnicodeString -PtnSkeleton::getSkeleton() { +PtnSkeleton::getSkeleton() const { UnicodeString result; - - for(int32_t i=0; i< UDATPG_FIELD_COUNT; ++i) { - if (original[i].length()!=0) { - result += original[i]; - } - } - return result; + return original.appendTo(result); } UnicodeString -PtnSkeleton::getBaseSkeleton() { +PtnSkeleton::getBaseSkeleton() const { UnicodeString result; + return baseOriginal.appendTo(result); +} - for(int32_t i=0; i< UDATPG_FIELD_COUNT; ++i) { - if (baseOriginal[i].length()!=0) { - result += baseOriginal[i]; - } - } - return result; +UChar +PtnSkeleton::getFirstChar() const { + return baseOriginal.getFirstChar(); } PtnSkeleton::~PtnSkeleton() { diff --git a/deps/icu-small/source/i18n/dtptngen_impl.h b/deps/icu-small/source/i18n/dtptngen_impl.h index 0cfa88ab4d..00a707585b 100644 --- a/deps/icu-small/source/i18n/dtptngen_impl.h +++ b/deps/icu-small/source/i18n/dtptngen_impl.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2007-2016, International Business Machines Corporation and @@ -112,17 +114,56 @@ typedef struct dtTypeElem { int16_t weight; }dtTypeElem; +// A compact storage mechanism for skeleton field strings. Several dozen of these will be created +// for a typical DateTimePatternGenerator instance. +class SkeletonFields : public UMemory { +public: + SkeletonFields(); + void clear(); + void copyFrom(const SkeletonFields& other); + void clearField(int32_t field); + UChar getFieldChar(int32_t field) const; + int32_t getFieldLength(int32_t field) const; + void populate(int32_t field, const UnicodeString& value); + void populate(int32_t field, UChar repeatChar, int32_t repeatCount); + UBool isFieldEmpty(int32_t field) const; + UnicodeString& appendTo(UnicodeString& string) const; + UnicodeString& appendFieldTo(int32_t field, UnicodeString& string) const; + UChar getFirstChar() const; + inline UBool operator==(const SkeletonFields& other) const; + inline UBool operator!=(const SkeletonFields& other) const; + +private: + int8_t chars[UDATPG_FIELD_COUNT]; + int8_t lengths[UDATPG_FIELD_COUNT]; +}; + +inline UBool SkeletonFields::operator==(const SkeletonFields& other) const { + return (uprv_memcmp(chars, other.chars, sizeof(chars)) == 0 + && uprv_memcmp(lengths, other.lengths, sizeof(lengths)) == 0); +} + +inline UBool SkeletonFields::operator!=(const SkeletonFields& other) const { + return (! operator==(other)); +} + class PtnSkeleton : public UMemory { public: int32_t type[UDATPG_FIELD_COUNT]; - UnicodeString original[UDATPG_FIELD_COUNT]; - UnicodeString baseOriginal[UDATPG_FIELD_COUNT]; + SkeletonFields original; + SkeletonFields baseOriginal; PtnSkeleton(); PtnSkeleton(const PtnSkeleton& other); - UBool equals(const PtnSkeleton& other); - UnicodeString getSkeleton(); - UnicodeString getBaseSkeleton(); + void copyFrom(const PtnSkeleton& other); + void clear(); + UBool equals(const PtnSkeleton& other) const; + UnicodeString getSkeleton() const; + UnicodeString getBaseSkeleton() const; + UChar getFirstChar() const; + + // TODO: Why is this virtual, as well as the other destructors in this file? We don't want + // vtables when we don't use class objects polymorphically. virtual ~PtnSkeleton(); }; @@ -183,7 +224,7 @@ class DateTimeMatcher: public UMemory { public: PtnSkeleton skeleton; - void getBasePattern(UnicodeString &basePattern); + void getBasePattern(UnicodeString& basePattern); UnicodeString getPattern(); void set(const UnicodeString& pattern, FormatParser* fp); void set(const UnicodeString& pattern, FormatParser* fp, PtnSkeleton& skeleton); diff --git a/deps/icu-small/source/i18n/dtrule.cpp b/deps/icu-small/source/i18n/dtrule.cpp index b8fd30ea97..41b61ae045 100644 --- a/deps/icu-small/source/i18n/dtrule.cpp +++ b/deps/icu-small/source/i18n/dtrule.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2007-2012, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/esctrn.cpp b/deps/icu-small/source/i18n/esctrn.cpp index 85c38cc2d8..9be926f138 100644 --- a/deps/icu-small/source/i18n/esctrn.cpp +++ b/deps/icu-small/source/i18n/esctrn.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2001-2011, International Business Machines diff --git a/deps/icu-small/source/i18n/esctrn.h b/deps/icu-small/source/i18n/esctrn.h index 96872b9168..7afea1b503 100644 --- a/deps/icu-small/source/i18n/esctrn.h +++ b/deps/icu-small/source/i18n/esctrn.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2001-2007, International Business Machines diff --git a/deps/icu-small/source/i18n/ethpccal.cpp b/deps/icu-small/source/i18n/ethpccal.cpp index 346d002bc2..e27f005583 100644 --- a/deps/icu-small/source/i18n/ethpccal.cpp +++ b/deps/icu-small/source/i18n/ethpccal.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2003 - 2013, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/ethpccal.h b/deps/icu-small/source/i18n/ethpccal.h index eb750fe16a..a9adac6f57 100644 --- a/deps/icu-small/source/i18n/ethpccal.h +++ b/deps/icu-small/source/i18n/ethpccal.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2003 - 2013, International Business Machines Corporation and * diff --git a/deps/icu-small/source/i18n/fmtable.cpp b/deps/icu-small/source/i18n/fmtable.cpp index ee0b617a84..feb4e28a07 100644 --- a/deps/icu-small/source/i18n/fmtable.cpp +++ b/deps/icu-small/source/i18n/fmtable.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 1997-2016, International Business Machines Corporation and @@ -155,7 +157,7 @@ Formattable::Formattable(int64_t value) // ------------------------------------- // Creates a formattable object with a decimal number value from a string. -Formattable::Formattable(const StringPiece &number, UErrorCode &status) { +Formattable::Formattable(StringPiece number, UErrorCode &status) { init(); setDecimalNumber(number, status); } @@ -796,7 +798,7 @@ Formattable::adoptDigitList(DigitList *dl) { // --------------------------------------- void -Formattable::setDecimalNumber(const StringPiece &numberString, UErrorCode &status) { +Formattable::setDecimalNumber(StringPiece numberString, UErrorCode &status) { if (U_FAILURE(status)) { return; } diff --git a/deps/icu-small/source/i18n/fmtable_cnv.cpp b/deps/icu-small/source/i18n/fmtable_cnv.cpp index 8e9645402e..ff4deae92d 100644 --- a/deps/icu-small/source/i18n/fmtable_cnv.cpp +++ b/deps/icu-small/source/i18n/fmtable_cnv.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 1997-2010, International Business Machines Corporation and * diff --git a/deps/icu-small/source/i18n/fmtableimp.h b/deps/icu-small/source/i18n/fmtableimp.h index c3f62a8502..8b3778ccc3 100644 --- a/deps/icu-small/source/i18n/fmtableimp.h +++ b/deps/icu-small/source/i18n/fmtableimp.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2010-2014, International Business Machines Corporation and * diff --git a/deps/icu-small/source/i18n/format.cpp b/deps/icu-small/source/i18n/format.cpp index e369e4021a..e951b3082e 100644 --- a/deps/icu-small/source/i18n/format.cpp +++ b/deps/icu-small/source/i18n/format.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 1997-2012, International Business Machines Corporation and * diff --git a/deps/icu-small/source/i18n/fphdlimp.cpp b/deps/icu-small/source/i18n/fphdlimp.cpp index a8fa6f46e6..6a004a6685 100644 --- a/deps/icu-small/source/i18n/fphdlimp.cpp +++ b/deps/icu-small/source/i18n/fphdlimp.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2009-2015, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/fphdlimp.h b/deps/icu-small/source/i18n/fphdlimp.h index 6071580b7f..b1fe42bb40 100644 --- a/deps/icu-small/source/i18n/fphdlimp.h +++ b/deps/icu-small/source/i18n/fphdlimp.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2009-2015, International Business Machines Corporation and * diff --git a/deps/icu-small/source/i18n/fpositer.cpp b/deps/icu-small/source/i18n/fpositer.cpp index f7d54deb8b..426226d69d 100644 --- a/deps/icu-small/source/i18n/fpositer.cpp +++ b/deps/icu-small/source/i18n/fpositer.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * Copyright (C) 2009-2012, International Business Machines Corporation and @@ -60,7 +62,10 @@ void FieldPositionIterator::setData(UVector32 *adopt, UErrorCode& status) { // Verify that adopt has valid data, and update status if it doesn't. if (U_SUCCESS(status)) { if (adopt) { - if ((adopt->size() % 3) != 0) { + if (adopt->size() == 0) { + delete adopt; + adopt = NULL; + } else if ((adopt->size() % 3) != 0) { status = U_ILLEGAL_ARGUMENT_ERROR; } else { for (int i = 1; i < adopt->size(); i += 3) { diff --git a/deps/icu-small/source/i18n/funcrepl.cpp b/deps/icu-small/source/i18n/funcrepl.cpp index 7ad5fc20bf..683e00a2c8 100644 --- a/deps/icu-small/source/i18n/funcrepl.cpp +++ b/deps/icu-small/source/i18n/funcrepl.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2002-2012, International Business Machines Corporation diff --git a/deps/icu-small/source/i18n/funcrepl.h b/deps/icu-small/source/i18n/funcrepl.h index ff00b55abf..954150cf00 100644 --- a/deps/icu-small/source/i18n/funcrepl.h +++ b/deps/icu-small/source/i18n/funcrepl.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2002-2011, International Business Machines Corporation diff --git a/deps/icu-small/source/i18n/gender.cpp b/deps/icu-small/source/i18n/gender.cpp index 0c2fca576f..4847ce9584 100644 --- a/deps/icu-small/source/i18n/gender.cpp +++ b/deps/icu-small/source/i18n/gender.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2008-2013, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/gregocal.cpp b/deps/icu-small/source/i18n/gregocal.cpp index b8bd8e293d..959228ab49 100644 --- a/deps/icu-small/source/i18n/gregocal.cpp +++ b/deps/icu-small/source/i18n/gregocal.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 1997-2016, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/gregoimp.cpp b/deps/icu-small/source/i18n/gregoimp.cpp index 6b3277107f..fa886f5a6f 100644 --- a/deps/icu-small/source/i18n/gregoimp.cpp +++ b/deps/icu-small/source/i18n/gregoimp.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2003-2008, International Business Machines @@ -18,10 +20,6 @@ #include "cstring.h" #include "uassert.h" -#if defined(U_DEBUG_CALDATA) -#include <stdio.h> -#endif - U_NAMESPACE_BEGIN int32_t ClockMath::floorDivide(int32_t numerator, int32_t denominator) { @@ -157,171 +155,6 @@ int32_t Grego::dayOfWeekInMonth(int32_t year, int32_t month, int32_t dom) { return weekInMonth; } -/* ---- CalendarData ------ */ - -#define U_CALENDAR_KEY "calendar" -#define U_GREGORIAN_KEY "gregorian" -#define U_FORMAT_KEY "format" -#define U_DEFAULT_KEY "default" -#define U_CALENDAR_DATA ((char*)0) - - -// CalendarData::CalendarData(const Locale& loc, UErrorCode& status) -// : fFillin(NULL), fBundle(NULL), fFallback(NULL) { -// initData(loc.getBaseName(), (char*) "???", status); -// } - -CalendarData::CalendarData(const Locale& loc, const char *type, UErrorCode& status) - : fFillin(NULL), fOtherFillin(NULL), fBundle(NULL), fFallback(NULL) { - initData(loc.getBaseName(), type, status); -} - -void CalendarData::initData(const char *locale, const char *type, UErrorCode& status) { - fOtherFillin = ures_open(U_CALENDAR_DATA, locale, &status); - fFillin = ures_getByKey(fOtherFillin, U_CALENDAR_KEY, fFillin, &status); - - if((type != NULL) && - (*type != '\0') && - (uprv_strcmp(type, U_GREGORIAN_KEY))) - { - fBundle = ures_getByKeyWithFallback(fFillin, type, NULL, &status); - fFallback = ures_getByKeyWithFallback(fFillin, U_GREGORIAN_KEY, NULL, &status); - -#if defined (U_DEBUG_CALDATA) - fprintf(stderr, "%p: CalendarData(%s, %s, %s) -> main(%p, %s)=%s, fallback(%p, %s)=%s\n", - this, locale, type, u_errorName(status), fBundle, type, fBundle?ures_getLocale(fBundle, &status):"", - fFallback, U_GREGORIAN_KEY, fFallback?ures_getLocale(fFallback, &status):""); -#endif - - } else { - fBundle = ures_getByKeyWithFallback(fFillin, U_GREGORIAN_KEY, NULL, &status); -#if defined (U_DEBUG_CALDATA) - fprintf(stderr, "%p: CalendarData(%s, %s, %s) -> main(%p, %s)=%s, fallback = NULL\n", - this, locale, type, u_errorName(status), fBundle, U_GREGORIAN_KEY, fBundle?ures_getLocale(fBundle, &status):"" ); -#endif - } -} - -CalendarData::~CalendarData() { - ures_close(fFillin); - ures_close(fBundle); - ures_close(fFallback); - ures_close(fOtherFillin); -} - -UResourceBundle* -CalendarData::getByKey(const char *key, UErrorCode& status) { - if(U_FAILURE(status)) { - return NULL; - } - - if(fBundle) { - fFillin = ures_getByKeyWithFallback(fBundle, key, fFillin, &status); -#if defined (U_DEBUG_CALDATA) - fprintf(stderr, "%p: get %s -> %s - from MAIN %s\n",this, key, u_errorName(status), ures_getLocale(fFillin, &status)); -#endif - } - if(fFallback && (status == U_MISSING_RESOURCE_ERROR)) { - status = U_ZERO_ERROR; // retry with fallback (gregorian) - fFillin = ures_getByKeyWithFallback(fFallback, key, fFillin, &status); -#if defined (U_DEBUG_CALDATA) - fprintf(stderr, "%p: get %s -> %s - from FALLBACK %s\n",this, key, u_errorName(status), ures_getLocale(fFillin, &status)); -#endif - } - return fFillin; -} - -UResourceBundle* CalendarData::getByKey2(const char *key, const char *subKey, UErrorCode& status) { - if(U_FAILURE(status)) { - return NULL; - } - - if(fBundle) { -#if defined (U_DEBUG_CALDATA) - fprintf(stderr, "%p: //\n"); -#endif - fFillin = ures_getByKeyWithFallback(fBundle, key, fFillin, &status); - fOtherFillin = ures_getByKeyWithFallback(fFillin, U_FORMAT_KEY, fOtherFillin, &status); - fFillin = ures_getByKeyWithFallback(fOtherFillin, subKey, fFillin, &status); -#if defined (U_DEBUG_CALDATA) - fprintf(stderr, "%p: get %s/format/%s -> %s - from MAIN %s\n", this, key, subKey, u_errorName(status), ures_getLocale(fFillin, &status)); -#endif - } - if(fFallback && (status == U_MISSING_RESOURCE_ERROR)) { - status = U_ZERO_ERROR; // retry with fallback (gregorian) - fFillin = ures_getByKeyWithFallback(fFallback, key, fFillin, &status); - fOtherFillin = ures_getByKeyWithFallback(fFillin, U_FORMAT_KEY, fOtherFillin, &status); - fFillin = ures_getByKeyWithFallback(fOtherFillin, subKey, fFillin, &status); -#if defined (U_DEBUG_CALDATA) - fprintf(stderr, "%p: get %s/format/%s -> %s - from FALLBACK %s\n",this, key, subKey, u_errorName(status), ures_getLocale(fFillin,&status)); -#endif - } - -//// handling of 'default' keyword on failure: Commented out for 3.0. -// if((status == U_MISSING_RESOURCE_ERROR) && -// uprv_strcmp(subKey,U_DEFAULT_KEY)) { // avoid recursion -// #if defined (U_DEBUG_CALDATA) -// fprintf(stderr, "%p: - attempting fallback -\n", this); -// fflush(stderr); -// #endif -// UErrorCode subStatus = U_ZERO_ERROR; -// int32_t len; -// char kwBuf[128] = ""; -// const UChar *kw; -// /* fFillin = */ getByKey2(key, U_DEFAULT_KEY, subStatus); -// kw = ures_getString(fFillin, &len, &subStatus); -// if(len>126) { // too big -// len = 0; -// } -// if(U_SUCCESS(subStatus) && (len>0)) { -// u_UCharsToChars(kw, kwBuf, len+1); -// if(*kwBuf && uprv_strcmp(kwBuf,subKey)) { -// #if defined (U_DEBUG_CALDATA) -// fprintf(stderr, "%p: trying %s/format/default -> \"%s\"\n",this, key, kwBuf); -// #endif -// // now try again with the default -// status = U_ZERO_ERROR; -// /* fFillin = */ getByKey2(key, kwBuf, status); -// } -// #if defined (U_DEBUG_CALDATA) -// } else { -// fprintf(stderr, "%p: could not load %s/format/default - fail out (%s)\n",this, key, kwBuf, u_errorName(status)); -// #endif -// } -// } - - return fFillin; -} - -UResourceBundle* CalendarData::getByKey3(const char *key, const char *contextKey, const char *subKey, UErrorCode& status) { - if(U_FAILURE(status)) { - return NULL; - } - - if(fBundle) { -#if defined (U_DEBUG_CALDATA) - fprintf(stderr, "%p: //\n"); -#endif - fFillin = ures_getByKeyWithFallback(fBundle, key, fFillin, &status); - fOtherFillin = ures_getByKeyWithFallback(fFillin, contextKey, fOtherFillin, &status); - fFillin = ures_getByKeyWithFallback(fOtherFillin, subKey, fFillin, &status); -#if defined (U_DEBUG_CALDATA) - fprintf(stderr, "%p: get %s/%s/%s -> %s - from MAIN %s\n", this, key, contextKey, subKey, u_errorName(status), ures_getLocale(fFillin, &status)); -#endif - } - if(fFallback && (status == U_MISSING_RESOURCE_ERROR)) { - status = U_ZERO_ERROR; // retry with fallback (gregorian) - fFillin = ures_getByKeyWithFallback(fFallback, key, fFillin, &status); - fOtherFillin = ures_getByKeyWithFallback(fFillin, contextKey, fOtherFillin, &status); - fFillin = ures_getByKeyWithFallback(fOtherFillin, subKey, fFillin, &status); -#if defined (U_DEBUG_CALDATA) - fprintf(stderr, "%p: get %s/%s/%s -> %s - from FALLBACK %s\n",this, key, contextKey, subKey, u_errorName(status), ures_getLocale(fFillin,&status)); -#endif - } - - return fFillin; -} - U_NAMESPACE_END #endif diff --git a/deps/icu-small/source/i18n/gregoimp.h b/deps/icu-small/source/i18n/gregoimp.h index b3048946c7..19e44c7a5a 100644 --- a/deps/icu-small/source/i18n/gregoimp.h +++ b/deps/icu-small/source/i18n/gregoimp.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2003-2008, International Business Machines @@ -291,71 +293,6 @@ inline int32_t Grego::gregorianShift(int32_t eyear) { return gregShift; } -/** - * This utility class provides convenient access to the data needed for a calendar. - * @internal ICU 3.0 - */ -class CalendarData : public UMemory { -public: - /** - * Construct a CalendarData from the given locale. - * @param loc locale to use. The 'calendar' keyword will be ignored. - * @param type calendar type. NULL indicates the gregorian calendar. - * No default lookup is done. - * @param status error code - */ - CalendarData(const Locale& loc, const char *type, UErrorCode& status); - - /** - * Load data for calendar. Note, this object owns the resources, do NOT call ures_close()! - * The ResourceBundle C++ API should NOT be used because it is too slow for a low level API. - * - * @param key Resource key to data - * @param status Error Status - * @internal - */ - UResourceBundle* getByKey(const char *key, UErrorCode& status); - - /** - * Load data for calendar. Note, this object owns the resources, do NOT call ures_close()! - * There is an implicit key of 'format' - * data is located in: "calendar/key/format/subKey" - * for example, calendar/dayNames/format/abbreviated - * The ResourceBundle C++ API should NOT be used because it is too slow for a low level API. - * - * @param key Resource key to data - * @param subKey Resource key to data - * @param status Error Status - * @internal - */ - UResourceBundle* getByKey2(const char *key, const char *subKey, UErrorCode& status); - - /** - * Load data for calendar. Note, this object owns the resources, do NOT call ures_close()! - * data is located in: "calendar/key/contextKey/subKey" - * for example, calendar/dayNames/standalone/narrow - * The ResourceBundle C++ API should NOT be used because it is too slow for a low level API. - * - * @param key Resource key to data - * @param contextKey Resource key to data - * @param subKey Resource key to data - * @param status Error Status - * @internal - */ - UResourceBundle* getByKey3(const char *key, const char *contextKey, const char *subKey, UErrorCode& status); - - ~CalendarData(); - -private: - void initData(const char *locale, const char *type, UErrorCode& status); - - UResourceBundle *fFillin; - UResourceBundle *fOtherFillin; - UResourceBundle *fBundle; - UResourceBundle *fFallback; - CalendarData(); // Not implemented. -}; - U_NAMESPACE_END #endif // !UCONFIG_NO_FORMATTING diff --git a/deps/icu-small/source/i18n/hebrwcal.cpp b/deps/icu-small/source/i18n/hebrwcal.cpp index 96673e5788..0b329a8715 100644 --- a/deps/icu-small/source/i18n/hebrwcal.cpp +++ b/deps/icu-small/source/i18n/hebrwcal.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * Copyright (C) 2003-2016, International Business Machines Corporation diff --git a/deps/icu-small/source/i18n/hebrwcal.h b/deps/icu-small/source/i18n/hebrwcal.h index 4cb2d3ebbf..0824fb7c78 100644 --- a/deps/icu-small/source/i18n/hebrwcal.h +++ b/deps/icu-small/source/i18n/hebrwcal.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * Copyright (C) 2003-2013, International Business Machines Corporation diff --git a/deps/icu-small/source/i18n/i18n.rc b/deps/icu-small/source/i18n/i18n.rc index cc516ee0a0..62fcbc738d 100644 --- a/deps/icu-small/source/i18n/i18n.rc +++ b/deps/icu-small/source/i18n/i18n.rc @@ -1,6 +1,8 @@ // Do not edit with Microsoft Developer Studio Resource Editor. // It will permanently substitute version numbers that are intended to be // picked up by the pre-processor during each build. +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html // Copyright (c) 2001-2010 International Business Machines // Corporation and others. All Rights Reserved. // diff --git a/deps/icu-small/source/i18n/identifier_info.cpp b/deps/icu-small/source/i18n/identifier_info.cpp deleted file mode 100644 index 05882830a5..0000000000 --- a/deps/icu-small/source/i18n/identifier_info.cpp +++ /dev/null @@ -1,310 +0,0 @@ -/* -********************************************************************** -* Copyright (C) 2012-2014, International Business Machines -* Corporation and others. All Rights Reserved. -********************************************************************** -*/ - -#include "unicode/utypes.h" - -#include "unicode/uchar.h" -#include "unicode/utf16.h" - -#include "identifier_info.h" -#include "mutex.h" -#include "scriptset.h" -#include "ucln_in.h" -#include "uvector.h" - -U_NAMESPACE_BEGIN - -static UnicodeSet *ASCII; -static ScriptSet *JAPANESE; -static ScriptSet *CHINESE; -static ScriptSet *KOREAN; -static ScriptSet *CONFUSABLE_WITH_LATIN; -static UInitOnce gIdentifierInfoInitOnce = U_INITONCE_INITIALIZER; - - -U_CDECL_BEGIN -static UBool U_CALLCONV -IdentifierInfo_cleanup(void) { - delete ASCII; - ASCII = NULL; - delete JAPANESE; - JAPANESE = NULL; - delete CHINESE; - CHINESE = NULL; - delete KOREAN; - KOREAN = NULL; - delete CONFUSABLE_WITH_LATIN; - CONFUSABLE_WITH_LATIN = NULL; - gIdentifierInfoInitOnce.reset(); - return TRUE; -} - -static void U_CALLCONV -IdentifierInfo_init(UErrorCode &status) { - ASCII = new UnicodeSet(0, 0x7f); - JAPANESE = new ScriptSet(); - CHINESE = new ScriptSet(); - KOREAN = new ScriptSet(); - CONFUSABLE_WITH_LATIN = new ScriptSet(); - if (ASCII == NULL || JAPANESE == NULL || CHINESE == NULL || KOREAN == NULL - || CONFUSABLE_WITH_LATIN == NULL) { - status = U_MEMORY_ALLOCATION_ERROR; - return; - } - ASCII->freeze(); - JAPANESE->set(USCRIPT_LATIN, status).set(USCRIPT_HAN, status).set(USCRIPT_HIRAGANA, status) - .set(USCRIPT_KATAKANA, status); - CHINESE->set(USCRIPT_LATIN, status).set(USCRIPT_HAN, status).set(USCRIPT_BOPOMOFO, status); - KOREAN->set(USCRIPT_LATIN, status).set(USCRIPT_HAN, status).set(USCRIPT_HANGUL, status); - CONFUSABLE_WITH_LATIN->set(USCRIPT_CYRILLIC, status).set(USCRIPT_GREEK, status) - .set(USCRIPT_CHEROKEE, status); - ucln_i18n_registerCleanup(UCLN_I18N_IDENTIFIER_INFO, IdentifierInfo_cleanup); -} -U_CDECL_END - - -IdentifierInfo::IdentifierInfo(UErrorCode &status): - fIdentifier(NULL), fRequiredScripts(NULL), fScriptSetSet(NULL), - fCommonAmongAlternates(NULL), fNumerics(NULL), fIdentifierProfile(NULL) { - umtx_initOnce(gIdentifierInfoInitOnce, &IdentifierInfo_init, status); - if (U_FAILURE(status)) { - return; - } - - fIdentifier = new UnicodeString(); - fRequiredScripts = new ScriptSet(); - fScriptSetSet = uhash_open(uhash_hashScriptSet, uhash_compareScriptSet, NULL, &status); - uhash_setKeyDeleter(fScriptSetSet, uhash_deleteScriptSet); - fCommonAmongAlternates = new ScriptSet(); - fNumerics = new UnicodeSet(); - fIdentifierProfile = new UnicodeSet(0, 0x10FFFF); - - if (U_SUCCESS(status) && (fIdentifier == NULL || fRequiredScripts == NULL || fScriptSetSet == NULL || - fCommonAmongAlternates == NULL || fNumerics == NULL || fIdentifierProfile == NULL)) { - status = U_MEMORY_ALLOCATION_ERROR; - } -} - -IdentifierInfo::~IdentifierInfo() { - delete fIdentifier; - delete fRequiredScripts; - uhash_close(fScriptSetSet); - delete fCommonAmongAlternates; - delete fNumerics; - delete fIdentifierProfile; -} - - -IdentifierInfo &IdentifierInfo::clear() { - fRequiredScripts->resetAll(); - uhash_removeAll(fScriptSetSet); - fNumerics->clear(); - fCommonAmongAlternates->resetAll(); - return *this; -} - - -IdentifierInfo &IdentifierInfo::setIdentifierProfile(const UnicodeSet &identifierProfile) { - *fIdentifierProfile = identifierProfile; - return *this; -} - - -const UnicodeSet &IdentifierInfo::getIdentifierProfile() const { - return *fIdentifierProfile; -} - - -IdentifierInfo &IdentifierInfo::setIdentifier(const UnicodeString &identifier, UErrorCode &status) { - if (U_FAILURE(status)) { - return *this; - } - *fIdentifier = identifier; - clear(); - ScriptSet scriptsForCP; - UChar32 cp; - for (int32_t i = 0; i < identifier.length(); i += U16_LENGTH(cp)) { - cp = identifier.char32At(i); - // Store a representative character for each kind of decimal digit - if (u_charType(cp) == U_DECIMAL_DIGIT_NUMBER) { - // Just store the zero character as a representative for comparison. Unicode guarantees it is cp - value - fNumerics->add(cp - (UChar32)u_getNumericValue(cp)); - } - UScriptCode extensions[500]; - int32_t extensionsCount = uscript_getScriptExtensions(cp, extensions, UPRV_LENGTHOF(extensions), &status); - if (U_FAILURE(status)) { - return *this; - } - scriptsForCP.resetAll(); - for (int32_t j=0; j<extensionsCount; j++) { - scriptsForCP.set(extensions[j], status); - } - scriptsForCP.reset(USCRIPT_COMMON, status); - scriptsForCP.reset(USCRIPT_INHERITED, status); - switch (scriptsForCP.countMembers()) { - case 0: break; - case 1: - // Single script, record it. - fRequiredScripts->Union(scriptsForCP); - break; - default: - if (!fRequiredScripts->intersects(scriptsForCP) - && !uhash_geti(fScriptSetSet, &scriptsForCP)) { - // If the set hasn't been added already, add it - // (Add a copy, fScriptSetSet takes ownership of the copy.) - uhash_puti(fScriptSetSet, new ScriptSet(scriptsForCP), 1, &status); - } - break; - } - } - // Now make a final pass through ScriptSetSet to remove alternates that came before singles. - // [Kana], [Kana Hira] => [Kana] - // This is relatively infrequent, so doesn't have to be optimized. - // We also compute any commonalities among the alternates. - if (uhash_count(fScriptSetSet) > 0) { - fCommonAmongAlternates->setAll(); - for (int32_t it = UHASH_FIRST;;) { - const UHashElement *nextHashEl = uhash_nextElement(fScriptSetSet, &it); - if (nextHashEl == NULL) { - break; - } - ScriptSet *next = static_cast<ScriptSet *>(nextHashEl->key.pointer); - // [Kana], [Kana Hira] => [Kana] - if (fRequiredScripts->intersects(*next)) { - uhash_removeElement(fScriptSetSet, nextHashEl); - } else { - fCommonAmongAlternates->intersect(*next); - // [[Arab Syrc Thaa]; [Arab Syrc]] => [[Arab Syrc]] - for (int32_t otherIt = UHASH_FIRST;;) { - const UHashElement *otherHashEl = uhash_nextElement(fScriptSetSet, &otherIt); - if (otherHashEl == NULL) { - break; - } - ScriptSet *other = static_cast<ScriptSet *>(otherHashEl->key.pointer); - if (next != other && next->contains(*other)) { - uhash_removeElement(fScriptSetSet, nextHashEl); - break; - } - } - } - } - } - if (uhash_count(fScriptSetSet) == 0) { - fCommonAmongAlternates->resetAll(); - } - return *this; -} - - -const UnicodeString *IdentifierInfo::getIdentifier() const { - return fIdentifier; -} - -const ScriptSet *IdentifierInfo::getScripts() const { - return fRequiredScripts; -} - -const UHashtable *IdentifierInfo::getAlternates() const { - return fScriptSetSet; -} - - -const UnicodeSet *IdentifierInfo::getNumerics() const { - return fNumerics; -} - -const ScriptSet *IdentifierInfo::getCommonAmongAlternates() const { - return fCommonAmongAlternates; -} - -#if !UCONFIG_NO_NORMALIZATION - -URestrictionLevel IdentifierInfo::getRestrictionLevel(UErrorCode &status) const { - if (!fIdentifierProfile->containsAll(*fIdentifier) || getNumerics()->size() > 1) { - return USPOOF_UNRESTRICTIVE; - } - if (ASCII->containsAll(*fIdentifier)) { - return USPOOF_ASCII; - } - // This is a bit tricky. We look at a number of factors. - // The number of scripts in the text. - // Plus 1 if there is some commonality among the alternates (eg [Arab Thaa]; [Arab Syrc]) - // Plus number of alternates otherwise (this only works because we only test cardinality up to 2.) - - // Note: the requiredScripts set omits COMMON and INHERITED; they are taken out at the - // time it is created, in setIdentifier(). - int32_t cardinalityPlus = fRequiredScripts->countMembers() + - (fCommonAmongAlternates->countMembers() == 0 ? uhash_count(fScriptSetSet) : 1); - if (cardinalityPlus < 2) { - return USPOOF_SINGLE_SCRIPT_RESTRICTIVE; - } - if (containsWithAlternates(*JAPANESE, *fRequiredScripts) || containsWithAlternates(*CHINESE, *fRequiredScripts) - || containsWithAlternates(*KOREAN, *fRequiredScripts)) { - return USPOOF_HIGHLY_RESTRICTIVE; - } - if (cardinalityPlus == 2 && - fRequiredScripts->test(USCRIPT_LATIN, status) && - !fRequiredScripts->intersects(*CONFUSABLE_WITH_LATIN)) { - return USPOOF_MODERATELY_RESTRICTIVE; - } - return USPOOF_MINIMALLY_RESTRICTIVE; -} - -#endif /* !UCONFIG_NO_NORMALIZATION */ - -int32_t IdentifierInfo::getScriptCount() const { - // Note: Common and Inherited scripts were removed by setIdentifier(), and do not appear in fRequiredScripts. - int32_t count = fRequiredScripts->countMembers() + - (fCommonAmongAlternates->countMembers() == 0 ? uhash_count(fScriptSetSet) : 1); - return count; -} - - - -UBool IdentifierInfo::containsWithAlternates(const ScriptSet &container, const ScriptSet &containee) const { - if (!container.contains(containee)) { - return FALSE; - } - for (int32_t iter = UHASH_FIRST; ;) { - const UHashElement *hashEl = uhash_nextElement(fScriptSetSet, &iter); - if (hashEl == NULL) { - break; - } - ScriptSet *alternatives = static_cast<ScriptSet *>(hashEl->key.pointer); - if (!container.intersects(*alternatives)) { - return false; - } - } - return true; -} - -UnicodeString &IdentifierInfo::displayAlternates(UnicodeString &dest, const UHashtable *alternates, UErrorCode &status) { - UVector sorted(status); - if (U_FAILURE(status)) { - return dest; - } - for (int32_t pos = UHASH_FIRST; ;) { - const UHashElement *el = uhash_nextElement(alternates, &pos); - if (el == NULL) { - break; - } - ScriptSet *ss = static_cast<ScriptSet *>(el->key.pointer); - sorted.addElement(ss, status); - } - sorted.sort(uhash_compareScriptSet, status); - UnicodeString separator = UNICODE_STRING_SIMPLE("; "); - for (int32_t i=0; i<sorted.size(); i++) { - if (i>0) { - dest.append(separator); - } - ScriptSet *ss = static_cast<ScriptSet *>(sorted.elementAt(i)); - ss->displayScripts(dest); - } - return dest; -} - -U_NAMESPACE_END diff --git a/deps/icu-small/source/i18n/identifier_info.h b/deps/icu-small/source/i18n/identifier_info.h deleted file mode 100644 index 1dee627e1c..0000000000 --- a/deps/icu-small/source/i18n/identifier_info.h +++ /dev/null @@ -1,189 +0,0 @@ -/* -********************************************************************** -* Copyright (C) 2014, International Business Machines -* Corporation and others. All Rights Reserved. -********************************************************************** -* -* indentifier_info.h -* -* created on: 2013 Jan 7 -* created by: Andy Heninger -*/ - -#ifndef __IDENTIFIER_INFO_H__ -#define __IDENTIFIER_INFO_H__ - -#include "unicode/utypes.h" - -#include "unicode/uniset.h" -#include "unicode/uspoof.h" -#include "uhash.h" - -U_NAMESPACE_BEGIN - -class ScriptSet; - -// TODO(andy): review consistency of reference vs pointer arguments to the funcions. - -/** - * This class analyzes a possible identifier for script and identifier status. Use it by calling setIdentifierProfile - * then setIdentifier. Available methods include: - * <ol> - * <li>call getScripts for the specific scripts in the identifier. The identifier contains at least one character in - * each of these. - * <li>call getAlternates to get cases where a character is not limited to a single script. For example, it could be - * either Katakana or Hiragana. - * <li>call getCommonAmongAlternates to find out if any scripts are common to all the alternates. - * <li>call getNumerics to get a representative character (with value zero) for each of the decimal number systems in - * the identifier. - * <li>call getRestrictionLevel to see what the UTS36 restriction level is. - * </ol> - * - * This is a port from ICU4J of class com.ibm.icu.text.IdentifierInfo - */ -class U_I18N_API IdentifierInfo : public UMemory { - - public: - /** - * Create an identifier info object. Subsequently, call setIdentifier(), etc. - * @internal - */ - IdentifierInfo(UErrorCode &status); - - /** - * Destructor - */ - virtual ~IdentifierInfo(); - - private: - /* Disallow copying for now. Can be added if there's a need. */ - IdentifierInfo(const IdentifierInfo &other); - - public: - - /** - * Set the identifier profile: the characters that are to be allowed in the identifier. - * - * @param identifierProfile the characters that are to be allowed in the identifier - * @return this - * @internal - */ - IdentifierInfo &setIdentifierProfile(const UnicodeSet &identifierProfile); - - /** - * Get the identifier profile: the characters that are to be allowed in the identifier. - * - * @return The characters that are to be allowed in the identifier. - * @internal - */ - const UnicodeSet &getIdentifierProfile() const; - - - /** - * Set an identifier to analyze. Afterwards, call methods like getScripts() - * - * @param identifier the identifier to analyze - * @param status Errorcode, set if errors occur. - * @return this - * @internal - */ - IdentifierInfo &setIdentifier(const UnicodeString &identifier, UErrorCode &status); - - - /** - * Get the identifier that was analyzed. The returned string is owned by the ICU library, - * and must not be deleted by the caller. - * - * @return the identifier that was analyzed. - * @internal - */ - const UnicodeString *getIdentifier() const; - - - /** - * Get the scripts found in the identifiers. - * - * @return the set of explicit scripts. - * @internal - */ - const ScriptSet *getScripts() const; - - /** - * Get the set of alternate scripts found in the identifiers. That is, when a character can be in two scripts, then - * the set consisting of those scripts will be returned. - * - * @return a uhash, with each key being of type (ScriptSet *). - * This is a set, not a map, so the value stored in the uhash is not relevant. - * (It is, in fact, 1). - * Ownership of the uhash and its contents remains with the IndetifierInfo object, - * and remains valid until a new identifer is set or until the object is deleted. - * @internal - */ - const UHashtable *getAlternates() const; - - /** - * Get the representative characters (zeros) for the numerics found in the identifier. - * - * @return the set of explicit scripts. - * @internal - */ - const UnicodeSet *getNumerics() const; - - /** - * Find out which scripts are in common among the alternates. - * - * @return the set of scripts that are in common among the alternates. - * @internal - */ - const ScriptSet *getCommonAmongAlternates() const; - - /** - * Get the number of scripts appearing in the identifier. - * Note: Common and Inherited scripts are omitted from the count. - * Note: Result may be high when the identifier contains characters - * with alternate scripts. The distinction between - * 0, 1 and > 1 will remain valid, however. - * @return the number of scripts. - */ - int32_t getScriptCount() const; - -#if !UCONFIG_NO_NORMALIZATION - - /** - * Find the "tightest" restriction level that the identifier satisfies. - * - * @return the restriction level. - * @internal - */ - URestrictionLevel getRestrictionLevel(UErrorCode &status) const; - -#endif /*!UCONFIG_NO_NORMALIZATION */ - - UnicodeString toString() const; - - /** - * Produce a readable string of alternates. - * - * @param alternates a UHashtable of UScriptSets. - * Keys only, no meaningful values in the UHash. - * @return display form - * @internal - */ - static UnicodeString &displayAlternates(UnicodeString &dest, const UHashtable *alternates, UErrorCode &status); - - private: - - IdentifierInfo & clear(); - UBool containsWithAlternates(const ScriptSet &container, const ScriptSet &containee) const; - - UnicodeString *fIdentifier; - ScriptSet *fRequiredScripts; - UHashtable *fScriptSetSet; - ScriptSet *fCommonAmongAlternates; - UnicodeSet *fNumerics; - UnicodeSet *fIdentifierProfile; -}; - -U_NAMESPACE_END - -#endif // __IDENTIFIER_INFO_H__ diff --git a/deps/icu-small/source/i18n/indiancal.cpp b/deps/icu-small/source/i18n/indiancal.cpp index 722d3adcdc..7964d45312 100644 --- a/deps/icu-small/source/i18n/indiancal.cpp +++ b/deps/icu-small/source/i18n/indiancal.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* * Copyright (C) 2003-2014, International Business Machines Corporation * and others. All Rights Reserved. diff --git a/deps/icu-small/source/i18n/indiancal.h b/deps/icu-small/source/i18n/indiancal.h index 62ff1c78e7..fcc21d729b 100644 --- a/deps/icu-small/source/i18n/indiancal.h +++ b/deps/icu-small/source/i18n/indiancal.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ***************************************************************************** * Copyright (C) 2003-2008, International Business Machines Corporation diff --git a/deps/icu-small/source/i18n/inputext.cpp b/deps/icu-small/source/i18n/inputext.cpp index 5c75d5d42c..4e053aef2e 100644 --- a/deps/icu-small/source/i18n/inputext.cpp +++ b/deps/icu-small/source/i18n/inputext.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2005-2016, International Business Machines diff --git a/deps/icu-small/source/i18n/inputext.h b/deps/icu-small/source/i18n/inputext.h index 12b915a0bd..6a5d253e05 100644 --- a/deps/icu-small/source/i18n/inputext.h +++ b/deps/icu-small/source/i18n/inputext.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2005-2008, International Business Machines diff --git a/deps/icu-small/source/i18n/islamcal.cpp b/deps/icu-small/source/i18n/islamcal.cpp index f343ebd88b..7c2d1b6b98 100644 --- a/deps/icu-small/source/i18n/islamcal.cpp +++ b/deps/icu-small/source/i18n/islamcal.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * Copyright (C) 2003-2015, International Business Machines Corporation @@ -734,7 +736,7 @@ int32_t IslamicCalendar::defaultCenturyStartYear() const } -void U_CALLCONV +U_CFUNC void U_CALLCONV IslamicCalendar::initializeSystemDefaultCentury() { // initialize systemDefaultCentury and systemDefaultCenturyYear based diff --git a/deps/icu-small/source/i18n/islamcal.h b/deps/icu-small/source/i18n/islamcal.h index 8597ace929..4e2a1e3d52 100644 --- a/deps/icu-small/source/i18n/islamcal.h +++ b/deps/icu-small/source/i18n/islamcal.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** * Copyright (C) 2003-2013, International Business Machines Corporation @@ -417,7 +419,7 @@ class U_I18N_API IslamicCalendar : public Calendar { * are considered to fall within so that its start date is 80 years * before the current time. */ - static void initializeSystemDefaultCentury(void); + static void U_CALLCONV initializeSystemDefaultCentury(void); }; U_NAMESPACE_END diff --git a/deps/icu-small/source/i18n/japancal.cpp b/deps/icu-small/source/i18n/japancal.cpp index e9b5483620..0c8396f6f8 100644 --- a/deps/icu-small/source/i18n/japancal.cpp +++ b/deps/icu-small/source/i18n/japancal.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2003-2009,2012,2016 International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/japancal.h b/deps/icu-small/source/i18n/japancal.h index f4c405eba9..ab267f81f1 100644 --- a/deps/icu-small/source/i18n/japancal.h +++ b/deps/icu-small/source/i18n/japancal.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** * Copyright (C) 2003-2008, International Business Machines Corporation diff --git a/deps/icu-small/source/i18n/measfmt.cpp b/deps/icu-small/source/i18n/measfmt.cpp index f8f46a9a95..4ac2f7d5eb 100644 --- a/deps/icu-small/source/i18n/measfmt.cpp +++ b/deps/icu-small/source/i18n/measfmt.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2004-2016, International Business Machines @@ -39,7 +41,7 @@ #include "standardplural.h" #include "unifiedcache.h" -#define MEAS_UNIT_COUNT 134 +#define MEAS_UNIT_COUNT 138 #define WIDTH_INDEX_COUNT (UMEASFMT_WIDTH_NARROW + 1) U_NAMESPACE_BEGIN @@ -108,6 +110,7 @@ public: UMeasureFormatWidth widthFallback[WIDTH_INDEX_COUNT]; /** Measure unit -> format width -> array of patterns ("{0} meters") (plurals + PER_UNIT_INDEX) */ SimpleFormatter *patterns[MEAS_UNIT_COUNT][WIDTH_INDEX_COUNT][PATTERN_COUNT]; + const UChar* dnams[MEAS_UNIT_COUNT][WIDTH_INDEX_COUNT]; SimpleFormatter perFormatters[WIDTH_INDEX_COUNT]; MeasureFormatCacheData(); @@ -157,6 +160,7 @@ MeasureFormatCacheData::MeasureFormatCacheData() { currencyFormats[i] = NULL; } uprv_memset(patterns, 0, sizeof(patterns)); + uprv_memset(dnams, 0, sizeof(dnams)); integerFormat = NULL; numericDateFormatters = NULL; } @@ -172,6 +176,7 @@ MeasureFormatCacheData::~MeasureFormatCacheData() { } } } + // Note: the contents of 'dnams' are pointers into the resource bundle delete integerFormat; delete numericDateFormatters; } @@ -213,117 +218,135 @@ static const UChar gNarrow[] = { 0x4E, 0x61, 0x72, 0x72, 0x6F, 0x77 }; * C++: Each inner sink class has a reference to the main outer sink. * Java: Use non-static inner classes instead. */ -struct UnitDataSink : public ResourceTableSink { - /** - * Sink for a table of display patterns. For example, - * unitsShort/duration/hour contains other{"{0} hrs"}. - */ - struct UnitPatternSink : public ResourceTableSink { - UnitPatternSink(UnitDataSink &sink) : outer(sink) {} - ~UnitPatternSink(); - - void setFormatterIfAbsent(int32_t index, const ResourceValue &value, - int32_t minPlaceholders, UErrorCode &errorCode) { - SimpleFormatter **patterns = - &outer.cacheData.patterns[outer.unitIndex][outer.width][0]; - if (U_SUCCESS(errorCode) && patterns[index] == NULL) { +struct UnitDataSink : public ResourceSink { + + // Output data. + MeasureFormatCacheData &cacheData; + + // Path to current data. + UMeasureFormatWidth width; + const char *type; + int32_t unitIndex; + + UnitDataSink(MeasureFormatCacheData &outputData) + : cacheData(outputData), + width(UMEASFMT_WIDTH_COUNT), type(NULL), unitIndex(0) {} + ~UnitDataSink(); + + void setFormatterIfAbsent(int32_t index, const ResourceValue &value, + int32_t minPlaceholders, UErrorCode &errorCode) { + SimpleFormatter **patterns = &cacheData.patterns[unitIndex][width][0]; + if (U_SUCCESS(errorCode) && patterns[index] == NULL) { + if (minPlaceholders >= 0) { patterns[index] = new SimpleFormatter( - value.getUnicodeString(errorCode), minPlaceholders, 1, errorCode); - if (U_SUCCESS(errorCode) && patterns[index] == NULL) { - errorCode = U_MEMORY_ALLOCATION_ERROR; - } + value.getUnicodeString(errorCode), minPlaceholders, 1, errorCode); + } + if (U_SUCCESS(errorCode) && patterns[index] == NULL) { + errorCode = U_MEMORY_ALLOCATION_ERROR; } } + } - virtual void put(const char *key, const ResourceValue &value, UErrorCode &errorCode) { - if (U_FAILURE(errorCode)) { return; } - if (uprv_strcmp(key, "dnam") == 0) { - // Skip the unit display name for now. - } else if (uprv_strcmp(key, "per") == 0) { - // For example, "{0}/h". - setFormatterIfAbsent(MeasureFormatCacheData::PER_UNIT_INDEX, value, 1, errorCode); - } else { - // The key must be one of the plural form strings. For example: - // one{"{0} hr"} - // other{"{0} hrs"} - setFormatterIfAbsent(StandardPlural::indexFromString(key, errorCode), value, 0, - errorCode); - } + void setDnamIfAbsent(const ResourceValue &value, UErrorCode& errorCode) { + if (cacheData.dnams[unitIndex][width] == NULL) { + int32_t length; + cacheData.dnams[unitIndex][width] = value.getString(length, errorCode); } - UnitDataSink &outer; - } patternSink; + } /** - * Sink for a table of per-unit tables. For example, + * Consume a display pattern. For example, + * unitsShort/duration/hour contains other{"{0} hrs"}. + */ + void consumePattern(const char *key, const ResourceValue &value, UErrorCode &errorCode) { + if (U_FAILURE(errorCode)) { return; } + if (uprv_strcmp(key, "dnam") == 0) { + // The display name for the unit in the current width. + setDnamIfAbsent(value, errorCode); + } else if (uprv_strcmp(key, "per") == 0) { + // For example, "{0}/h". + setFormatterIfAbsent(MeasureFormatCacheData::PER_UNIT_INDEX, value, 1, errorCode); + } else { + // The key must be one of the plural form strings. For example: + // one{"{0} hr"} + // other{"{0} hrs"} + setFormatterIfAbsent(StandardPlural::indexFromString(key, errorCode), value, 0, + errorCode); + } + } + + /** + * Consume a table of per-unit tables. For example, * unitsShort/duration contains tables for duration-unit subtypes day & hour. */ - struct UnitSubtypeSink : public ResourceTableSink { - UnitSubtypeSink(UnitDataSink &sink) : outer(sink) {} - ~UnitSubtypeSink(); - virtual ResourceTableSink *getOrCreateTableSink( - const char *key, int32_t /* initialSize */, UErrorCode &errorCode) { - if (U_FAILURE(errorCode)) { return NULL; } - outer.unitIndex = MeasureUnit::internalGetIndexForTypeAndSubtype(outer.type, key); - if (outer.unitIndex >= 0) { - return &outer.patternSink; + void consumeSubtypeTable(const char *key, ResourceValue &value, UErrorCode &errorCode) { + if (U_FAILURE(errorCode)) { return; } + unitIndex = MeasureUnit::internalGetIndexForTypeAndSubtype(type, key); + if (unitIndex < 0) { + // TODO: How to handle unexpected data? + // See http://bugs.icu-project.org/trac/ticket/12597 + return; + } + + if (value.getType() == URES_STRING) { + // Units like "coordinate" that don't have plural variants + setFormatterIfAbsent(StandardPlural::OTHER, value, 0, errorCode); + } else if (value.getType() == URES_TABLE) { + // Units that have plural variants + ResourceTable patternTableTable = value.getTable(errorCode); + if (U_FAILURE(errorCode)) { return; } + for (int i = 0; patternTableTable.getKeyAndValue(i, key, value); ++i) { + consumePattern(key, value, errorCode); } - return NULL; + } else { + // TODO: How to handle unexpected data? + // See http://bugs.icu-project.org/trac/ticket/12597 + return; } - UnitDataSink &outer; - } subtypeSink; + } /** - * Sink for compound x-per-y display pattern. For example, + * Consume compound x-per-y display pattern. For example, * unitsShort/compound/per may be "{0}/{1}". */ - struct UnitCompoundSink : public ResourceTableSink { - UnitCompoundSink(UnitDataSink &sink) : outer(sink) {} - ~UnitCompoundSink(); - virtual void put(const char *key, const ResourceValue &value, UErrorCode &errorCode) { - if (U_SUCCESS(errorCode) && uprv_strcmp(key, "per") == 0) { - outer.cacheData.perFormatters[outer.width]. - applyPatternMinMaxArguments(value.getUnicodeString(errorCode), 2, 2, errorCode); - } + void consumeCompoundPattern(const char *key, const ResourceValue &value, UErrorCode &errorCode) { + if (U_SUCCESS(errorCode) && uprv_strcmp(key, "per") == 0) { + cacheData.perFormatters[width]. + applyPatternMinMaxArguments(value.getUnicodeString(errorCode), 2, 2, errorCode); } - UnitDataSink &outer; - } compoundSink; + } /** - * Sink for a table of unit type tables. For example, + * Consume a table of unit type tables. For example, * unitsShort contains tables for area & duration. * It also contains a table for the compound/per pattern. */ - struct UnitTypeSink : public ResourceTableSink { - UnitTypeSink(UnitDataSink &sink) : outer(sink) {} - ~UnitTypeSink(); - virtual ResourceTableSink *getOrCreateTableSink( - const char *key, int32_t /* initialSize */, UErrorCode &errorCode) { - if (U_FAILURE(errorCode)) { return NULL; } - if (uprv_strcmp(key, "currency") == 0) { - // Skip. - } else if (uprv_strcmp(key, "compound") == 0) { - if (!outer.cacheData.hasPerFormatter(outer.width)) { - return &outer.compoundSink; + void consumeUnitTypesTable(const char *key, ResourceValue &value, UErrorCode &errorCode) { + if (U_FAILURE(errorCode)) { return; } + if (uprv_strcmp(key, "currency") == 0) { + // Skip. + } else if (uprv_strcmp(key, "compound") == 0) { + if (!cacheData.hasPerFormatter(width)) { + ResourceTable compoundTable = value.getTable(errorCode); + if (U_FAILURE(errorCode)) { return; } + for (int i = 0; compoundTable.getKeyAndValue(i, key, value); ++i) { + consumeCompoundPattern(key, value, errorCode); } - } else { - outer.type = key; - return &outer.subtypeSink; } - return NULL; + } else { + type = key; + ResourceTable subtypeTable = value.getTable(errorCode); + if (U_FAILURE(errorCode)) { return; } + for (int i = 0; subtypeTable.getKeyAndValue(i, key, value); ++i) { + consumeSubtypeTable(key, value, errorCode); + } } - UnitDataSink &outer; - } typeSink; + } - UnitDataSink(MeasureFormatCacheData &outputData) - : patternSink(*this), subtypeSink(*this), compoundSink(*this), typeSink(*this), - cacheData(outputData), - width(UMEASFMT_WIDTH_COUNT), type(NULL), unitIndex(0) {} - ~UnitDataSink(); - virtual void put(const char *key, const ResourceValue &value, UErrorCode &errorCode) { + void consumeAlias(const char *key, const ResourceValue &value, UErrorCode &errorCode) { // Handle aliases like // units:alias{"/LOCALE/unitsShort"} // which should only occur in the root bundle. - if (U_FAILURE(errorCode) || value.getType() != URES_ALIAS) { return; } UMeasureFormatWidth sourceWidth = widthFromKey(key); if (sourceWidth == UMEASFMT_WIDTH_COUNT) { // Alias from something we don't care about. @@ -342,12 +365,15 @@ struct UnitDataSink : public ResourceTableSink { } cacheData.widthFallback[sourceWidth] = targetWidth; } - virtual ResourceTableSink *getOrCreateTableSink( - const char *key, int32_t /* initialSize */, UErrorCode &errorCode) { + + void consumeTable(const char *key, ResourceValue &value, UErrorCode &errorCode) { if (U_SUCCESS(errorCode) && (width = widthFromKey(key)) != UMEASFMT_WIDTH_COUNT) { - return &typeSink; + ResourceTable unitTypesTable = value.getTable(errorCode); + if (U_FAILURE(errorCode)) { return; } + for (int i = 0; unitTypesTable.getKeyAndValue(i, key, value); ++i) { + consumeUnitTypesTable(key, value, errorCode); + } } - return NULL; } static UMeasureFormatWidth widthFromKey(const char *key) { @@ -382,20 +408,22 @@ struct UnitDataSink : public ResourceTableSink { return UMEASFMT_WIDTH_COUNT; } - // Output data. - MeasureFormatCacheData &cacheData; - - // Path to current data. - UMeasureFormatWidth width; - const char *type; - int32_t unitIndex; + virtual void put(const char *key, ResourceValue &value, UBool /*noFallback*/, + UErrorCode &errorCode) { + // Main entry point to sink + ResourceTable widthsTable = value.getTable(errorCode); + if (U_FAILURE(errorCode)) { return; } + for (int i = 0; widthsTable.getKeyAndValue(i, key, value); ++i) { + if (value.getType() == URES_ALIAS) { + consumeAlias(key, value, errorCode); + } else { + consumeTable(key, value, errorCode); + } + } + } }; // Virtual destructors must be defined out of line. -UnitDataSink::UnitPatternSink::~UnitPatternSink() {} -UnitDataSink::UnitSubtypeSink::~UnitSubtypeSink() {} -UnitDataSink::UnitCompoundSink::~UnitCompoundSink() {} -UnitDataSink::UnitTypeSink::~UnitTypeSink() {} UnitDataSink::~UnitDataSink() {} } // namespace @@ -405,7 +433,7 @@ static UBool loadMeasureUnitData( MeasureFormatCacheData &cacheData, UErrorCode &status) { UnitDataSink sink(cacheData); - ures_getAllTableItemsWithFallback(resource, "", sink, status); + ures_getAllItemsWithFallback(resource, "", sink, status); return U_SUCCESS(status); } @@ -484,8 +512,14 @@ const MeasureFormatCacheData *LocaleCacheKey<MeasureFormatCacheData>::createObje } for (int32_t i = 0; i < WIDTH_INDEX_COUNT; ++i) { + // NumberFormat::createInstance can erase warning codes from status, so pass it + // a separate status instance + UErrorCode localStatus = U_ZERO_ERROR; result->adoptCurrencyFormat(i, NumberFormat::createInstance( - localeId, currencyStyles[i], status)); + localeId, currencyStyles[i], localStatus)); + if (localStatus != U_ZERO_ERROR) { + status = localStatus; + } if (U_FAILURE(status)) { return NULL; } @@ -795,6 +829,24 @@ UnicodeString &MeasureFormat::formatMeasures( return appendTo; } +UnicodeString MeasureFormat::getUnitDisplayName(const MeasureUnit& unit, UErrorCode& /*status*/) const { + UMeasureFormatWidth width = getRegularWidth(this->width); + const UChar* const* styleToDnam = cache->dnams[unit.getIndex()]; + const UChar* dnam = styleToDnam[width]; + if (dnam == NULL) { + int32_t fallbackWidth = cache->widthFallback[width]; + dnam = styleToDnam[fallbackWidth]; + } + + UnicodeString result; + if (dnam == NULL) { + result.setToBogus(); + } else { + result.setTo(dnam, -1); + } + return result; +} + void MeasureFormat::initMeasureFormat( const Locale &locale, UMeasureFormatWidth w, diff --git a/deps/icu-small/source/i18n/measunit.cpp b/deps/icu-small/source/i18n/measunit.cpp index ad540b5085..a3021b7405 100644 --- a/deps/icu-small/source/i18n/measunit.cpp +++ b/deps/icu-small/source/i18n/measunit.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2004-2016, International Business Machines @@ -38,20 +40,21 @@ static const int32_t gOffsets[] = { 16, 20, 24, - 284, - 294, - 305, + 28, + 288, + 298, 309, - 315, + 313, 319, - 338, - 339, - 350, - 356, - 361, + 323, + 342, + 343, + 354, + 360, 365, 369, - 394 + 373, + 398 }; static const int32_t gIndexes[] = { @@ -61,20 +64,21 @@ static const int32_t gIndexes[] = { 16, 20, 24, - 24, - 34, - 45, + 28, + 28, + 38, 49, - 55, + 53, 59, - 78, - 79, - 90, - 96, - 101, + 63, + 82, + 83, + 94, + 100, 105, 109, - 134 + 113, + 138 }; // Must be sorted alphabetically. @@ -84,6 +88,7 @@ static const char * const gTypes[] = { "area", "concentr", "consumption", + "coordinate", "currency", "digital", "duration", @@ -126,6 +131,10 @@ static const char * const gSubTypes[] = { "liter-per-kilometer", "mile-per-gallon", "mile-per-gallon-imperial", + "east", + "north", + "south", + "west", "ADP", "AED", "AFA", @@ -500,14 +509,14 @@ static const char * const gSubTypes[] = { // Must be sorted by first value and then second value. static int32_t unitPerUnitToSingleUnit[][4] = { - {326, 296, 16, 0}, - {328, 302, 16, 2}, - {330, 296, 16, 3}, - {330, 383, 4, 2}, - {330, 384, 4, 3}, - {344, 381, 3, 1}, - {347, 11, 15, 4}, - {386, 326, 4, 1} + {330, 300, 17, 0}, + {332, 306, 17, 2}, + {334, 300, 17, 3}, + {334, 387, 4, 2}, + {334, 388, 4, 3}, + {348, 385, 3, 1}, + {351, 11, 16, 4}, + {390, 330, 4, 1} }; MeasureUnit *MeasureUnit::createGForce(UErrorCode &status) { @@ -606,444 +615,460 @@ MeasureUnit *MeasureUnit::createMilePerGallonImperial(UErrorCode &status) { return MeasureUnit::create(4, 3, status); } +MeasureUnit *MeasureUnit::createEast(UErrorCode &status) { + return MeasureUnit::create(5, 0, status); +} + +MeasureUnit *MeasureUnit::createNorth(UErrorCode &status) { + return MeasureUnit::create(5, 1, status); +} + +MeasureUnit *MeasureUnit::createSouth(UErrorCode &status) { + return MeasureUnit::create(5, 2, status); +} + +MeasureUnit *MeasureUnit::createWest(UErrorCode &status) { + return MeasureUnit::create(5, 3, status); +} + MeasureUnit *MeasureUnit::createBit(UErrorCode &status) { - return MeasureUnit::create(6, 0, status); + return MeasureUnit::create(7, 0, status); } MeasureUnit *MeasureUnit::createByte(UErrorCode &status) { - return MeasureUnit::create(6, 1, status); + return MeasureUnit::create(7, 1, status); } MeasureUnit *MeasureUnit::createGigabit(UErrorCode &status) { - return MeasureUnit::create(6, 2, status); + return MeasureUnit::create(7, 2, status); } MeasureUnit *MeasureUnit::createGigabyte(UErrorCode &status) { - return MeasureUnit::create(6, 3, status); + return MeasureUnit::create(7, 3, status); } MeasureUnit *MeasureUnit::createKilobit(UErrorCode &status) { - return MeasureUnit::create(6, 4, status); + return MeasureUnit::create(7, 4, status); } MeasureUnit *MeasureUnit::createKilobyte(UErrorCode &status) { - return MeasureUnit::create(6, 5, status); + return MeasureUnit::create(7, 5, status); } MeasureUnit *MeasureUnit::createMegabit(UErrorCode &status) { - return MeasureUnit::create(6, 6, status); + return MeasureUnit::create(7, 6, status); } MeasureUnit *MeasureUnit::createMegabyte(UErrorCode &status) { - return MeasureUnit::create(6, 7, status); + return MeasureUnit::create(7, 7, status); } MeasureUnit *MeasureUnit::createTerabit(UErrorCode &status) { - return MeasureUnit::create(6, 8, status); + return MeasureUnit::create(7, 8, status); } MeasureUnit *MeasureUnit::createTerabyte(UErrorCode &status) { - return MeasureUnit::create(6, 9, status); + return MeasureUnit::create(7, 9, status); } MeasureUnit *MeasureUnit::createCentury(UErrorCode &status) { - return MeasureUnit::create(7, 0, status); + return MeasureUnit::create(8, 0, status); } MeasureUnit *MeasureUnit::createDay(UErrorCode &status) { - return MeasureUnit::create(7, 1, status); + return MeasureUnit::create(8, 1, status); } MeasureUnit *MeasureUnit::createHour(UErrorCode &status) { - return MeasureUnit::create(7, 2, status); + return MeasureUnit::create(8, 2, status); } MeasureUnit *MeasureUnit::createMicrosecond(UErrorCode &status) { - return MeasureUnit::create(7, 3, status); + return MeasureUnit::create(8, 3, status); } MeasureUnit *MeasureUnit::createMillisecond(UErrorCode &status) { - return MeasureUnit::create(7, 4, status); + return MeasureUnit::create(8, 4, status); } MeasureUnit *MeasureUnit::createMinute(UErrorCode &status) { - return MeasureUnit::create(7, 5, status); + return MeasureUnit::create(8, 5, status); } MeasureUnit *MeasureUnit::createMonth(UErrorCode &status) { - return MeasureUnit::create(7, 6, status); + return MeasureUnit::create(8, 6, status); } MeasureUnit *MeasureUnit::createNanosecond(UErrorCode &status) { - return MeasureUnit::create(7, 7, status); + return MeasureUnit::create(8, 7, status); } MeasureUnit *MeasureUnit::createSecond(UErrorCode &status) { - return MeasureUnit::create(7, 8, status); + return MeasureUnit::create(8, 8, status); } MeasureUnit *MeasureUnit::createWeek(UErrorCode &status) { - return MeasureUnit::create(7, 9, status); + return MeasureUnit::create(8, 9, status); } MeasureUnit *MeasureUnit::createYear(UErrorCode &status) { - return MeasureUnit::create(7, 10, status); + return MeasureUnit::create(8, 10, status); } MeasureUnit *MeasureUnit::createAmpere(UErrorCode &status) { - return MeasureUnit::create(8, 0, status); + return MeasureUnit::create(9, 0, status); } MeasureUnit *MeasureUnit::createMilliampere(UErrorCode &status) { - return MeasureUnit::create(8, 1, status); + return MeasureUnit::create(9, 1, status); } MeasureUnit *MeasureUnit::createOhm(UErrorCode &status) { - return MeasureUnit::create(8, 2, status); + return MeasureUnit::create(9, 2, status); } MeasureUnit *MeasureUnit::createVolt(UErrorCode &status) { - return MeasureUnit::create(8, 3, status); + return MeasureUnit::create(9, 3, status); } MeasureUnit *MeasureUnit::createCalorie(UErrorCode &status) { - return MeasureUnit::create(9, 0, status); + return MeasureUnit::create(10, 0, status); } MeasureUnit *MeasureUnit::createFoodcalorie(UErrorCode &status) { - return MeasureUnit::create(9, 1, status); + return MeasureUnit::create(10, 1, status); } MeasureUnit *MeasureUnit::createJoule(UErrorCode &status) { - return MeasureUnit::create(9, 2, status); + return MeasureUnit::create(10, 2, status); } MeasureUnit *MeasureUnit::createKilocalorie(UErrorCode &status) { - return MeasureUnit::create(9, 3, status); + return MeasureUnit::create(10, 3, status); } MeasureUnit *MeasureUnit::createKilojoule(UErrorCode &status) { - return MeasureUnit::create(9, 4, status); + return MeasureUnit::create(10, 4, status); } MeasureUnit *MeasureUnit::createKilowattHour(UErrorCode &status) { - return MeasureUnit::create(9, 5, status); + return MeasureUnit::create(10, 5, status); } MeasureUnit *MeasureUnit::createGigahertz(UErrorCode &status) { - return MeasureUnit::create(10, 0, status); + return MeasureUnit::create(11, 0, status); } MeasureUnit *MeasureUnit::createHertz(UErrorCode &status) { - return MeasureUnit::create(10, 1, status); + return MeasureUnit::create(11, 1, status); } MeasureUnit *MeasureUnit::createKilohertz(UErrorCode &status) { - return MeasureUnit::create(10, 2, status); + return MeasureUnit::create(11, 2, status); } MeasureUnit *MeasureUnit::createMegahertz(UErrorCode &status) { - return MeasureUnit::create(10, 3, status); + return MeasureUnit::create(11, 3, status); } MeasureUnit *MeasureUnit::createAstronomicalUnit(UErrorCode &status) { - return MeasureUnit::create(11, 0, status); + return MeasureUnit::create(12, 0, status); } MeasureUnit *MeasureUnit::createCentimeter(UErrorCode &status) { - return MeasureUnit::create(11, 1, status); + return MeasureUnit::create(12, 1, status); } MeasureUnit *MeasureUnit::createDecimeter(UErrorCode &status) { - return MeasureUnit::create(11, 2, status); + return MeasureUnit::create(12, 2, status); } MeasureUnit *MeasureUnit::createFathom(UErrorCode &status) { - return MeasureUnit::create(11, 3, status); + return MeasureUnit::create(12, 3, status); } MeasureUnit *MeasureUnit::createFoot(UErrorCode &status) { - return MeasureUnit::create(11, 4, status); + return MeasureUnit::create(12, 4, status); } MeasureUnit *MeasureUnit::createFurlong(UErrorCode &status) { - return MeasureUnit::create(11, 5, status); + return MeasureUnit::create(12, 5, status); } MeasureUnit *MeasureUnit::createInch(UErrorCode &status) { - return MeasureUnit::create(11, 6, status); + return MeasureUnit::create(12, 6, status); } MeasureUnit *MeasureUnit::createKilometer(UErrorCode &status) { - return MeasureUnit::create(11, 7, status); + return MeasureUnit::create(12, 7, status); } MeasureUnit *MeasureUnit::createLightYear(UErrorCode &status) { - return MeasureUnit::create(11, 8, status); + return MeasureUnit::create(12, 8, status); } MeasureUnit *MeasureUnit::createMeter(UErrorCode &status) { - return MeasureUnit::create(11, 9, status); + return MeasureUnit::create(12, 9, status); } MeasureUnit *MeasureUnit::createMicrometer(UErrorCode &status) { - return MeasureUnit::create(11, 10, status); + return MeasureUnit::create(12, 10, status); } MeasureUnit *MeasureUnit::createMile(UErrorCode &status) { - return MeasureUnit::create(11, 11, status); + return MeasureUnit::create(12, 11, status); } MeasureUnit *MeasureUnit::createMileScandinavian(UErrorCode &status) { - return MeasureUnit::create(11, 12, status); + return MeasureUnit::create(12, 12, status); } MeasureUnit *MeasureUnit::createMillimeter(UErrorCode &status) { - return MeasureUnit::create(11, 13, status); + return MeasureUnit::create(12, 13, status); } MeasureUnit *MeasureUnit::createNanometer(UErrorCode &status) { - return MeasureUnit::create(11, 14, status); + return MeasureUnit::create(12, 14, status); } MeasureUnit *MeasureUnit::createNauticalMile(UErrorCode &status) { - return MeasureUnit::create(11, 15, status); + return MeasureUnit::create(12, 15, status); } MeasureUnit *MeasureUnit::createParsec(UErrorCode &status) { - return MeasureUnit::create(11, 16, status); + return MeasureUnit::create(12, 16, status); } MeasureUnit *MeasureUnit::createPicometer(UErrorCode &status) { - return MeasureUnit::create(11, 17, status); + return MeasureUnit::create(12, 17, status); } MeasureUnit *MeasureUnit::createYard(UErrorCode &status) { - return MeasureUnit::create(11, 18, status); + return MeasureUnit::create(12, 18, status); } MeasureUnit *MeasureUnit::createLux(UErrorCode &status) { - return MeasureUnit::create(12, 0, status); + return MeasureUnit::create(13, 0, status); } MeasureUnit *MeasureUnit::createCarat(UErrorCode &status) { - return MeasureUnit::create(13, 0, status); + return MeasureUnit::create(14, 0, status); } MeasureUnit *MeasureUnit::createGram(UErrorCode &status) { - return MeasureUnit::create(13, 1, status); + return MeasureUnit::create(14, 1, status); } MeasureUnit *MeasureUnit::createKilogram(UErrorCode &status) { - return MeasureUnit::create(13, 2, status); + return MeasureUnit::create(14, 2, status); } MeasureUnit *MeasureUnit::createMetricTon(UErrorCode &status) { - return MeasureUnit::create(13, 3, status); + return MeasureUnit::create(14, 3, status); } MeasureUnit *MeasureUnit::createMicrogram(UErrorCode &status) { - return MeasureUnit::create(13, 4, status); + return MeasureUnit::create(14, 4, status); } MeasureUnit *MeasureUnit::createMilligram(UErrorCode &status) { - return MeasureUnit::create(13, 5, status); + return MeasureUnit::create(14, 5, status); } MeasureUnit *MeasureUnit::createOunce(UErrorCode &status) { - return MeasureUnit::create(13, 6, status); + return MeasureUnit::create(14, 6, status); } MeasureUnit *MeasureUnit::createOunceTroy(UErrorCode &status) { - return MeasureUnit::create(13, 7, status); + return MeasureUnit::create(14, 7, status); } MeasureUnit *MeasureUnit::createPound(UErrorCode &status) { - return MeasureUnit::create(13, 8, status); + return MeasureUnit::create(14, 8, status); } MeasureUnit *MeasureUnit::createStone(UErrorCode &status) { - return MeasureUnit::create(13, 9, status); + return MeasureUnit::create(14, 9, status); } MeasureUnit *MeasureUnit::createTon(UErrorCode &status) { - return MeasureUnit::create(13, 10, status); + return MeasureUnit::create(14, 10, status); } MeasureUnit *MeasureUnit::createGigawatt(UErrorCode &status) { - return MeasureUnit::create(14, 0, status); + return MeasureUnit::create(15, 0, status); } MeasureUnit *MeasureUnit::createHorsepower(UErrorCode &status) { - return MeasureUnit::create(14, 1, status); + return MeasureUnit::create(15, 1, status); } MeasureUnit *MeasureUnit::createKilowatt(UErrorCode &status) { - return MeasureUnit::create(14, 2, status); + return MeasureUnit::create(15, 2, status); } MeasureUnit *MeasureUnit::createMegawatt(UErrorCode &status) { - return MeasureUnit::create(14, 3, status); + return MeasureUnit::create(15, 3, status); } MeasureUnit *MeasureUnit::createMilliwatt(UErrorCode &status) { - return MeasureUnit::create(14, 4, status); + return MeasureUnit::create(15, 4, status); } MeasureUnit *MeasureUnit::createWatt(UErrorCode &status) { - return MeasureUnit::create(14, 5, status); + return MeasureUnit::create(15, 5, status); } MeasureUnit *MeasureUnit::createHectopascal(UErrorCode &status) { - return MeasureUnit::create(15, 0, status); + return MeasureUnit::create(16, 0, status); } MeasureUnit *MeasureUnit::createInchHg(UErrorCode &status) { - return MeasureUnit::create(15, 1, status); + return MeasureUnit::create(16, 1, status); } MeasureUnit *MeasureUnit::createMillibar(UErrorCode &status) { - return MeasureUnit::create(15, 2, status); + return MeasureUnit::create(16, 2, status); } MeasureUnit *MeasureUnit::createMillimeterOfMercury(UErrorCode &status) { - return MeasureUnit::create(15, 3, status); + return MeasureUnit::create(16, 3, status); } MeasureUnit *MeasureUnit::createPoundPerSquareInch(UErrorCode &status) { - return MeasureUnit::create(15, 4, status); + return MeasureUnit::create(16, 4, status); } MeasureUnit *MeasureUnit::createKilometerPerHour(UErrorCode &status) { - return MeasureUnit::create(16, 0, status); + return MeasureUnit::create(17, 0, status); } MeasureUnit *MeasureUnit::createKnot(UErrorCode &status) { - return MeasureUnit::create(16, 1, status); + return MeasureUnit::create(17, 1, status); } MeasureUnit *MeasureUnit::createMeterPerSecond(UErrorCode &status) { - return MeasureUnit::create(16, 2, status); + return MeasureUnit::create(17, 2, status); } MeasureUnit *MeasureUnit::createMilePerHour(UErrorCode &status) { - return MeasureUnit::create(16, 3, status); + return MeasureUnit::create(17, 3, status); } MeasureUnit *MeasureUnit::createCelsius(UErrorCode &status) { - return MeasureUnit::create(17, 0, status); + return MeasureUnit::create(18, 0, status); } MeasureUnit *MeasureUnit::createFahrenheit(UErrorCode &status) { - return MeasureUnit::create(17, 1, status); + return MeasureUnit::create(18, 1, status); } MeasureUnit *MeasureUnit::createGenericTemperature(UErrorCode &status) { - return MeasureUnit::create(17, 2, status); + return MeasureUnit::create(18, 2, status); } MeasureUnit *MeasureUnit::createKelvin(UErrorCode &status) { - return MeasureUnit::create(17, 3, status); + return MeasureUnit::create(18, 3, status); } MeasureUnit *MeasureUnit::createAcreFoot(UErrorCode &status) { - return MeasureUnit::create(18, 0, status); + return MeasureUnit::create(19, 0, status); } MeasureUnit *MeasureUnit::createBushel(UErrorCode &status) { - return MeasureUnit::create(18, 1, status); + return MeasureUnit::create(19, 1, status); } MeasureUnit *MeasureUnit::createCentiliter(UErrorCode &status) { - return MeasureUnit::create(18, 2, status); + return MeasureUnit::create(19, 2, status); } MeasureUnit *MeasureUnit::createCubicCentimeter(UErrorCode &status) { - return MeasureUnit::create(18, 3, status); + return MeasureUnit::create(19, 3, status); } MeasureUnit *MeasureUnit::createCubicFoot(UErrorCode &status) { - return MeasureUnit::create(18, 4, status); + return MeasureUnit::create(19, 4, status); } MeasureUnit *MeasureUnit::createCubicInch(UErrorCode &status) { - return MeasureUnit::create(18, 5, status); + return MeasureUnit::create(19, 5, status); } MeasureUnit *MeasureUnit::createCubicKilometer(UErrorCode &status) { - return MeasureUnit::create(18, 6, status); + return MeasureUnit::create(19, 6, status); } MeasureUnit *MeasureUnit::createCubicMeter(UErrorCode &status) { - return MeasureUnit::create(18, 7, status); + return MeasureUnit::create(19, 7, status); } MeasureUnit *MeasureUnit::createCubicMile(UErrorCode &status) { - return MeasureUnit::create(18, 8, status); + return MeasureUnit::create(19, 8, status); } MeasureUnit *MeasureUnit::createCubicYard(UErrorCode &status) { - return MeasureUnit::create(18, 9, status); + return MeasureUnit::create(19, 9, status); } MeasureUnit *MeasureUnit::createCup(UErrorCode &status) { - return MeasureUnit::create(18, 10, status); + return MeasureUnit::create(19, 10, status); } MeasureUnit *MeasureUnit::createCupMetric(UErrorCode &status) { - return MeasureUnit::create(18, 11, status); + return MeasureUnit::create(19, 11, status); } MeasureUnit *MeasureUnit::createDeciliter(UErrorCode &status) { - return MeasureUnit::create(18, 12, status); + return MeasureUnit::create(19, 12, status); } MeasureUnit *MeasureUnit::createFluidOunce(UErrorCode &status) { - return MeasureUnit::create(18, 13, status); + return MeasureUnit::create(19, 13, status); } MeasureUnit *MeasureUnit::createGallon(UErrorCode &status) { - return MeasureUnit::create(18, 14, status); + return MeasureUnit::create(19, 14, status); } MeasureUnit *MeasureUnit::createGallonImperial(UErrorCode &status) { - return MeasureUnit::create(18, 15, status); + return MeasureUnit::create(19, 15, status); } MeasureUnit *MeasureUnit::createHectoliter(UErrorCode &status) { - return MeasureUnit::create(18, 16, status); + return MeasureUnit::create(19, 16, status); } MeasureUnit *MeasureUnit::createLiter(UErrorCode &status) { - return MeasureUnit::create(18, 17, status); + return MeasureUnit::create(19, 17, status); } MeasureUnit *MeasureUnit::createMegaliter(UErrorCode &status) { - return MeasureUnit::create(18, 18, status); + return MeasureUnit::create(19, 18, status); } MeasureUnit *MeasureUnit::createMilliliter(UErrorCode &status) { - return MeasureUnit::create(18, 19, status); + return MeasureUnit::create(19, 19, status); } MeasureUnit *MeasureUnit::createPint(UErrorCode &status) { - return MeasureUnit::create(18, 20, status); + return MeasureUnit::create(19, 20, status); } MeasureUnit *MeasureUnit::createPintMetric(UErrorCode &status) { - return MeasureUnit::create(18, 21, status); + return MeasureUnit::create(19, 21, status); } MeasureUnit *MeasureUnit::createQuart(UErrorCode &status) { - return MeasureUnit::create(18, 22, status); + return MeasureUnit::create(19, 22, status); } MeasureUnit *MeasureUnit::createTablespoon(UErrorCode &status) { - return MeasureUnit::create(18, 23, status); + return MeasureUnit::create(19, 23, status); } MeasureUnit *MeasureUnit::createTeaspoon(UErrorCode &status) { - return MeasureUnit::create(18, 24, status); + return MeasureUnit::create(19, 24, status); } // End generated code diff --git a/deps/icu-small/source/i18n/measure.cpp b/deps/icu-small/source/i18n/measure.cpp index eb610e6f8f..3459e71b80 100644 --- a/deps/icu-small/source/i18n/measure.cpp +++ b/deps/icu-small/source/i18n/measure.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2004-2014, International Business Machines diff --git a/deps/icu-small/source/i18n/msgfmt.cpp b/deps/icu-small/source/i18n/msgfmt.cpp index 1fe2c8d622..4658528050 100644 --- a/deps/icu-small/source/i18n/msgfmt.cpp +++ b/deps/icu-small/source/i18n/msgfmt.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /******************************************************************** * COPYRIGHT: * Copyright (c) 1997-2015, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/msgfmt_impl.h b/deps/icu-small/source/i18n/msgfmt_impl.h index 0f56dee885..80a07dc1ea 100644 --- a/deps/icu-small/source/i18n/msgfmt_impl.h +++ b/deps/icu-small/source/i18n/msgfmt_impl.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2007-2008, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/name2uni.cpp b/deps/icu-small/source/i18n/name2uni.cpp index 45705e676a..acd9c0af99 100644 --- a/deps/icu-small/source/i18n/name2uni.cpp +++ b/deps/icu-small/source/i18n/name2uni.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2001-2011, International Business Machines diff --git a/deps/icu-small/source/i18n/name2uni.h b/deps/icu-small/source/i18n/name2uni.h index 1324ec3e8d..2ba4c8f792 100644 --- a/deps/icu-small/source/i18n/name2uni.h +++ b/deps/icu-small/source/i18n/name2uni.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2001-2007, International Business Machines diff --git a/deps/icu-small/source/i18n/nfrlist.h b/deps/icu-small/source/i18n/nfrlist.h index 95e8378838..65b21c6b1d 100644 --- a/deps/icu-small/source/i18n/nfrlist.h +++ b/deps/icu-small/source/i18n/nfrlist.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * Copyright (C) 1997-2012, International Business Machines diff --git a/deps/icu-small/source/i18n/nfrs.cpp b/deps/icu-small/source/i18n/nfrs.cpp index 88f903cf20..5cbd33d0e2 100644 --- a/deps/icu-small/source/i18n/nfrs.cpp +++ b/deps/icu-small/source/i18n/nfrs.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * Copyright (C) 1997-2015, International Business Machines diff --git a/deps/icu-small/source/i18n/nfrs.h b/deps/icu-small/source/i18n/nfrs.h index 47c17e6fb5..b06c2b2215 100644 --- a/deps/icu-small/source/i18n/nfrs.h +++ b/deps/icu-small/source/i18n/nfrs.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * Copyright (C) 1997-2015, International Business Machines diff --git a/deps/icu-small/source/i18n/nfrule.cpp b/deps/icu-small/source/i18n/nfrule.cpp index b162b197ab..100a46490d 100644 --- a/deps/icu-small/source/i18n/nfrule.cpp +++ b/deps/icu-small/source/i18n/nfrule.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * Copyright (C) 1997-2015, International Business Machines diff --git a/deps/icu-small/source/i18n/nfrule.h b/deps/icu-small/source/i18n/nfrule.h index b4bc2cf28f..5424b968a1 100644 --- a/deps/icu-small/source/i18n/nfrule.h +++ b/deps/icu-small/source/i18n/nfrule.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 1997-2015, International Business Machines diff --git a/deps/icu-small/source/i18n/nfsubs.cpp b/deps/icu-small/source/i18n/nfsubs.cpp index ea570dc453..58039c8bac 100644 --- a/deps/icu-small/source/i18n/nfsubs.cpp +++ b/deps/icu-small/source/i18n/nfsubs.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * Copyright (C) 1997-2015, International Business Machines diff --git a/deps/icu-small/source/i18n/nfsubs.h b/deps/icu-small/source/i18n/nfsubs.h index e7a950a2dd..4fb0c06caf 100644 --- a/deps/icu-small/source/i18n/nfsubs.h +++ b/deps/icu-small/source/i18n/nfsubs.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * Copyright (C) 1997-2015, International Business Machines diff --git a/deps/icu-small/source/i18n/nortrans.cpp b/deps/icu-small/source/i18n/nortrans.cpp index 038a6836c3..da0206776c 100644 --- a/deps/icu-small/source/i18n/nortrans.cpp +++ b/deps/icu-small/source/i18n/nortrans.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2001-2011, International Business Machines diff --git a/deps/icu-small/source/i18n/nortrans.h b/deps/icu-small/source/i18n/nortrans.h index 634f534f7d..79d1be3b07 100644 --- a/deps/icu-small/source/i18n/nortrans.h +++ b/deps/icu-small/source/i18n/nortrans.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2001-2010, International Business Machines diff --git a/deps/icu-small/source/i18n/nultrans.cpp b/deps/icu-small/source/i18n/nultrans.cpp index 820c43d07e..600873e373 100644 --- a/deps/icu-small/source/i18n/nultrans.cpp +++ b/deps/icu-small/source/i18n/nultrans.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2000-2005, International Business Machines diff --git a/deps/icu-small/source/i18n/nultrans.h b/deps/icu-small/source/i18n/nultrans.h index 699c323f8c..a9856bde5b 100644 --- a/deps/icu-small/source/i18n/nultrans.h +++ b/deps/icu-small/source/i18n/nultrans.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2000-2007, International Business Machines diff --git a/deps/icu-small/source/i18n/numfmt.cpp b/deps/icu-small/source/i18n/numfmt.cpp index 3f10bbf1b4..c00955a781 100644 --- a/deps/icu-small/source/i18n/numfmt.cpp +++ b/deps/icu-small/source/i18n/numfmt.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 1997-2015, International Business Machines Corporation and @@ -450,7 +452,7 @@ NumberFormat::format(int64_t number, // XXXFormat::format(double UnicodeString& -NumberFormat::format(const StringPiece &decimalNum, +NumberFormat::format(StringPiece decimalNum, UnicodeString& toAppendTo, FieldPositionIterator* fpi, UErrorCode& status) const @@ -683,7 +685,7 @@ NumberFormat::parseObject(const UnicodeString& source, UnicodeString& NumberFormat::format(double number, UnicodeString& appendTo) const { - FieldPosition pos(0); + FieldPosition pos(FieldPosition::DONT_CARE); return format(number, appendTo, pos); } @@ -693,7 +695,7 @@ NumberFormat::format(double number, UnicodeString& appendTo) const UnicodeString& NumberFormat::format(int32_t number, UnicodeString& appendTo) const { - FieldPosition pos(0); + FieldPosition pos(FieldPosition::DONT_CARE); return format(number, appendTo, pos); } @@ -703,7 +705,7 @@ NumberFormat::format(int32_t number, UnicodeString& appendTo) const UnicodeString& NumberFormat::format(int64_t number, UnicodeString& appendTo) const { - FieldPosition pos(0); + FieldPosition pos(FieldPosition::DONT_CARE); return format(number, appendTo, pos); } diff --git a/deps/icu-small/source/i18n/numsys.cpp b/deps/icu-small/source/i18n/numsys.cpp index 498a8b3891..442ad7f255 100644 --- a/deps/icu-small/source/i18n/numsys.cpp +++ b/deps/icu-small/source/i18n/numsys.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2010-2015, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/numsys_impl.h b/deps/icu-small/source/i18n/numsys_impl.h index 5b7f4f3f3a..d39faba5af 100644 --- a/deps/icu-small/source/i18n/numsys_impl.h +++ b/deps/icu-small/source/i18n/numsys_impl.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2015, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/olsontz.cpp b/deps/icu-small/source/i18n/olsontz.cpp index 56b36c3666..f4c3dd24c9 100644 --- a/deps/icu-small/source/i18n/olsontz.cpp +++ b/deps/icu-small/source/i18n/olsontz.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2003-2013, International Business Machines diff --git a/deps/icu-small/source/i18n/olsontz.h b/deps/icu-small/source/i18n/olsontz.h index 115a0773c5..7dbc303a05 100644 --- a/deps/icu-small/source/i18n/olsontz.h +++ b/deps/icu-small/source/i18n/olsontz.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2003-2013, International Business Machines diff --git a/deps/icu-small/source/i18n/persncal.cpp b/deps/icu-small/source/i18n/persncal.cpp index e1b30b8aee..210646ca8c 100644 --- a/deps/icu-small/source/i18n/persncal.cpp +++ b/deps/icu-small/source/i18n/persncal.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * Copyright (C) 2003-2013, International Business Machines Corporation diff --git a/deps/icu-small/source/i18n/persncal.h b/deps/icu-small/source/i18n/persncal.h index ff18f6158c..3fe5a61464 100644 --- a/deps/icu-small/source/i18n/persncal.h +++ b/deps/icu-small/source/i18n/persncal.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * Copyright (C) 2003-2013, International Business Machines Corporation diff --git a/deps/icu-small/source/i18n/pluralaffix.cpp b/deps/icu-small/source/i18n/pluralaffix.cpp index b541f120df..f6a51a79ef 100644 --- a/deps/icu-small/source/i18n/pluralaffix.cpp +++ b/deps/icu-small/source/i18n/pluralaffix.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* * Copyright (C) 2015, International Business Machines * Corporation and others. All Rights Reserved. diff --git a/deps/icu-small/source/i18n/pluralaffix.h b/deps/icu-small/source/i18n/pluralaffix.h index 5212fc714b..a08f2131d9 100644 --- a/deps/icu-small/source/i18n/pluralaffix.h +++ b/deps/icu-small/source/i18n/pluralaffix.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2015, International Business Machines diff --git a/deps/icu-small/source/i18n/plurfmt.cpp b/deps/icu-small/source/i18n/plurfmt.cpp index 9ff2bffc9d..8a000ce6e9 100644 --- a/deps/icu-small/source/i18n/plurfmt.cpp +++ b/deps/icu-small/source/i18n/plurfmt.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2009-2015, International Business Machines Corporation and @@ -216,14 +218,14 @@ PluralFormat::format(const Formattable& obj, UnicodeString PluralFormat::format(int32_t number, UErrorCode& status) const { - FieldPosition fpos(0); + FieldPosition fpos(FieldPosition::DONT_CARE); UnicodeString result; return format(Formattable(number), number, result, fpos, status); } UnicodeString PluralFormat::format(double number, UErrorCode& status) const { - FieldPosition fpos(0); + FieldPosition fpos(FieldPosition::DONT_CARE); UnicodeString result; return format(Formattable(number), number, result, fpos, status); } diff --git a/deps/icu-small/source/i18n/plurrule.cpp b/deps/icu-small/source/i18n/plurrule.cpp index 9d5fa5bee2..7b50634551 100644 --- a/deps/icu-small/source/i18n/plurrule.cpp +++ b/deps/icu-small/source/i18n/plurrule.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2007-2016, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/plurrule_impl.h b/deps/icu-small/source/i18n/plurrule_impl.h index d829110cd0..c6e4767a09 100644 --- a/deps/icu-small/source/i18n/plurrule_impl.h +++ b/deps/icu-small/source/i18n/plurrule_impl.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2007-2016, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/precision.cpp b/deps/icu-small/source/i18n/precision.cpp index c7765748ad..5d07e0f9ee 100644 --- a/deps/icu-small/source/i18n/precision.cpp +++ b/deps/icu-small/source/i18n/precision.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* * Copyright (C) 2015, International Business Machines * Corporation and others. All Rights Reserved. diff --git a/deps/icu-small/source/i18n/precision.h b/deps/icu-small/source/i18n/precision.h index 4543108cef..f002fd228b 100644 --- a/deps/icu-small/source/i18n/precision.h +++ b/deps/icu-small/source/i18n/precision.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2015, International Business Machines diff --git a/deps/icu-small/source/i18n/quant.cpp b/deps/icu-small/source/i18n/quant.cpp index 4bfdf2a181..6e08e628fc 100644 --- a/deps/icu-small/source/i18n/quant.cpp +++ b/deps/icu-small/source/i18n/quant.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2001-2012, International Business Machines diff --git a/deps/icu-small/source/i18n/quant.h b/deps/icu-small/source/i18n/quant.h index f84c431332..21adf19e70 100644 --- a/deps/icu-small/source/i18n/quant.h +++ b/deps/icu-small/source/i18n/quant.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2001-2011, International Business Machines Corporation diff --git a/deps/icu-small/source/i18n/quantityformatter.cpp b/deps/icu-small/source/i18n/quantityformatter.cpp index 3b04c86d46..c44357a53b 100644 --- a/deps/icu-small/source/i18n/quantityformatter.cpp +++ b/deps/icu-small/source/i18n/quantityformatter.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * Copyright (C) 2014-2016, International Business Machines diff --git a/deps/icu-small/source/i18n/quantityformatter.h b/deps/icu-small/source/i18n/quantityformatter.h index 7f61c0dc03..0f61022666 100644 --- a/deps/icu-small/source/i18n/quantityformatter.h +++ b/deps/icu-small/source/i18n/quantityformatter.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * Copyright (C) 2014-2016, International Business Machines diff --git a/deps/icu-small/source/i18n/rbnf.cpp b/deps/icu-small/source/i18n/rbnf.cpp index 5f78f73b86..5e32d80444 100644 --- a/deps/icu-small/source/i18n/rbnf.cpp +++ b/deps/icu-small/source/i18n/rbnf.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 1997-2015, International Business Machines Corporation diff --git a/deps/icu-small/source/i18n/rbt.cpp b/deps/icu-small/source/i18n/rbt.cpp index e38aabc832..62aae52f18 100644 --- a/deps/icu-small/source/i18n/rbt.cpp +++ b/deps/icu-small/source/i18n/rbt.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 1999-2015, International Business Machines diff --git a/deps/icu-small/source/i18n/rbt.h b/deps/icu-small/source/i18n/rbt.h index f8a6f3cbc4..9add715aca 100644 --- a/deps/icu-small/source/i18n/rbt.h +++ b/deps/icu-small/source/i18n/rbt.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 1999-2007, International Business Machines diff --git a/deps/icu-small/source/i18n/rbt_data.cpp b/deps/icu-small/source/i18n/rbt_data.cpp index 579c681de0..1b6163956c 100644 --- a/deps/icu-small/source/i18n/rbt_data.cpp +++ b/deps/icu-small/source/i18n/rbt_data.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 1999-2014, International Business Machines diff --git a/deps/icu-small/source/i18n/rbt_data.h b/deps/icu-small/source/i18n/rbt_data.h index ce833dc26d..29e39a59ef 100644 --- a/deps/icu-small/source/i18n/rbt_data.h +++ b/deps/icu-small/source/i18n/rbt_data.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 1999-2007, International Business Machines Corporation diff --git a/deps/icu-small/source/i18n/rbt_pars.cpp b/deps/icu-small/source/i18n/rbt_pars.cpp index c6840456dd..5e7c0ff5f9 100644 --- a/deps/icu-small/source/i18n/rbt_pars.cpp +++ b/deps/icu-small/source/i18n/rbt_pars.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 1999-2016, International Business Machines diff --git a/deps/icu-small/source/i18n/rbt_pars.h b/deps/icu-small/source/i18n/rbt_pars.h index 497c1e3182..48067905b9 100644 --- a/deps/icu-small/source/i18n/rbt_pars.h +++ b/deps/icu-small/source/i18n/rbt_pars.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 1999-2011, International Business Machines Corporation diff --git a/deps/icu-small/source/i18n/rbt_rule.cpp b/deps/icu-small/source/i18n/rbt_rule.cpp index e88df7e5ae..a04a535f0e 100644 --- a/deps/icu-small/source/i18n/rbt_rule.cpp +++ b/deps/icu-small/source/i18n/rbt_rule.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 1999-2011, International Business Machines @@ -174,7 +176,7 @@ TransliterationRule::TransliterationRule(TransliterationRule& other) : segmentsCount = 0; if (other.segmentsCount > 0) { segments = (UnicodeFunctor **)uprv_malloc(other.segmentsCount * sizeof(UnicodeFunctor *)); - uprv_memcpy(segments, other.segments, other.segmentsCount*sizeof(segments[0])); + uprv_memcpy(segments, other.segments, (size_t)other.segmentsCount*sizeof(segments[0])); } if (other.anteContext != NULL) { diff --git a/deps/icu-small/source/i18n/rbt_rule.h b/deps/icu-small/source/i18n/rbt_rule.h index ffbd25c6a8..b25afd6ef0 100644 --- a/deps/icu-small/source/i18n/rbt_rule.h +++ b/deps/icu-small/source/i18n/rbt_rule.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* * Copyright (C) {1999-2001}, International Business Machines Corporation and others. All Rights Reserved. ********************************************************************** diff --git a/deps/icu-small/source/i18n/rbt_set.cpp b/deps/icu-small/source/i18n/rbt_set.cpp index 425e3e7258..f2c78ca9c8 100644 --- a/deps/icu-small/source/i18n/rbt_set.cpp +++ b/deps/icu-small/source/i18n/rbt_set.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 1999-2011, International Business Machines diff --git a/deps/icu-small/source/i18n/rbt_set.h b/deps/icu-small/source/i18n/rbt_set.h index cbf3419a97..ed76e6ddf7 100644 --- a/deps/icu-small/source/i18n/rbt_set.h +++ b/deps/icu-small/source/i18n/rbt_set.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 1999-2007, International Business Machines Corporation diff --git a/deps/icu-small/source/i18n/rbtz.cpp b/deps/icu-small/source/i18n/rbtz.cpp index 73fc480e1d..fb458dd502 100644 --- a/deps/icu-small/source/i18n/rbtz.cpp +++ b/deps/icu-small/source/i18n/rbtz.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2007-2013, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/regexcmp.cpp b/deps/icu-small/source/i18n/regexcmp.cpp index 8262cfaed4..d0e166cfa4 100644 --- a/deps/icu-small/source/i18n/regexcmp.cpp +++ b/deps/icu-small/source/i18n/regexcmp.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html // // file: regexcmp.cpp // @@ -2603,7 +2605,11 @@ void RegexCompile::findCaseInsensitiveStarters(UChar32 c, UnicodeSet *starterCh // End of machine generated data. - if (u_hasBinaryProperty(c, UCHAR_CASE_SENSITIVE)) { + if (c < UCHAR_MIN_VALUE || c > UCHAR_MAX_VALUE) { + // This function should never be called with an invalid input character. + U_ASSERT(FALSE); + starterChars->clear(); + } else if (u_hasBinaryProperty(c, UCHAR_CASE_SENSITIVE)) { UChar32 caseFoldedC = u_foldCase(c, U_FOLD_CASE_DEFAULT); starterChars->set(caseFoldedC, caseFoldedC); diff --git a/deps/icu-small/source/i18n/regexcmp.h b/deps/icu-small/source/i18n/regexcmp.h index 896de17f58..931f2387b5 100644 --- a/deps/icu-small/source/i18n/regexcmp.h +++ b/deps/icu-small/source/i18n/regexcmp.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html // // regexcmp.h // diff --git a/deps/icu-small/source/i18n/regexcst.h b/deps/icu-small/source/i18n/regexcst.h index 8e572e2120..259b44f5dd 100644 --- a/deps/icu-small/source/i18n/regexcst.h +++ b/deps/icu-small/source/i18n/regexcst.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html //--------------------------------------------------------------------------------- // // Generated Header File. Do not edit by hand. diff --git a/deps/icu-small/source/i18n/regexcst.pl b/deps/icu-small/source/i18n/regexcst.pl index c15d2868b2..6c06b4eb5f 100644..100755 --- a/deps/icu-small/source/i18n/regexcst.pl +++ b/deps/icu-small/source/i18n/regexcst.pl @@ -1,4 +1,6 @@ #!/usr/bin/perl +# Copyright (C) 2016 and later: Unicode, Inc. and others. +# License & terms of use: http://www.unicode.org/copyright.html # ******************************************************************** # * COPYRIGHT: # * Copyright (c) 2002-2016, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/regeximp.cpp b/deps/icu-small/source/i18n/regeximp.cpp index d923deb9e8..c1360ebf6c 100644 --- a/deps/icu-small/source/i18n/regeximp.cpp +++ b/deps/icu-small/source/i18n/regeximp.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html // // Copyright (C) 2012 International Business Machines Corporation // and others. All rights reserved. diff --git a/deps/icu-small/source/i18n/regeximp.h b/deps/icu-small/source/i18n/regeximp.h index c6c3b0d6ca..0261c58c63 100644 --- a/deps/icu-small/source/i18n/regeximp.h +++ b/deps/icu-small/source/i18n/regeximp.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html // // Copyright (C) 2002-2015 International Business Machines Corporation // and others. All rights reserved. diff --git a/deps/icu-small/source/i18n/regexst.cpp b/deps/icu-small/source/i18n/regexst.cpp index 1ef879e399..a8feffa1bd 100644 --- a/deps/icu-small/source/i18n/regexst.cpp +++ b/deps/icu-small/source/i18n/regexst.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html // // regexst.h // diff --git a/deps/icu-small/source/i18n/regexst.h b/deps/icu-small/source/i18n/regexst.h index 59faa4846b..21f7ec945c 100644 --- a/deps/icu-small/source/i18n/regexst.h +++ b/deps/icu-small/source/i18n/regexst.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html // // regexst.h // diff --git a/deps/icu-small/source/i18n/regextxt.cpp b/deps/icu-small/source/i18n/regextxt.cpp index 2156756a49..d6157f5ed6 100644 --- a/deps/icu-small/source/i18n/regextxt.cpp +++ b/deps/icu-small/source/i18n/regextxt.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /******************************************************************** * COPYRIGHT: * Copyright (c) 2008-2011, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/regextxt.h b/deps/icu-small/source/i18n/regextxt.h index 5b59838a92..c5651aefd4 100644 --- a/deps/icu-small/source/i18n/regextxt.h +++ b/deps/icu-small/source/i18n/regextxt.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /******************************************************************** * COPYRIGHT: * Copyright (c) 2008-2010, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/region.cpp b/deps/icu-small/source/i18n/region.cpp index 551960bfe8..fdd467fc98 100644 --- a/deps/icu-small/source/i18n/region.cpp +++ b/deps/icu-small/source/i18n/region.cpp @@ -1,6 +1,8 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* -* Copyright (C) 2014-2015, International Business Machines Corporation and +* Copyright (C) 2014-2016, International Business Machines Corporation and * others. All Rights Reserved. ******************************************************************************* * @@ -67,8 +69,7 @@ static UVector *allRegions = NULL; static const UChar UNKNOWN_REGION_ID [] = { 0x5A, 0x5A, 0 }; /* "ZZ" */ static const UChar OUTLYING_OCEANIA_REGION_ID [] = { 0x51, 0x4F, 0 }; /* "QO" */ static const UChar WORLD_ID [] = { 0x30, 0x30, 0x31, 0 }; /* "001" */ -static const UChar RANGE_MARKER [] = { 0x7e, 0 }; /* "~" */ -static const UnicodeString RANGE_MARKER_STRING(RANGE_MARKER); +static const UChar RANGE_MARKER = 0x7E; /* '~' */ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(RegionNameEnumeration) @@ -80,7 +81,7 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(RegionNameEnumeration) * If the region data has already loaded, then this method simply returns without doing * anything meaningful. */ -void Region::loadRegionData(UErrorCode &status) { +void U_CALLCONV Region::loadRegionData(UErrorCode &status) { // Construct service objs first LocalUHashtablePointer newRegionIDMap(uhash_open(uhash_hashUnicodeString, uhash_compareUnicodeString, NULL, &status)); @@ -121,7 +122,7 @@ void Region::loadRegionData(UErrorCode &status) { while ( ures_hasNext(regionRegular.getAlias()) ) { UnicodeString regionName = ures_getNextUnicodeString(regionRegular.getAlias(),NULL,&status); - int32_t rangeMarkerLocation = regionName.indexOf(RANGE_MARKER_STRING); + int32_t rangeMarkerLocation = regionName.indexOf(RANGE_MARKER); UChar buf[6]; regionName.extract(buf,6,status); if ( rangeMarkerLocation > 0 ) { @@ -140,7 +141,7 @@ void Region::loadRegionData(UErrorCode &status) { while ( ures_hasNext(regionMacro.getAlias()) ) { UnicodeString regionName = ures_getNextUnicodeString(regionMacro.getAlias(),NULL,&status); - int32_t rangeMarkerLocation = regionName.indexOf(RANGE_MARKER_STRING); + int32_t rangeMarkerLocation = regionName.indexOf(RANGE_MARKER); UChar buf[6]; regionName.extract(buf,6,status); if ( rangeMarkerLocation > 0 ) { diff --git a/deps/icu-small/source/i18n/region_impl.h b/deps/icu-small/source/i18n/region_impl.h index 2bd97f6105..852209603b 100644 --- a/deps/icu-small/source/i18n/region_impl.h +++ b/deps/icu-small/source/i18n/region_impl.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2013, International Business Machines Corporation and * diff --git a/deps/icu-small/source/i18n/reldatefmt.cpp b/deps/icu-small/source/i18n/reldatefmt.cpp index 29f760e0e8..7009b190a2 100644 --- a/deps/icu-small/source/i18n/reldatefmt.cpp +++ b/deps/icu-small/source/i18n/reldatefmt.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * Copyright (C) 2014-2016, International Business Machines Corporation and @@ -178,14 +180,11 @@ namespace { /** * Sink for enumerating all of the measurement unit display names. - * Contains inner sink classes, each one corresponding to a level of the resource table. * * More specific bundles (en_GB) are enumerated before their parents (en_001, en, root): * Only store a value if it is still missing, that is, it has not been overridden. - * - * C++: Each inner sink class has a reference to the main outer sink. */ -struct RelDateTimeFmtDataSink : public ResourceTableSink { +struct RelDateTimeFmtDataSink : public ResourceSink { /** * Sink for patterns for relative dates and times. For example, @@ -291,188 +290,16 @@ struct RelDateTimeFmtDataSink : public ResourceTableSink { return -1; } - // Sinks for additional levels under /fields/*/relative/ and /fields/*/relativeTime/ - - /** - * Make list of simplePatternFmtList, for past and for future. - * Set a SimpleFormatter for the <style, relative unit, plurality> - * - * Fill in values for the particular plural given, e.g., ONE, FEW, OTHER, etc. - */ - struct RelDateTimeDetailSink : public ResourceTableSink { - RelDateTimeDetailSink(RelDateTimeFmtDataSink &sink) : outer(sink) {} - ~RelDateTimeDetailSink(); - - virtual void put(const char *key, const ResourceValue &value, - UErrorCode &errorCode) { - if (U_FAILURE(errorCode)) { return; } - - outer.relUnitIndex = relUnitFromGeneric(outer.genericUnit); - if (outer.relUnitIndex < 0) { - return; - } - - /* Make two lists of simplePatternFmtList, one for past and one for future. - * Set a SimpleFormatter pattern for the <style, relative unit, plurality> - * - * Fill in values for the particular plural given, e.g., ONE, FEW, OTHER, etc. - */ - int32_t pluralIndex = StandardPlural::indexOrNegativeFromString(key); - if (pluralIndex >= 0) { - SimpleFormatter **patterns = - outer.outputData.relativeUnitsFormatters[outer.style][outer.relUnitIndex] - [outer.pastFutureIndex]; - // Only set if not already established. - if (patterns[pluralIndex] == NULL) { - patterns[pluralIndex] = new SimpleFormatter( - value.getUnicodeString(errorCode), 0, 1, errorCode); - if (patterns[pluralIndex] == NULL) { - errorCode = U_MEMORY_ALLOCATION_ERROR; - } - } - } - } - - RelDateTimeFmtDataSink &outer; - } relDateTimeDetailSink; - - /* - * Handles "relativeTime" entries, e.g., under "day", "hour", "minute", - * "minute-short", etc. - */ - struct RelativeTimeSink : public ResourceTableSink { - RelativeTimeSink(RelDateTimeFmtDataSink &sink) : outer(sink) {} - ~RelativeTimeSink(); - - virtual ResourceTableSink *getOrCreateTableSink( - const char *key, int32_t /* initialSize */, UErrorCode& errorCode) { - if (U_FAILURE(errorCode)) { return NULL; } - outer.relUnitIndex = relUnitFromGeneric(outer.genericUnit); - if (outer.relUnitIndex < 0) { - return NULL; - } - - if (uprv_strcmp(key, "past") == 0) { - outer.pastFutureIndex = 0; - } else if (uprv_strcmp(key, "future") == 0) { - outer.pastFutureIndex = 1; - } else { - // Unknown key. - return NULL; - } - return &outer.relDateTimeDetailSink; - } - - RelDateTimeFmtDataSink &outer; - } relativeTimeSink; - - /* - * Handles "relative" entries, e.g., under "day", "day-short", "fri", - * "fri-narrow", "fri-short", etc. - */ - struct RelativeSink : public ResourceTableSink { - RelativeSink(RelDateTimeFmtDataSink &sink) : outer(sink) {} - ~RelativeSink(); - - virtual void put(const char *key, const ResourceValue &value, UErrorCode &errorCode) { - if (U_FAILURE(errorCode)) { return; } - int32_t direction = keyToDirection(key); - if (direction < 0) { - return; - } - - int32_t relUnitIndex = relUnitFromGeneric(outer.genericUnit); - if (relUnitIndex == UDAT_RELATIVE_SECONDS && - direction == UDAT_DIRECTION_THIS && - outer.outputData.absoluteUnits[outer.style][UDAT_ABSOLUTE_NOW] - [UDAT_DIRECTION_PLAIN].isEmpty()) { - // Handle "NOW" - outer.outputData.absoluteUnits[outer.style][UDAT_ABSOLUTE_NOW] - [UDAT_DIRECTION_PLAIN].fastCopyFrom(value.getUnicodeString(errorCode)); - } - - int32_t absUnitIndex = absUnitFromGeneric(outer.genericUnit); - if (absUnitIndex < 0) { - return; - } - // Only reset if slot is empty. - if (outer.outputData.absoluteUnits[outer.style][absUnitIndex][direction].isEmpty()) { - outer.outputData.absoluteUnits[outer.style][absUnitIndex] - [direction].fastCopyFrom(value.getUnicodeString(errorCode)); - } - } - - RelDateTimeFmtDataSink &outer; - } relativeSink; - - /* - * Handles entries under "fields", recognizing "relative" and "relativeTime" entries. - */ - struct UnitSink : public ResourceTableSink { - UnitSink(RelDateTimeFmtDataSink &sink) : outer(sink) {} - ~UnitSink(); - - virtual void put(const char *key, const ResourceValue &value, UErrorCode &errorCode) { - if (U_FAILURE(errorCode)) { return; } - if (uprv_strcmp(key, "dn") != 0) { - return; - } - - // Handle Display Name for PLAIN direction for some units. - int32_t absUnit = absUnitFromGeneric(outer.genericUnit); - if (absUnit < 0) { - return; // Not interesting. - } - - // TODO(Travis Keep): This is a hack to get around CLDR bug 6818. - UnicodeString displayName = value.getUnicodeString(errorCode); - if (U_SUCCESS(errorCode)) { - if (uprv_strcmp("en", outer.sinkLocaleId) == 0) { - displayName.toLower(); - } - } - // end hack - - // Store displayname if not set. - if (outer.outputData.absoluteUnits[outer.style] - [absUnit][UDAT_DIRECTION_PLAIN].isEmpty()) { - outer.outputData.absoluteUnits[outer.style] - [absUnit][UDAT_DIRECTION_PLAIN].fastCopyFrom(displayName); - return; - } - } - - virtual ResourceTableSink *getOrCreateTableSink( - const char *key, int32_t /* initialSize */, UErrorCode &errorCode) { - if (U_FAILURE(errorCode)) { return NULL; } - if (uprv_strcmp(key, "relative") == 0) { - return &outer.relativeSink; - } else if (uprv_strcmp(key, "relativeTime") == 0) { - return &outer.relativeTimeSink; - } - return NULL; - } - - RelDateTimeFmtDataSink &outer; - } unitSink; - - // For hack for locale "en". - // TODO(Travis Keep): This is a hack to get around CLDR bug 6818. - const char* sinkLocaleId; - // Values kept between levels of parsing the CLDR data. int32_t pastFutureIndex; // 0 == past or 1 == future UDateRelativeDateTimeFormatterStyle style; // {LONG, SHORT, NARROW} RelAbsUnit genericUnit; - int32_t relUnitIndex; - int32_t absUnitIndex; RelativeDateTimeCacheData &outputData; // Constructor - RelDateTimeFmtDataSink(RelativeDateTimeCacheData& cacheData, const char* localeId) - : relDateTimeDetailSink(*this), relativeTimeSink(*this), relativeSink(*this), - unitSink(*this), sinkLocaleId(localeId), outputData(cacheData) { + RelDateTimeFmtDataSink(RelativeDateTimeCacheData& cacheData) + : outputData(cacheData) { // Clear cacheData.fallBackCache cacheData.fallBackCache[UDAT_STYLE_LONG] = -1; cacheData.fallBackCache[UDAT_STYLE_SHORT] = -1; @@ -571,55 +398,165 @@ struct RelDateTimeFmtDataSink : public ResourceTableSink { return INVALID_UNIT; } - // Member functions of top level sink. - virtual void put(const char *key, const ResourceValue &value, UErrorCode &errorCode) { - // Only handle aliases, storing information about alias fallback. + void handlePlainDirection(ResourceValue &value, UErrorCode &errorCode) { + // Handle Display Name for PLAIN direction for some units. + if (U_FAILURE(errorCode)) { return; } + + int32_t absUnit = absUnitFromGeneric(genericUnit); + if (absUnit < 0) { + return; // Not interesting. + } + + // Store displayname if not set. + if (outputData.absoluteUnits[style] + [absUnit][UDAT_DIRECTION_PLAIN].isEmpty()) { + outputData.absoluteUnits[style] + [absUnit][UDAT_DIRECTION_PLAIN].fastCopyFrom(value.getUnicodeString(errorCode)); + return; + } + } + + void consumeTableRelative(const char *key, ResourceValue &value, UErrorCode &errorCode) { + ResourceTable unitTypesTable = value.getTable(errorCode); + if (U_FAILURE(errorCode)) { return; } + + for (int32_t i = 0; unitTypesTable.getKeyAndValue(i, key, value); ++i) { + if (value.getType() == URES_STRING) { + int32_t direction = keyToDirection(key); + if (direction < 0) { + continue; + } - if (U_SUCCESS(errorCode)) { - if (value.getType() != URES_ALIAS) { - return; + int32_t relUnitIndex = relUnitFromGeneric(genericUnit); + if (relUnitIndex == UDAT_RELATIVE_SECONDS && uprv_strcmp(key, "0") == 0 && + outputData.absoluteUnits[style][UDAT_ABSOLUTE_NOW][UDAT_DIRECTION_PLAIN].isEmpty()) { + // Handle "NOW" + outputData.absoluteUnits[style][UDAT_ABSOLUTE_NOW] + [UDAT_DIRECTION_PLAIN].fastCopyFrom(value.getUnicodeString(errorCode)); + } + + int32_t absUnitIndex = absUnitFromGeneric(genericUnit); + if (absUnitIndex < 0) { + continue; + } + // Only reset if slot is empty. + if (outputData.absoluteUnits[style][absUnitIndex][direction].isEmpty()) { + outputData.absoluteUnits[style][absUnitIndex] + [direction].fastCopyFrom(value.getUnicodeString(errorCode)); + } } - const UnicodeString valueStr = value.getAliasUnicodeString(errorCode); - if (U_SUCCESS(errorCode)) { - UDateRelativeDateTimeFormatterStyle sourceStyle= styleFromString(key); - UDateRelativeDateTimeFormatterStyle targetStyle = - styleFromAliasUnicodeString(valueStr); - - if (sourceStyle == targetStyle) { - errorCode = U_INVALID_FORMAT_ERROR; - return; + } + } + + void consumeTimeDetail(int32_t relUnitIndex, + const char *key, ResourceValue &value, UErrorCode &errorCode) { + ResourceTable unitTypesTable = value.getTable(errorCode); + if (U_FAILURE(errorCode)) { return; } + + for (int32_t i = 0; unitTypesTable.getKeyAndValue(i, key, value); ++i) { + if (value.getType() == URES_STRING) { + int32_t pluralIndex = StandardPlural::indexOrNegativeFromString(key); + if (pluralIndex >= 0) { + SimpleFormatter **patterns = + outputData.relativeUnitsFormatters[style][relUnitIndex] + [pastFutureIndex]; + // Only set if not already established. + if (patterns[pluralIndex] == NULL) { + patterns[pluralIndex] = new SimpleFormatter( + value.getUnicodeString(errorCode), 0, 1, errorCode); + if (patterns[pluralIndex] == NULL) { + errorCode = U_MEMORY_ALLOCATION_ERROR; + } + } } - if (outputData.fallBackCache[sourceStyle] != -1 && - outputData.fallBackCache[sourceStyle] != targetStyle) { - errorCode = U_INVALID_FORMAT_ERROR; - return; + } + } + } + + void consumeTableRelativeTime(const char *key, ResourceValue &value, UErrorCode &errorCode) { + ResourceTable relativeTimeTable = value.getTable(errorCode); + if (U_FAILURE(errorCode)) { return; } + + int32_t relUnitIndex = relUnitFromGeneric(genericUnit); + if (relUnitIndex < 0) { + return; + } + for (int32_t i = 0; relativeTimeTable.getKeyAndValue(i, key, value); ++i) { + if (uprv_strcmp(key, "past") == 0) { + pastFutureIndex = 0; + } else if (uprv_strcmp(key, "future") == 0) { + pastFutureIndex = 1; + } else { + // Unknown key. + continue; + } + consumeTimeDetail(relUnitIndex, key, value, errorCode); + } + } + + void consumeAlias(const char *key, const ResourceValue &value, UErrorCode &errorCode) { + + UDateRelativeDateTimeFormatterStyle sourceStyle = styleFromString(key); + const UnicodeString valueStr = value.getAliasUnicodeString(errorCode); + if (U_FAILURE(errorCode)) { return; } + + UDateRelativeDateTimeFormatterStyle targetStyle = + styleFromAliasUnicodeString(valueStr); + + if (sourceStyle == targetStyle) { + errorCode = U_INVALID_FORMAT_ERROR; + return; + } + if (outputData.fallBackCache[sourceStyle] != -1 && + outputData.fallBackCache[sourceStyle] != targetStyle) { + errorCode = U_INVALID_FORMAT_ERROR; + return; + } + outputData.fallBackCache[sourceStyle] = targetStyle; + } + + void consumeTimeUnit(const char *key, ResourceValue &value, UErrorCode &errorCode) { + ResourceTable unitTypesTable = value.getTable(errorCode); + if (U_FAILURE(errorCode)) { return; } + + for (int32_t i = 0; unitTypesTable.getKeyAndValue(i, key, value); ++i) { + // Handle display name. + if (uprv_strcmp(key, "dn") == 0 && value.getType() == URES_STRING) { + handlePlainDirection(value, errorCode); + } + if (value.getType() == URES_TABLE) { + if (uprv_strcmp(key, "relative") == 0) { + consumeTableRelative(key, value, errorCode); + } else if (uprv_strcmp(key, "relativeTime") == 0) { + consumeTableRelativeTime(key, value, errorCode); } - outputData.fallBackCache[sourceStyle] = targetStyle; } } - return; } - // Top level sink - virtual ResourceTableSink *getOrCreateTableSink( - const char *key, int32_t /* initialSize */, UErrorCode& /* errorCode */) { - style= styleFromString(key); - int32_t unitSize = uprv_strlen(key) - styleSuffixLength(style); - genericUnit = unitOrNegativeFromString(key, unitSize); - if (style < 0 || genericUnit == INVALID_UNIT) { - return NULL; - } - return &unitSink; + virtual void put(const char *key, ResourceValue &value, + UBool /*noFallback*/, UErrorCode &errorCode) { + // Main entry point to sink + ResourceTable table = value.getTable(errorCode); + if (U_FAILURE(errorCode)) { return; } + for (int32_t i = 0; table.getKeyAndValue(i, key, value); ++i) { + if (value.getType() == URES_ALIAS) { + consumeAlias(key, value, errorCode); + } else { + style = styleFromString(key); + int32_t unitSize = uprv_strlen(key) - styleSuffixLength(style); + genericUnit = unitOrNegativeFromString(key, unitSize); + if (style >= 0 && genericUnit != INVALID_UNIT) { + consumeTimeUnit(key, value, errorCode); + } + } + } } + }; // Virtual destructors must be defined out of line. -RelDateTimeFmtDataSink::RelDateTimeDetailSink::~RelDateTimeDetailSink() {} -RelDateTimeFmtDataSink::RelativeTimeSink::~RelativeTimeSink() {} -RelDateTimeFmtDataSink::RelativeSink::~RelativeSink() {} -RelDateTimeFmtDataSink::UnitSink::~UnitSink() {} RelDateTimeFmtDataSink::~RelDateTimeFmtDataSink() {} - } // namespace DateFormatSymbols::DtWidthType styleToDateFormatSymbolWidth[UDAT_STYLE_COUNT] = { @@ -652,8 +589,10 @@ static UBool loadUnitData( RelativeDateTimeCacheData &cacheData, const char* localeId, UErrorCode &status) { - RelDateTimeFmtDataSink sink(cacheData, localeId); - ures_getAllTableItemsWithFallback(resource, "fields", sink, status); + + RelDateTimeFmtDataSink sink(cacheData); + + ures_getAllItemsWithFallback(resource, "fields", sink, status); // Get the weekday names from DateFormatSymbols. loadWeekdayNames(cacheData.absoluteUnits, localeId, status); diff --git a/deps/icu-small/source/i18n/reldtfmt.cpp b/deps/icu-small/source/i18n/reldtfmt.cpp index 7055e724bb..4a92869535 100644 --- a/deps/icu-small/source/i18n/reldtfmt.cpp +++ b/deps/icu-small/source/i18n/reldtfmt.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2007-2016, International Business Machines Corporation and @@ -11,15 +13,15 @@ #include <stdlib.h> -#include "reldtfmt.h" #include "unicode/datefmt.h" +#include "unicode/reldatefmt.h" #include "unicode/simpleformatter.h" #include "unicode/smpdtfmt.h" #include "unicode/udisplaycontext.h" #include "unicode/uchar.h" #include "unicode/brkiter.h" -#include "gregoimp.h" // for CalendarData +#include "reldtfmt.h" #include "cmemory.h" #include "uresimp.h" @@ -35,16 +37,12 @@ struct URelativeString { const UChar* string; /** string, or NULL if not set **/ }; -static const char DT_DateTimePatternsTag[]="DateTimePatterns"; - - UOBJECT_DEFINE_RTTI_IMPLEMENTATION(RelativeDateFormat) RelativeDateFormat::RelativeDateFormat(const RelativeDateFormat& other) : DateFormat(other), fDateTimeFormatter(NULL), fDatePattern(other.fDatePattern), fTimePattern(other.fTimePattern), fCombinedFormat(NULL), fDateStyle(other.fDateStyle), fLocale(other.fLocale), - fDayMin(other.fDayMin), fDayMax(other.fDayMax), fDatesLen(other.fDatesLen), fDates(NULL), fCombinedHasDateAtStart(other.fCombinedHasDateAtStart), fCapitalizationInfoSet(other.fCapitalizationInfoSet), @@ -59,8 +57,8 @@ RelativeDateFormat::RelativeDateFormat(const RelativeDateFormat& other) : fCombinedFormat = new SimpleFormatter(*other.fCombinedFormat); } if (fDatesLen > 0) { - fDates = (URelativeString*) uprv_malloc(sizeof(fDates[0])*fDatesLen); - uprv_memcpy(fDates, other.fDates, sizeof(fDates[0])*fDatesLen); + fDates = (URelativeString*) uprv_malloc(sizeof(fDates[0])*(size_t)fDatesLen); + uprv_memcpy(fDates, other.fDates, sizeof(fDates[0])*(size_t)fDatesLen); } #if !UCONFIG_NO_BREAK_ITERATION if (other.fCapitalizationBrkIter != NULL) { @@ -72,7 +70,7 @@ RelativeDateFormat::RelativeDateFormat(const RelativeDateFormat& other) : RelativeDateFormat::RelativeDateFormat( UDateFormatStyle timeStyle, UDateFormatStyle dateStyle, const Locale& locale, UErrorCode& status) : DateFormat(), fDateTimeFormatter(NULL), fDatePattern(), fTimePattern(), fCombinedFormat(NULL), - fDateStyle(dateStyle), fLocale(locale), fDayMin(0), fDayMax(0), fDatesLen(0), fDates(NULL), + fDateStyle(dateStyle), fLocale(locale), fDatesLen(0), fDates(NULL), fCombinedHasDateAtStart(FALSE), fCapitalizationInfoSet(FALSE), fCapitalizationOfRelativeUnitsForUIListMenu(FALSE), fCapitalizationOfRelativeUnitsForStandAlone(FALSE), fCapitalizationBrkIter(NULL) @@ -112,6 +110,7 @@ RelativeDateFormat::RelativeDateFormat( UDateFormatStyle timeStyle, UDateFormatS fDateTimeFormatter=dynamic_cast<SimpleDateFormat *>(df); if (fDateTimeFormatter == NULL) { status = U_UNSUPPORTED_ERROR; + delete df; return; } fDateTimeFormatter->toPattern(fTimePattern); @@ -353,19 +352,14 @@ const UChar *RelativeDateFormat::getStringForDay(int32_t day, int32_t &len, UErr return NULL; } - // Is it outside the resource bundle's range? - if(day < fDayMin || day > fDayMax) { - return NULL; // don't have it. - } - - // Linear search the held strings - for(int n=0;n<fDatesLen;n++) { - if(fDates[n].offset == day) { + // Is it inside the resource bundle's range? + int n = day + UDAT_DIRECTION_THIS; + if (n >= 0 && n < fDatesLen) { + if (fDates[n].offset == day && fDates[n].string != NULL) { len = fDates[n].len; return fDates[n].string; } } - return NULL; // not found. } @@ -453,125 +447,114 @@ RelativeDateFormat::initCapitalizationContextInfo(const Locale& thelocale) #if !UCONFIG_NO_BREAK_ITERATION const char * localeID = (thelocale != NULL)? thelocale.getBaseName(): NULL; UErrorCode status = U_ZERO_ERROR; - UResourceBundle *rb = ures_open(NULL, localeID, &status); - rb = ures_getByKeyWithFallback(rb, "contextTransforms", rb, &status); - rb = ures_getByKeyWithFallback(rb, "relative", rb, &status); + LocalUResourceBundlePointer rb(ures_open(NULL, localeID, &status)); + ures_getByKeyWithFallback(rb.getAlias(), + "contextTransforms/relative", + rb.getAlias(), &status); if (U_SUCCESS(status) && rb != NULL) { int32_t len = 0; - const int32_t * intVector = ures_getIntVector(rb, &len, &status); + const int32_t * intVector = ures_getIntVector(rb.getAlias(), + &len, &status); if (U_SUCCESS(status) && intVector != NULL && len >= 2) { fCapitalizationOfRelativeUnitsForUIListMenu = intVector[0]; fCapitalizationOfRelativeUnitsForStandAlone = intVector[1]; } } - ures_close(rb); #endif } +namespace { + +/** + * Sink for getting data from fields/day/relative data. + * For loading relative day names, e.g., "yesterday", "today". + */ + +struct RelDateFmtDataSink : public ResourceSink { + URelativeString *fDatesPtr; + int32_t fDatesLen; + + RelDateFmtDataSink(URelativeString* fDates, int32_t len) : fDatesPtr(fDates), fDatesLen(len) { + for (int32_t i = 0; i < fDatesLen; ++i) { + fDatesPtr[i].offset = 0; + fDatesPtr[i].string = NULL; + fDatesPtr[i].len = -1; + } + } + + virtual ~RelDateFmtDataSink(); + + virtual void put(const char *key, ResourceValue &value, + UBool /*noFallback*/, UErrorCode &errorCode) { + ResourceTable relDayTable = value.getTable(errorCode); + int32_t n = 0; + int32_t len = 0; + for (int32_t i = 0; relDayTable.getKeyAndValue(i, key, value); ++i) { + // Find the relative offset. + int32_t offset = atoi(key); + + // Put in the proper spot, but don't override existing data. + n = offset + UDAT_DIRECTION_THIS; // Converts to index in UDAT_R + if (n < fDatesLen && fDatesPtr[n].string == NULL) { + // Not found and n is an empty slot. + fDatesPtr[n].offset = offset; + fDatesPtr[n].string = value.getString(len, errorCode); + fDatesPtr[n].len = len; + } + } + } +}; + + +// Virtual destructors must be defined out of line. +RelDateFmtDataSink::~RelDateFmtDataSink() {} + +} // Namespace + + static const UChar patItem1[] = {0x7B,0x31,0x7D}; // "{1}" static const int32_t patItem1Len = 3; void RelativeDateFormat::loadDates(UErrorCode &status) { - CalendarData calData(fLocale, "gregorian", status); - - UErrorCode tempStatus = status; - UResourceBundle *dateTimePatterns = calData.getByKey(DT_DateTimePatternsTag, tempStatus); - if(U_SUCCESS(tempStatus)) { - int32_t patternsSize = ures_getSize(dateTimePatterns); + UResourceBundle *rb = ures_open(NULL, fLocale.getBaseName(), &status); + LocalUResourceBundlePointer dateTimePatterns( + ures_getByKeyWithFallback(rb, + "calendar/gregorian/DateTimePatterns", + (UResourceBundle*)NULL, &status)); + if(U_SUCCESS(status)) { + int32_t patternsSize = ures_getSize(dateTimePatterns.getAlias()); if (patternsSize > kDateTime) { int32_t resStrLen = 0; - int32_t glueIndex = kDateTime; - if (patternsSize >= (DateFormat::kDateTimeOffset + DateFormat::kShort + 1)) { - // Get proper date time format - switch (fDateStyle) { - case kFullRelative: - case kFull: - glueIndex = kDateTimeOffset + kFull; - break; - case kLongRelative: - case kLong: - glueIndex = kDateTimeOffset + kLong; - break; - case kMediumRelative: - case kMedium: - glueIndex = kDateTimeOffset + kMedium; - break; - case kShortRelative: - case kShort: - glueIndex = kDateTimeOffset + kShort; - break; - default: - break; + if (patternsSize >= (kDateTimeOffset + kShort + 1)) { + int32_t offsetIncrement = (fDateStyle & ~kRelative); // Remove relative bit. + if (offsetIncrement >= (int32_t)kFull && + offsetIncrement <= (int32_t)kShortRelative) { + glueIndex = kDateTimeOffset + offsetIncrement; } } - const UChar *resStr = ures_getStringByIndex(dateTimePatterns, glueIndex, &resStrLen, &tempStatus); - if (U_SUCCESS(tempStatus) && resStrLen >= patItem1Len && u_strncmp(resStr,patItem1,patItem1Len)==0) { + const UChar *resStr = ures_getStringByIndex(dateTimePatterns.getAlias(), glueIndex, &resStrLen, &status); + if (U_SUCCESS(status) && resStrLen >= patItem1Len && u_strncmp(resStr,patItem1,patItem1Len)==0) { fCombinedHasDateAtStart = TRUE; } - fCombinedFormat = new SimpleFormatter(UnicodeString(TRUE, resStr, resStrLen), 2, 2, tempStatus); + fCombinedFormat = new SimpleFormatter(UnicodeString(TRUE, resStr, resStrLen), 2, 2, status); } } - UResourceBundle *rb = ures_open(NULL, fLocale.getBaseName(), &status); - rb = ures_getByKeyWithFallback(rb, "fields", rb, &status); - rb = ures_getByKeyWithFallback(rb, "day", rb, &status); - rb = ures_getByKeyWithFallback(rb, "relative", rb, &status); - // set up min/max - fDayMin=-1; - fDayMax=1; - - if(U_FAILURE(status)) { - fDatesLen=0; - ures_close(rb); - return; - } - - fDatesLen = ures_getSize(rb); + // Data loading for relative names, e.g., "yesterday", "today", "tomorrow". + fDatesLen = UDAT_DIRECTION_COUNT; // Maximum defined by data. fDates = (URelativeString*) uprv_malloc(sizeof(fDates[0])*fDatesLen); - // Load in each item into the array... - int n = 0; - - UResourceBundle *subString = NULL; - - while(ures_hasNext(rb) && U_SUCCESS(status)) { // iterate over items - subString = ures_getNextResource(rb, subString, &status); - - if(U_FAILURE(status) || (subString==NULL)) break; - - // key = offset # - const char *key = ures_getKey(subString); - - // load the string and length - int32_t aLen; - const UChar* aString = ures_getString(subString, &aLen, &status); + RelDateFmtDataSink sink(fDates, fDatesLen); + ures_getAllItemsWithFallback(rb, "fields/day/relative", sink, status); - if(U_FAILURE(status) || aString == NULL) break; - - // calculate the offset - int32_t offset = atoi(key); - - // set min/max - if(offset < fDayMin) { - fDayMin = offset; - } - if(offset > fDayMax) { - fDayMax = offset; - } - - // copy the string pointer - fDates[n].offset = offset; - fDates[n].string = aString; - fDates[n].len = aLen; - - n++; - } - ures_close(subString); ures_close(rb); - // the fDates[] array could be sorted here, for direct access. + if(U_FAILURE(status)) { + fDatesLen=0; + return; + } } //---------------------------------------------------------------------- @@ -609,4 +592,4 @@ int32_t RelativeDateFormat::dayDifference(Calendar &cal, UErrorCode &status) { U_NAMESPACE_END -#endif +#endif /* !UCONFIG_NO_FORMATTING */ diff --git a/deps/icu-small/source/i18n/reldtfmt.h b/deps/icu-small/source/i18n/reldtfmt.h index f82855c357..ea091a91c3 100644 --- a/deps/icu-small/source/i18n/reldtfmt.h +++ b/deps/icu-small/source/i18n/reldtfmt.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2007-2016, International Business Machines Corporation and * @@ -255,8 +257,6 @@ private: UDateFormatStyle fDateStyle; Locale fLocale; - int32_t fDayMin; // day id of lowest # - int32_t fDayMax; // day id of highest # int32_t fDatesLen; // Length of array URelativeString *fDates; // array of strings @@ -264,7 +264,11 @@ private: UBool fCapitalizationInfoSet; UBool fCapitalizationOfRelativeUnitsForUIListMenu; UBool fCapitalizationOfRelativeUnitsForStandAlone; +#if !UCONFIG_NO_BREAK_ITERATION BreakIterator* fCapitalizationBrkIter; +#else + UObject* fCapitalizationBrkIter; +#endif /** * Get the string at a specific offset. @@ -333,4 +337,3 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */ #endif // RELDTFMT_H -//eof diff --git a/deps/icu-small/source/i18n/rematch.cpp b/deps/icu-small/source/i18n/rematch.cpp index 348fd45d22..5a5bb80e05 100644 --- a/deps/icu-small/source/i18n/rematch.cpp +++ b/deps/icu-small/source/i18n/rematch.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ************************************************************************** * Copyright (C) 2002-2016 International Business Machines Corporation diff --git a/deps/icu-small/source/i18n/remtrans.cpp b/deps/icu-small/source/i18n/remtrans.cpp index 4ee98f7d3c..89837f991d 100644 --- a/deps/icu-small/source/i18n/remtrans.cpp +++ b/deps/icu-small/source/i18n/remtrans.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2001-2011, International Business Machines diff --git a/deps/icu-small/source/i18n/remtrans.h b/deps/icu-small/source/i18n/remtrans.h index 25a5609dff..a5635781f9 100644 --- a/deps/icu-small/source/i18n/remtrans.h +++ b/deps/icu-small/source/i18n/remtrans.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2001-2007, International Business Machines diff --git a/deps/icu-small/source/i18n/repattrn.cpp b/deps/icu-small/source/i18n/repattrn.cpp index bf69dbb66f..b792ca0484 100644 --- a/deps/icu-small/source/i18n/repattrn.cpp +++ b/deps/icu-small/source/i18n/repattrn.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html // // file: repattrn.cpp // diff --git a/deps/icu-small/source/i18n/rulebasedcollator.cpp b/deps/icu-small/source/i18n/rulebasedcollator.cpp index 758c65769c..4852667ada 100644 --- a/deps/icu-small/source/i18n/rulebasedcollator.cpp +++ b/deps/icu-small/source/i18n/rulebasedcollator.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 1996-2015, International Business Machines @@ -1609,7 +1611,7 @@ RuleBasedCollator::isUnsafe(UChar32 c) const { return data->isUnsafeBackward(c, settings->isNumeric()); } -void +void U_CALLCONV RuleBasedCollator::computeMaxExpansions(const CollationTailoring *t, UErrorCode &errorCode) { t->maxExpansions = CollationElementIterator::computeMaxExpansions(t->data, errorCode); } diff --git a/deps/icu-small/source/i18n/scientificnumberformatter.cpp b/deps/icu-small/source/i18n/scientificnumberformatter.cpp index b3bc09939c..56a43f9b7f 100644 --- a/deps/icu-small/source/i18n/scientificnumberformatter.cpp +++ b/deps/icu-small/source/i18n/scientificnumberformatter.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2014, International Business Machines diff --git a/deps/icu-small/source/i18n/scriptset.cpp b/deps/icu-small/source/i18n/scriptset.cpp index c20a55d00b..ab7cb1e68e 100644 --- a/deps/icu-small/source/i18n/scriptset.cpp +++ b/deps/icu-small/source/i18n/scriptset.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2014, International Business Machines @@ -191,6 +193,15 @@ int32_t ScriptSet::nextSetBit(int32_t fromIndex) const { return -1; } +UBool ScriptSet::isEmpty() const { + for (uint32_t i=0; i<UPRV_LENGTHOF(bits); i++) { + if (bits[i] != 0) { + return FALSE; + } + } + return TRUE; +} + UnicodeString &ScriptSet::displayScripts(UnicodeString &dest) const { UBool firstTime = TRUE; for (int32_t i = nextSetBit(0); i >= 0; i = nextSetBit(i + 1)) { @@ -238,6 +249,41 @@ ScriptSet &ScriptSet::parseScripts(const UnicodeString &scriptString, UErrorCode return *this; } +void ScriptSet::setScriptExtensions(UChar32 codePoint, UErrorCode& status) { + if (U_FAILURE(status)) { return; } + static const int32_t FIRST_GUESS_SCRIPT_CAPACITY = 5; + MaybeStackArray<UScriptCode,FIRST_GUESS_SCRIPT_CAPACITY> scripts; + UErrorCode internalStatus = U_ZERO_ERROR; + int32_t script_count = -1; + + while (TRUE) { + script_count = uscript_getScriptExtensions( + codePoint, scripts.getAlias(), FIRST_GUESS_SCRIPT_CAPACITY, &internalStatus); + if (internalStatus == U_BUFFER_OVERFLOW_ERROR) { + // Need to allocate more space + if (scripts.resize(script_count) == NULL) { + status = U_MEMORY_ALLOCATION_ERROR; + return; + } + internalStatus = U_ZERO_ERROR; + } else { + break; + } + } + + // Check if we failed for some reason other than buffer overflow + if (U_FAILURE(internalStatus)) { + status = internalStatus; + return; + } + + // Load the scripts into the ScriptSet and return + for (int32_t i = 0; i < script_count; i++) { + this->set(scripts[i], status); + if (U_FAILURE(status)) { return; } + } +} + U_NAMESPACE_END U_CAPI UBool U_EXPORT2 diff --git a/deps/icu-small/source/i18n/scriptset.h b/deps/icu-small/source/i18n/scriptset.h index 62af5d591d..e8de3b9613 100644 --- a/deps/icu-small/source/i18n/scriptset.h +++ b/deps/icu-small/source/i18n/scriptset.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2013, International Business Machines @@ -38,6 +40,7 @@ class U_I18N_API ScriptSet: public UMemory { ~ScriptSet(); UBool operator == (const ScriptSet &other) const; + UBool operator != (const ScriptSet &other) const {return !(*this == other);}; ScriptSet & operator = (const ScriptSet &other); UBool test(UScriptCode script, UErrorCode &status) const; @@ -55,9 +58,14 @@ class U_I18N_API ScriptSet: public UMemory { int32_t hashCode() const; int32_t nextSetBit(int32_t script) const; + UBool isEmpty() const; + UnicodeString &displayScripts(UnicodeString &dest) const; // append script names to dest string. ScriptSet & parseScripts(const UnicodeString &scriptsString, UErrorCode &status); // Replaces ScriptSet contents. + // Wraps around UScript::getScriptExtensions() and adds the corresponding scripts to this instance. + void setScriptExtensions(UChar32 codePoint, UErrorCode& status); + private: uint32_t bits[6]; }; diff --git a/deps/icu-small/source/i18n/search.cpp b/deps/icu-small/source/i18n/search.cpp index 8d2de67974..77323cc664 100644 --- a/deps/icu-small/source/i18n/search.cpp +++ b/deps/icu-small/source/i18n/search.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2001-2008,2010 IBM and others. All rights reserved. diff --git a/deps/icu-small/source/i18n/selfmt.cpp b/deps/icu-small/source/i18n/selfmt.cpp index 5016e8e30a..041fea515c 100644 --- a/deps/icu-small/source/i18n/selfmt.cpp +++ b/deps/icu-small/source/i18n/selfmt.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /******************************************************************** * COPYRIGHT: * Copyright (c) 1997-2012, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/selfmtimpl.h b/deps/icu-small/source/i18n/selfmtimpl.h index 0263844871..75bc3e343a 100644 --- a/deps/icu-small/source/i18n/selfmtimpl.h +++ b/deps/icu-small/source/i18n/selfmtimpl.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /******************************************************************** * COPYRIGHT: * Copyright (c) 1997-2011, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/sharedbreakiterator.cpp b/deps/icu-small/source/i18n/sharedbreakiterator.cpp index 430dfba1cc..ca962c6283 100644 --- a/deps/icu-small/source/i18n/sharedbreakiterator.cpp +++ b/deps/icu-small/source/i18n/sharedbreakiterator.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2013-2014, International Business Machines Corporation and * diff --git a/deps/icu-small/source/i18n/sharedbreakiterator.h b/deps/icu-small/source/i18n/sharedbreakiterator.h index 09ba4312a3..58be1f6a76 100644 --- a/deps/icu-small/source/i18n/sharedbreakiterator.h +++ b/deps/icu-small/source/i18n/sharedbreakiterator.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * Copyright (C) 2014, International Business Machines diff --git a/deps/icu-small/source/i18n/sharedcalendar.h b/deps/icu-small/source/i18n/sharedcalendar.h index 2a10c88b59..f6d97b55bc 100644 --- a/deps/icu-small/source/i18n/sharedcalendar.h +++ b/deps/icu-small/source/i18n/sharedcalendar.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * Copyright (C) 2014, International Business Machines diff --git a/deps/icu-small/source/i18n/shareddateformatsymbols.h b/deps/icu-small/source/i18n/shareddateformatsymbols.h index 8451183bc2..a11a8a391b 100644 --- a/deps/icu-small/source/i18n/shareddateformatsymbols.h +++ b/deps/icu-small/source/i18n/shareddateformatsymbols.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * Copyright (C) 2014, International Business Machines diff --git a/deps/icu-small/source/i18n/sharednumberformat.h b/deps/icu-small/source/i18n/sharednumberformat.h index b6f5a8c923..fcb618a4d4 100644 --- a/deps/icu-small/source/i18n/sharednumberformat.h +++ b/deps/icu-small/source/i18n/sharednumberformat.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * Copyright (C) 2014, International Business Machines diff --git a/deps/icu-small/source/i18n/sharedpluralrules.h b/deps/icu-small/source/i18n/sharedpluralrules.h index 51773008fb..faed6dea0e 100644 --- a/deps/icu-small/source/i18n/sharedpluralrules.h +++ b/deps/icu-small/source/i18n/sharedpluralrules.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * Copyright (C) 2014, International Business Machines diff --git a/deps/icu-small/source/i18n/significantdigitinterval.h b/deps/icu-small/source/i18n/significantdigitinterval.h index a3d86f1c8f..336af784a5 100644 --- a/deps/icu-small/source/i18n/significantdigitinterval.h +++ b/deps/icu-small/source/i18n/significantdigitinterval.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2015, International Business Machines diff --git a/deps/icu-small/source/i18n/simpletz.cpp b/deps/icu-small/source/i18n/simpletz.cpp index 3696d21073..7dadef5ae6 100644 --- a/deps/icu-small/source/i18n/simpletz.cpp +++ b/deps/icu-small/source/i18n/simpletz.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 1997-2013, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/smallintformatter.cpp b/deps/icu-small/source/i18n/smallintformatter.cpp index 44dd9391cb..b96f6dad3b 100644 --- a/deps/icu-small/source/i18n/smallintformatter.cpp +++ b/deps/icu-small/source/i18n/smallintformatter.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* * Copyright (C) 2015, International Business Machines * Corporation and others. All Rights Reserved. diff --git a/deps/icu-small/source/i18n/smallintformatter.h b/deps/icu-small/source/i18n/smallintformatter.h index 2907c6203a..846d6b4054 100644 --- a/deps/icu-small/source/i18n/smallintformatter.h +++ b/deps/icu-small/source/i18n/smallintformatter.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2015, International Business Machines diff --git a/deps/icu-small/source/i18n/smpdtfmt.cpp b/deps/icu-small/source/i18n/smpdtfmt.cpp index 145587fb12..85cc162a11 100644 --- a/deps/icu-small/source/i18n/smpdtfmt.cpp +++ b/deps/icu-small/source/i18n/smpdtfmt.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 1997-2016, International Business Machines Corporation and * @@ -50,10 +52,10 @@ #include "unicode/vtzone.h" #include "unicode/udisplaycontext.h" #include "unicode/brkiter.h" +#include "uresimp.h" #include "olsontz.h" #include "patternprops.h" #include "fphdlimp.h" -#include "gregoimp.h" #include "hebrwcal.h" #include "cstring.h" #include "uassert.h" @@ -164,9 +166,6 @@ static const UChar SUPPRESS_NEGATIVE_PREFIX[] = {0xAB00, 0}; * These are the tags we expect to see in normal resource bundle files associated * with a locale. */ -static const char gDateTimePatternsTag[]="DateTimePatterns"; - -//static const UChar gEtcUTC[] = {0x45, 0x74, 0x63, 0x2F, 0x55, 0x54, 0x43, 0x00}; // "Etc/UTC" static const UChar QUOTE = 0x27; // Single quote /* @@ -702,20 +701,42 @@ void SimpleDateFormat::construct(EStyle timeStyle, initializeCalendar(NULL, locale, status); if (U_FAILURE(status)) return; - CalendarData calData(locale, fCalendar?fCalendar->getType():NULL, status); - UResourceBundle *dateTimePatterns = calData.getByKey(gDateTimePatternsTag, status); - UResourceBundle *currentBundle; + // Load date time patterns directly from resources. + const char* cType = fCalendar ? fCalendar->getType() : NULL; + LocalUResourceBundlePointer bundle(ures_open(NULL, locale.getBaseName(), &status)); + if (U_FAILURE(status)) return; + + UBool cTypeIsGregorian = TRUE; + LocalUResourceBundlePointer dateTimePatterns; + if (cType != NULL && uprv_strcmp(cType, "gregorian") != 0) { + CharString resourcePath("calendar/", status); + resourcePath.append(cType, status).append("/DateTimePatterns", status); + dateTimePatterns.adoptInstead( + ures_getByKeyWithFallback(bundle.getAlias(), resourcePath.data(), + (UResourceBundle*)NULL, &status)); + cTypeIsGregorian = FALSE; + } + // Check for "gregorian" fallback. + if (cTypeIsGregorian || status == U_MISSING_RESOURCE_ERROR) { + status = U_ZERO_ERROR; + dateTimePatterns.adoptInstead( + ures_getByKeyWithFallback(bundle.getAlias(), + "calendar/gregorian/DateTimePatterns", + (UResourceBundle*)NULL, &status)); + } if (U_FAILURE(status)) return; - if (ures_getSize(dateTimePatterns) <= kDateTime) + LocalUResourceBundlePointer currentBundle; + + if (ures_getSize(dateTimePatterns.getAlias()) <= kDateTime) { status = U_INVALID_FORMAT_ERROR; return; } - setLocaleIDs(ures_getLocaleByType(dateTimePatterns, ULOC_VALID_LOCALE, &status), - ures_getLocaleByType(dateTimePatterns, ULOC_ACTUAL_LOCALE, &status)); + setLocaleIDs(ures_getLocaleByType(dateTimePatterns.getAlias(), ULOC_VALID_LOCALE, &status), + ures_getLocaleByType(dateTimePatterns.getAlias(), ULOC_ACTUAL_LOCALE, &status)); // create a symbols object from the locale fSymbols = DateFormatSymbols::createForLocale(locale, status); @@ -736,66 +757,64 @@ void SimpleDateFormat::construct(EStyle timeStyle, // and time pattern strings. if ((timeStyle != kNone) && (dateStyle != kNone)) { - currentBundle = ures_getByIndex(dateTimePatterns, (int32_t)timeStyle, NULL, &status); + currentBundle.adoptInstead( + ures_getByIndex(dateTimePatterns.getAlias(), (int32_t)timeStyle, NULL, &status)); if (U_FAILURE(status)) { status = U_INVALID_FORMAT_ERROR; return; } - switch (ures_getType(currentBundle)) { + switch (ures_getType(currentBundle.getAlias())) { case URES_STRING: { - resStr = ures_getString(currentBundle, &resStrLen, &status); + resStr = ures_getString(currentBundle.getAlias(), &resStrLen, &status); break; } case URES_ARRAY: { - resStr = ures_getStringByIndex(currentBundle, 0, &resStrLen, &status); - ovrStr = ures_getStringByIndex(currentBundle, 1, &ovrStrLen, &status); + resStr = ures_getStringByIndex(currentBundle.getAlias(), 0, &resStrLen, &status); + ovrStr = ures_getStringByIndex(currentBundle.getAlias(), 1, &ovrStrLen, &status); fTimeOverride.setTo(TRUE, ovrStr, ovrStrLen); break; } default: { status = U_INVALID_FORMAT_ERROR; - ures_close(currentBundle); return; } } - ures_close(currentBundle); UnicodeString tempus1(TRUE, resStr, resStrLen); - currentBundle = ures_getByIndex(dateTimePatterns, (int32_t)dateStyle, NULL, &status); + currentBundle.adoptInstead( + ures_getByIndex(dateTimePatterns.getAlias(), (int32_t)dateStyle, NULL, &status)); if (U_FAILURE(status)) { status = U_INVALID_FORMAT_ERROR; return; } - switch (ures_getType(currentBundle)) { + switch (ures_getType(currentBundle.getAlias())) { case URES_STRING: { - resStr = ures_getString(currentBundle, &resStrLen, &status); + resStr = ures_getString(currentBundle.getAlias(), &resStrLen, &status); break; } case URES_ARRAY: { - resStr = ures_getStringByIndex(currentBundle, 0, &resStrLen, &status); - ovrStr = ures_getStringByIndex(currentBundle, 1, &ovrStrLen, &status); + resStr = ures_getStringByIndex(currentBundle.getAlias(), 0, &resStrLen, &status); + ovrStr = ures_getStringByIndex(currentBundle.getAlias(), 1, &ovrStrLen, &status); fDateOverride.setTo(TRUE, ovrStr, ovrStrLen); break; } default: { status = U_INVALID_FORMAT_ERROR; - ures_close(currentBundle); return; } } - ures_close(currentBundle); UnicodeString tempus2(TRUE, resStr, resStrLen); int32_t glueIndex = kDateTime; - int32_t patternsSize = ures_getSize(dateTimePatterns); + int32_t patternsSize = ures_getSize(dateTimePatterns.getAlias()); if (patternsSize >= (kDateTimeOffset + kShort + 1)) { // Get proper date time format glueIndex = (int32_t)(kDateTimeOffset + (dateStyle - kDateOffset)); } - resStr = ures_getStringByIndex(dateTimePatterns, glueIndex, &resStrLen, &status); + resStr = ures_getStringByIndex(dateTimePatterns.getAlias(), glueIndex, &resStrLen, &status); SimpleFormatter(UnicodeString(TRUE, resStr, resStrLen), 2, 2, status). format(tempus1, tempus2, fPattern, status); } @@ -803,56 +822,54 @@ void SimpleDateFormat::construct(EStyle timeStyle, // pattern string from the resources // setTo() - see DateFormatSymbols::assignArray comments else if (timeStyle != kNone) { - currentBundle = ures_getByIndex(dateTimePatterns, (int32_t)timeStyle, NULL, &status); + currentBundle.adoptInstead( + ures_getByIndex(dateTimePatterns.getAlias(), (int32_t)timeStyle, NULL, &status)); if (U_FAILURE(status)) { status = U_INVALID_FORMAT_ERROR; return; } - switch (ures_getType(currentBundle)) { + switch (ures_getType(currentBundle.getAlias())) { case URES_STRING: { - resStr = ures_getString(currentBundle, &resStrLen, &status); + resStr = ures_getString(currentBundle.getAlias(), &resStrLen, &status); break; } case URES_ARRAY: { - resStr = ures_getStringByIndex(currentBundle, 0, &resStrLen, &status); - ovrStr = ures_getStringByIndex(currentBundle, 1, &ovrStrLen, &status); + resStr = ures_getStringByIndex(currentBundle.getAlias(), 0, &resStrLen, &status); + ovrStr = ures_getStringByIndex(currentBundle.getAlias(), 1, &ovrStrLen, &status); fDateOverride.setTo(TRUE, ovrStr, ovrStrLen); break; } default: { status = U_INVALID_FORMAT_ERROR; - ures_close(currentBundle); return; } } fPattern.setTo(TRUE, resStr, resStrLen); - ures_close(currentBundle); } else if (dateStyle != kNone) { - currentBundle = ures_getByIndex(dateTimePatterns, (int32_t)dateStyle, NULL, &status); + currentBundle.adoptInstead( + ures_getByIndex(dateTimePatterns.getAlias(), (int32_t)dateStyle, NULL, &status)); if (U_FAILURE(status)) { status = U_INVALID_FORMAT_ERROR; return; } - switch (ures_getType(currentBundle)) { + switch (ures_getType(currentBundle.getAlias())) { case URES_STRING: { - resStr = ures_getString(currentBundle, &resStrLen, &status); + resStr = ures_getString(currentBundle.getAlias(), &resStrLen, &status); break; } case URES_ARRAY: { - resStr = ures_getStringByIndex(currentBundle, 0, &resStrLen, &status); - ovrStr = ures_getStringByIndex(currentBundle, 1, &ovrStrLen, &status); + resStr = ures_getStringByIndex(currentBundle.getAlias(), 0, &resStrLen, &status); + ovrStr = ures_getStringByIndex(currentBundle.getAlias(), 1, &ovrStrLen, &status); fDateOverride.setTo(TRUE, ovrStr, ovrStrLen); break; } default: { status = U_INVALID_FORMAT_ERROR; - ures_close(currentBundle); return; } } fPattern.setTo(TRUE, resStr, resStrLen); - ures_close(currentBundle); } // and if it includes _neither_, that's an error @@ -1553,7 +1570,7 @@ SimpleDateFormat::subFormat(UnicodeString &appendTo, } else if (count == 2) { value /= 10; } - FieldPosition p(0); + FieldPosition p(FieldPosition::DONT_CARE); currentNumberFormat->format(value, appendTo, p); if (count > 3) { currentNumberFormat->setMinimumIntegerDigits(count - 3); @@ -2040,7 +2057,7 @@ SimpleDateFormat::zeroPaddingNumber( int32_t value, int32_t minDigits, int32_t maxDigits) const { if (currentNumberFormat!=NULL) { - FieldPosition pos(0); + FieldPosition pos(FieldPosition::DONT_CARE); currentNumberFormat->setMinimumIntegerDigits(minDigits); currentNumberFormat->setMaximumIntegerDigits(maxDigits); diff --git a/deps/icu-small/source/i18n/smpdtfst.cpp b/deps/icu-small/source/i18n/smpdtfst.cpp index f9e94b82c6..50980a99e4 100644 --- a/deps/icu-small/source/i18n/smpdtfst.cpp +++ b/deps/icu-small/source/i18n/smpdtfst.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2009-2013, International Business Machines Corporation and * diff --git a/deps/icu-small/source/i18n/smpdtfst.h b/deps/icu-small/source/i18n/smpdtfst.h index da30f11d88..38ad558de2 100644 --- a/deps/icu-small/source/i18n/smpdtfst.h +++ b/deps/icu-small/source/i18n/smpdtfst.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2009-2013, International Business Machines Corporation and * diff --git a/deps/icu-small/source/i18n/sortkey.cpp b/deps/icu-small/source/i18n/sortkey.cpp index 257888c741..68b0f062b8 100644 --- a/deps/icu-small/source/i18n/sortkey.cpp +++ b/deps/icu-small/source/i18n/sortkey.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 1996-2012, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/standardplural.cpp b/deps/icu-small/source/i18n/standardplural.cpp index 456e9390ca..c39bae1ab1 100644 --- a/deps/icu-small/source/i18n/standardplural.cpp +++ b/deps/icu-small/source/i18n/standardplural.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2015, International Business Machines Corporation diff --git a/deps/icu-small/source/i18n/standardplural.h b/deps/icu-small/source/i18n/standardplural.h index 8a8de21884..56c63c347c 100644 --- a/deps/icu-small/source/i18n/standardplural.h +++ b/deps/icu-small/source/i18n/standardplural.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2015, International Business Machines Corporation diff --git a/deps/icu-small/source/i18n/strmatch.cpp b/deps/icu-small/source/i18n/strmatch.cpp index ad02c5f44c..e72cfc9ab0 100644 --- a/deps/icu-small/source/i18n/strmatch.cpp +++ b/deps/icu-small/source/i18n/strmatch.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2001-2012, International Business Machines Corporation diff --git a/deps/icu-small/source/i18n/strmatch.h b/deps/icu-small/source/i18n/strmatch.h index 32f5c4b790..0241adfd3f 100644 --- a/deps/icu-small/source/i18n/strmatch.h +++ b/deps/icu-small/source/i18n/strmatch.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* * Copyright (C) 2001-2011, International Business Machines Corporation * and others. All Rights Reserved. diff --git a/deps/icu-small/source/i18n/strrepl.cpp b/deps/icu-small/source/i18n/strrepl.cpp index 3181d5b159..d061eff579 100644 --- a/deps/icu-small/source/i18n/strrepl.cpp +++ b/deps/icu-small/source/i18n/strrepl.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2002-2012, International Business Machines Corporation diff --git a/deps/icu-small/source/i18n/strrepl.h b/deps/icu-small/source/i18n/strrepl.h index faf96b6296..a452db993f 100644 --- a/deps/icu-small/source/i18n/strrepl.h +++ b/deps/icu-small/source/i18n/strrepl.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2002-2011, International Business Machines Corporation diff --git a/deps/icu-small/source/i18n/stsearch.cpp b/deps/icu-small/source/i18n/stsearch.cpp index 925ee3138f..643ec21b27 100644 --- a/deps/icu-small/source/i18n/stsearch.cpp +++ b/deps/icu-small/source/i18n/stsearch.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2001-2014 IBM and others. All rights reserved. diff --git a/deps/icu-small/source/i18n/taiwncal.cpp b/deps/icu-small/source/i18n/taiwncal.cpp index 7c51843c0f..f1ca6fa135 100644 --- a/deps/icu-small/source/i18n/taiwncal.cpp +++ b/deps/icu-small/source/i18n/taiwncal.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2003-2013, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/taiwncal.h b/deps/icu-small/source/i18n/taiwncal.h index 125a20da17..b15cff5beb 100644 --- a/deps/icu-small/source/i18n/taiwncal.h +++ b/deps/icu-small/source/i18n/taiwncal.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** * Copyright (C) 2003-2013, International Business Machines Corporation diff --git a/deps/icu-small/source/i18n/timezone.cpp b/deps/icu-small/source/i18n/timezone.cpp index d0a1a41879..427674aac4 100644 --- a/deps/icu-small/source/i18n/timezone.cpp +++ b/deps/icu-small/source/i18n/timezone.cpp @@ -1,6 +1,8 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* -* Copyright (C) 1997-2015, International Business Machines Corporation and +* Copyright (C) 1997-2016, International Business Machines Corporation and * others. All Rights Reserved. ******************************************************************************* * @@ -458,6 +460,8 @@ TimeZone::detectHostTimeZone() uprv_tzset(); // Initialize tz... system data + uprv_tzname_clear_cache(); + // Get the timezone ID from the host. This function should do // any required host-specific remapping; e.g., on Windows this // function maps the Date and Time control panel setting to an diff --git a/deps/icu-small/source/i18n/titletrn.cpp b/deps/icu-small/source/i18n/titletrn.cpp index 79ffb40319..a1de8be666 100644 --- a/deps/icu-small/source/i18n/titletrn.cpp +++ b/deps/icu-small/source/i18n/titletrn.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2001-2011, International Business Machines diff --git a/deps/icu-small/source/i18n/titletrn.h b/deps/icu-small/source/i18n/titletrn.h index a093152b66..a6380e3bd1 100644 --- a/deps/icu-small/source/i18n/titletrn.h +++ b/deps/icu-small/source/i18n/titletrn.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2001-2007, International Business Machines diff --git a/deps/icu-small/source/i18n/tmunit.cpp b/deps/icu-small/source/i18n/tmunit.cpp index e56c51ca0f..d9da268125 100644 --- a/deps/icu-small/source/i18n/tmunit.cpp +++ b/deps/icu-small/source/i18n/tmunit.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2008-2014, Google, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/tmutamt.cpp b/deps/icu-small/source/i18n/tmutamt.cpp index 734b5de882..7be730765b 100644 --- a/deps/icu-small/source/i18n/tmutamt.cpp +++ b/deps/icu-small/source/i18n/tmutamt.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2008, Google, International Business Machines Corporation and * diff --git a/deps/icu-small/source/i18n/tmutfmt.cpp b/deps/icu-small/source/i18n/tmutfmt.cpp index fa31d7b3c1..1669546f76 100644 --- a/deps/icu-small/source/i18n/tmutfmt.cpp +++ b/deps/icu-small/source/i18n/tmutfmt.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2008-2015, Google, International Business Machines Corporation @@ -347,6 +349,115 @@ TimeUnitFormat::initDataMembers(UErrorCode& err){ } } +struct TimeUnitFormatReadSink : public ResourceSink { + TimeUnitFormat *timeUnitFormatObj; + const UVector &pluralCounts; + UTimeUnitFormatStyle style; + UBool beenHere; + + TimeUnitFormatReadSink(TimeUnitFormat *timeUnitFormatObj, + const UVector &pluralCounts, UTimeUnitFormatStyle style) : + timeUnitFormatObj(timeUnitFormatObj), pluralCounts(pluralCounts), + style(style), beenHere(FALSE){} + + virtual ~TimeUnitFormatReadSink(); + + virtual void put(const char *key, ResourceValue &value, UBool, UErrorCode &errorCode) { + // Skip all put() calls except the first one -- discard all fallback data. + if (beenHere) { + return; + } else { + beenHere = TRUE; + } + + ResourceTable units = value.getTable(errorCode); + if (U_FAILURE(errorCode)) { return; } + + for (int32_t i = 0; units.getKeyAndValue(i, key, value); ++i) { + const char* timeUnitName = key; + if (timeUnitName == NULL) { + continue; + } + + TimeUnit::UTimeUnitFields timeUnitField = TimeUnit::UTIMEUNIT_FIELD_COUNT; + if ( uprv_strcmp(timeUnitName, gTimeUnitYear) == 0 ) { + timeUnitField = TimeUnit::UTIMEUNIT_YEAR; + } else if ( uprv_strcmp(timeUnitName, gTimeUnitMonth) == 0 ) { + timeUnitField = TimeUnit::UTIMEUNIT_MONTH; + } else if ( uprv_strcmp(timeUnitName, gTimeUnitDay) == 0 ) { + timeUnitField = TimeUnit::UTIMEUNIT_DAY; + } else if ( uprv_strcmp(timeUnitName, gTimeUnitHour) == 0 ) { + timeUnitField = TimeUnit::UTIMEUNIT_HOUR; + } else if ( uprv_strcmp(timeUnitName, gTimeUnitMinute) == 0 ) { + timeUnitField = TimeUnit::UTIMEUNIT_MINUTE; + } else if ( uprv_strcmp(timeUnitName, gTimeUnitSecond) == 0 ) { + timeUnitField = TimeUnit::UTIMEUNIT_SECOND; + } else if ( uprv_strcmp(timeUnitName, gTimeUnitWeek) == 0 ) { + timeUnitField = TimeUnit::UTIMEUNIT_WEEK; + } else { + continue; + } + LocalPointer<Hashtable> localCountToPatterns; + Hashtable *countToPatterns = + timeUnitFormatObj->fTimeUnitToCountToPatterns[timeUnitField]; + if (countToPatterns == NULL) { + localCountToPatterns.adoptInsteadAndCheckErrorCode( + timeUnitFormatObj->initHash(errorCode), errorCode); + countToPatterns = localCountToPatterns.getAlias(); + if (U_FAILURE(errorCode)) { + return; + } + } + + ResourceTable countsToPatternTable = value.getTable(errorCode); + if (U_FAILURE(errorCode)) { + continue; + } + for (int32_t j = 0; countsToPatternTable.getKeyAndValue(j, key, value); ++j) { + errorCode = U_ZERO_ERROR; + UnicodeString pattern = value.getUnicodeString(errorCode); + if (U_FAILURE(errorCode)) { + continue; + } + UnicodeString pluralCountUniStr(key, -1, US_INV); + if (!pluralCounts.contains(&pluralCountUniStr)) { + continue; + } + LocalPointer<MessageFormat> messageFormat(new MessageFormat( + pattern, timeUnitFormatObj->getLocale(errorCode), errorCode), errorCode); + if (U_FAILURE(errorCode)) { + return; + } + MessageFormat** formatters = + (MessageFormat**)countToPatterns->get(pluralCountUniStr); + if (formatters == NULL) { + LocalMemory<MessageFormat *> localFormatters( + (MessageFormat **)uprv_malloc(UTMUTFMT_FORMAT_STYLE_COUNT*sizeof(MessageFormat*))); + if (localFormatters.isNull()) { + errorCode = U_MEMORY_ALLOCATION_ERROR; + return; + } + localFormatters[UTMUTFMT_FULL_STYLE] = NULL; + localFormatters[UTMUTFMT_ABBREVIATED_STYLE] = NULL; + countToPatterns->put(pluralCountUniStr, localFormatters.getAlias(), errorCode); + if (U_FAILURE(errorCode)) { + return; + } + formatters = localFormatters.orphan(); + } + formatters[style] = messageFormat.orphan(); + } + + if (timeUnitFormatObj->fTimeUnitToCountToPatterns[timeUnitField] == NULL) { + timeUnitFormatObj->fTimeUnitToCountToPatterns[timeUnitField] = localCountToPatterns.orphan(); + } + } + } + +}; + +TimeUnitFormatReadSink::~TimeUnitFormatReadSink() {} + void TimeUnitFormat::readFromCurrentLocale(UTimeUnitFormatStyle style, const char* key, const UVector& pluralCounts, UErrorCode& err) { @@ -365,94 +476,10 @@ TimeUnitFormat::readFromCurrentLocale(UTimeUnitFormatStyle style, const char* ke if (U_FAILURE(status)) { return; } - int32_t size = ures_getSize(unitsRes.getAlias()); - for ( int32_t index = 0; index < size; ++index) { - status = U_ZERO_ERROR; - // resource of one time unit - LocalUResourceBundlePointer oneTimeUnit( - ures_getByIndex(unitsRes.getAlias(), index, NULL, &status)); - if (U_FAILURE(status)) { - continue; - } - const char* timeUnitName = ures_getKey(oneTimeUnit.getAlias()); - if (timeUnitName == NULL) { - continue; - } - LocalUResourceBundlePointer countsToPatternRB( - ures_getByKey(unitsRes.getAlias(), timeUnitName, NULL, &status)); - if (countsToPatternRB.isNull() || U_FAILURE(status)) { - continue; - } - TimeUnit::UTimeUnitFields timeUnitField = TimeUnit::UTIMEUNIT_FIELD_COUNT; - if ( uprv_strcmp(timeUnitName, gTimeUnitYear) == 0 ) { - timeUnitField = TimeUnit::UTIMEUNIT_YEAR; - } else if ( uprv_strcmp(timeUnitName, gTimeUnitMonth) == 0 ) { - timeUnitField = TimeUnit::UTIMEUNIT_MONTH; - } else if ( uprv_strcmp(timeUnitName, gTimeUnitDay) == 0 ) { - timeUnitField = TimeUnit::UTIMEUNIT_DAY; - } else if ( uprv_strcmp(timeUnitName, gTimeUnitHour) == 0 ) { - timeUnitField = TimeUnit::UTIMEUNIT_HOUR; - } else if ( uprv_strcmp(timeUnitName, gTimeUnitMinute) == 0 ) { - timeUnitField = TimeUnit::UTIMEUNIT_MINUTE; - } else if ( uprv_strcmp(timeUnitName, gTimeUnitSecond) == 0 ) { - timeUnitField = TimeUnit::UTIMEUNIT_SECOND; - } else if ( uprv_strcmp(timeUnitName, gTimeUnitWeek) == 0 ) { - timeUnitField = TimeUnit::UTIMEUNIT_WEEK; - } else { - continue; - } - LocalPointer<Hashtable> localCountToPatterns; - Hashtable *countToPatterns = fTimeUnitToCountToPatterns[timeUnitField]; - if (countToPatterns == NULL) { - localCountToPatterns.adoptInsteadAndCheckErrorCode(initHash(err), err); - countToPatterns = localCountToPatterns.getAlias(); - if (U_FAILURE(err)) { - return; - } - } - int32_t count = ures_getSize(countsToPatternRB.getAlias()); - const char* pluralCount; - for ( int32_t pluralIndex = 0; pluralIndex < count; ++pluralIndex) { - // resource of count to pattern - status = U_ZERO_ERROR; - UnicodeString pattern = - ures_getNextUnicodeString(countsToPatternRB.getAlias(), &pluralCount, &status); - if (U_FAILURE(status)) { - continue; - } - UnicodeString pluralCountUniStr(pluralCount, -1, US_INV); - if (!pluralCounts.contains(&pluralCountUniStr)) { - continue; - } - LocalPointer<MessageFormat> messageFormat(new MessageFormat(pattern, getLocale(err), err), err); - if (U_FAILURE(err)) { - return; - } - MessageFormat** formatters = (MessageFormat**)countToPatterns->get(pluralCountUniStr); - if (formatters == NULL) { - LocalMemory<MessageFormat *> localFormatters( - (MessageFormat **)uprv_malloc(UTMUTFMT_FORMAT_STYLE_COUNT*sizeof(MessageFormat*))); - if (localFormatters.isNull()) { - err = U_MEMORY_ALLOCATION_ERROR; - return; - } - localFormatters[UTMUTFMT_FULL_STYLE] = NULL; - localFormatters[UTMUTFMT_ABBREVIATED_STYLE] = NULL; - countToPatterns->put(pluralCountUniStr, localFormatters.getAlias(), err); - if (U_FAILURE(err)) { - return; - } - formatters = localFormatters.orphan(); - } - //delete formatters[style]; - formatters[style] = messageFormat.orphan(); - } - if (fTimeUnitToCountToPatterns[timeUnitField] == NULL) { - fTimeUnitToCountToPatterns[timeUnitField] = localCountToPatterns.orphan(); - } - } -} + TimeUnitFormatReadSink sink(this, pluralCounts, style); + ures_getAllItemsWithFallback(unitsRes.getAlias(), "", sink, status); +} void TimeUnitFormat::checkConsistency(UTimeUnitFormatStyle style, const char* key, UErrorCode& err) { diff --git a/deps/icu-small/source/i18n/tolowtrn.cpp b/deps/icu-small/source/i18n/tolowtrn.cpp index 3edeaf81a6..f0a59bbd0b 100644 --- a/deps/icu-small/source/i18n/tolowtrn.cpp +++ b/deps/icu-small/source/i18n/tolowtrn.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2001-2007, International Business Machines diff --git a/deps/icu-small/source/i18n/tolowtrn.h b/deps/icu-small/source/i18n/tolowtrn.h index 564b215a72..616e59899f 100644 --- a/deps/icu-small/source/i18n/tolowtrn.h +++ b/deps/icu-small/source/i18n/tolowtrn.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2001-2007, International Business Machines diff --git a/deps/icu-small/source/i18n/toupptrn.cpp b/deps/icu-small/source/i18n/toupptrn.cpp index 4b7c7d06ac..a34792e07c 100644 --- a/deps/icu-small/source/i18n/toupptrn.cpp +++ b/deps/icu-small/source/i18n/toupptrn.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2001-2007, International Business Machines diff --git a/deps/icu-small/source/i18n/toupptrn.h b/deps/icu-small/source/i18n/toupptrn.h index 77799acbfd..eae44e7d18 100644 --- a/deps/icu-small/source/i18n/toupptrn.h +++ b/deps/icu-small/source/i18n/toupptrn.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2001-2007, International Business Machines diff --git a/deps/icu-small/source/i18n/translit.cpp b/deps/icu-small/source/i18n/translit.cpp index 56cad2d18f..79328baa2b 100644 --- a/deps/icu-small/source/i18n/translit.cpp +++ b/deps/icu-small/source/i18n/translit.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 1999-2016, International Business Machines diff --git a/deps/icu-small/source/i18n/transreg.cpp b/deps/icu-small/source/i18n/transreg.cpp index 2f7e7d56fa..cc1d51dea8 100644 --- a/deps/icu-small/source/i18n/transreg.cpp +++ b/deps/icu-small/source/i18n/transreg.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2001-2014, International Business Machines diff --git a/deps/icu-small/source/i18n/transreg.h b/deps/icu-small/source/i18n/transreg.h index e01f89ad07..334963f8d1 100644 --- a/deps/icu-small/source/i18n/transreg.h +++ b/deps/icu-small/source/i18n/transreg.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2001-2014, International Business Machines diff --git a/deps/icu-small/source/i18n/tridpars.cpp b/deps/icu-small/source/i18n/tridpars.cpp index a58d58550d..140e3d7d1c 100644 --- a/deps/icu-small/source/i18n/tridpars.cpp +++ b/deps/icu-small/source/i18n/tridpars.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2002-2014, International Business Machines Corporation @@ -902,7 +904,7 @@ Transliterator* TransliteratorIDParser::createBasicInstance(const UnicodeString& /** * Initialize static memory. Called through umtx_initOnce only. */ -void TransliteratorIDParser::init(UErrorCode &status) { +void U_CALLCONV TransliteratorIDParser::init(UErrorCode &status) { U_ASSERT(SPECIAL_INVERSES == NULL); ucln_i18n_registerCleanup(UCLN_I18N_TRANSLITERATOR, utrans_transliterator_cleanup); diff --git a/deps/icu-small/source/i18n/tridpars.h b/deps/icu-small/source/i18n/tridpars.h index 88620fd18d..7c226023ef 100644 --- a/deps/icu-small/source/i18n/tridpars.h +++ b/deps/icu-small/source/i18n/tridpars.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ************************************************************************** * Copyright (c) 2002-2010, International Business Machines Corporation * @@ -349,7 +351,7 @@ class TransliteratorIDParser /* not : public UObject because all methods are sta /** * Initialize static memory. */ - static void init(UErrorCode &status); + static void U_CALLCONV init(UErrorCode &status); friend class SingleID; }; diff --git a/deps/icu-small/source/i18n/tzfmt.cpp b/deps/icu-small/source/i18n/tzfmt.cpp index e03b1a88aa..783edac34f 100644 --- a/deps/icu-small/source/i18n/tzfmt.cpp +++ b/deps/icu-small/source/i18n/tzfmt.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2011-2015, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/tzgnames.cpp b/deps/icu-small/source/i18n/tzgnames.cpp index 127ea58deb..4fc726ea54 100644 --- a/deps/icu-small/source/i18n/tzgnames.cpp +++ b/deps/icu-small/source/i18n/tzgnames.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2011-2016, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/tzgnames.h b/deps/icu-small/source/i18n/tzgnames.h index ebe9b76ba5..e78e8ee991 100644 --- a/deps/icu-small/source/i18n/tzgnames.h +++ b/deps/icu-small/source/i18n/tzgnames.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2011-2012, International Business Machines Corporation and * diff --git a/deps/icu-small/source/i18n/tznames.cpp b/deps/icu-small/source/i18n/tznames.cpp index db1ce0ddee..6aefd13b53 100644 --- a/deps/icu-small/source/i18n/tznames.cpp +++ b/deps/icu-small/source/i18n/tznames.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2011-2015, International Business Machines Corporation and * @@ -116,6 +118,9 @@ public: UnicodeString& getExemplarLocationName(const UnicodeString& tzID, UnicodeString& name) const; + void loadAllDisplayNames(UErrorCode& status); + void getDisplayNames(const UnicodeString& tzID, const UTimeZoneNameType types[], int32_t numTypes, UDate date, UnicodeString dest[], UErrorCode& status) const; + MatchInfoCollection* find(const UnicodeString& text, int32_t start, uint32_t types, UErrorCode& status) const; private: TimeZoneNamesDelegate(); @@ -278,6 +283,16 @@ TimeZoneNamesDelegate::getExemplarLocationName(const UnicodeString& tzID, Unicod return fTZnamesCacheEntry->names->getExemplarLocationName(tzID, name); } +void +TimeZoneNamesDelegate::loadAllDisplayNames(UErrorCode& status) { + fTZnamesCacheEntry->names->loadAllDisplayNames(status); +} + +void +TimeZoneNamesDelegate::getDisplayNames(const UnicodeString& tzID, const UTimeZoneNameType types[], int32_t numTypes, UDate date, UnicodeString dest[], UErrorCode& status) const { + fTZnamesCacheEntry->names->getDisplayNames(tzID, types, numTypes, date, dest, status); +} + TimeZoneNames::MatchInfoCollection* TimeZoneNamesDelegate::find(const UnicodeString& text, int32_t start, uint32_t types, UErrorCode& status) const { return fTZnamesCacheEntry->names->find(text, start, types, status); @@ -330,6 +345,29 @@ TimeZoneNames::getDisplayName(const UnicodeString& tzID, UTimeZoneNameType type, return name; } +// Empty default implementation, to be overriden in tznames_impl.cpp. +void +TimeZoneNames::loadAllDisplayNames(UErrorCode& /*status*/) { +} + +// A default, lightweight implementation of getDisplayNames. +// Overridden in tznames_impl.cpp. +void +TimeZoneNames::getDisplayNames(const UnicodeString& tzID, const UTimeZoneNameType types[], int32_t numTypes, UDate date, UnicodeString dest[], UErrorCode& status) const { + if (U_FAILURE(status)) { return; } + if (tzID.isEmpty()) { return; } + UnicodeString mzID; + for (int i = 0; i < numTypes; i++) { + getTimeZoneDisplayName(tzID, types[i], dest[i]); + if (dest[i].isEmpty()) { + if (mzID.isEmpty()) { + getMetaZoneID(tzID, date, mzID); + } + getMetaZoneDisplayName(mzID, types[i], dest[i]); + } + } +} + struct MatchInfo : UMemory { UTimeZoneNameType nameType; diff --git a/deps/icu-small/source/i18n/tznames_impl.cpp b/deps/icu-small/source/i18n/tznames_impl.cpp index 0f50232a3c..3e92acb6f9 100644 --- a/deps/icu-small/source/i18n/tznames_impl.cpp +++ b/deps/icu-small/source/i18n/tznames_impl.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2011-2016, International Business Machines Corporation and @@ -21,6 +23,7 @@ #include "cstring.h" #include "uassert.h" #include "mutex.h" +#include "resource.h" #include "uresimp.h" #include "ureslocs.h" #include "zonemeta.h" @@ -28,7 +31,6 @@ #include "uvector.h" #include "olsontz.h" - U_NAMESPACE_BEGIN #define ZID_KEY_MAX 128 @@ -37,25 +39,16 @@ U_NAMESPACE_BEGIN static const char gZoneStrings[] = "zoneStrings"; static const char gMZPrefix[] = "meta:"; -static const char* KEYS[] = {"lg", "ls", "ld", "sg", "ss", "sd"}; -static const int32_t KEYS_SIZE = UPRV_LENGTHOF(KEYS); - -static const char gEcTag[] = "ec"; - -static const char EMPTY[] = "<empty>"; // place holder for empty ZNames/TZNames - -static const UTimeZoneNameType ALL_NAME_TYPES[] = { - UTZNM_LONG_GENERIC, UTZNM_LONG_STANDARD, UTZNM_LONG_DAYLIGHT, - UTZNM_SHORT_GENERIC, UTZNM_SHORT_STANDARD, UTZNM_SHORT_DAYLIGHT, - UTZNM_EXEMPLAR_LOCATION, - UTZNM_UNKNOWN // unknown as the last one -}; +static const char EMPTY[] = "<empty>"; // place holder for empty ZNames +static const char DUMMY_LOADER[] = "<dummy>"; // place holder for dummy ZNamesLoader +static const UChar NO_NAME[] = { 0 }; // for empty no-fallback time zone names // stuff for TZDBTimeZoneNames static const char* TZDBNAMES_KEYS[] = {"ss", "sd"}; static const int32_t TZDBNAMES_KEYS_SIZE = UPRV_LENGTHOF(TZDBNAMES_KEYS); static UMutex gTZDBNamesMapLock = U_MUTEX_INITIALIZER; +static UMutex gDataMutex = U_MUTEX_INITIALIZER; static UHashtable* gTZDBNamesMap = NULL; static icu::UInitOnce gTZDBNamesMapInitOnce = U_INITONCE_INITIALIZER; @@ -63,6 +56,20 @@ static icu::UInitOnce gTZDBNamesMapInitOnce = U_INITONCE_INITIALIZER; static TextTrieMap* gTZDBNamesTrie = NULL; static icu::UInitOnce gTZDBNamesTrieInitOnce = U_INITONCE_INITIALIZER; +// The order in which strings are stored may be different than the order in the public enum. +enum UTimeZoneNameTypeIndex { + UTZNM_INDEX_UNKNOWN = -1, + UTZNM_INDEX_EXEMPLAR_LOCATION, + UTZNM_INDEX_LONG_GENERIC, + UTZNM_INDEX_LONG_STANDARD, + UTZNM_INDEX_LONG_DAYLIGHT, + UTZNM_INDEX_SHORT_GENERIC, + UTZNM_INDEX_SHORT_STANDARD, + UTZNM_INDEX_SHORT_DAYLIGHT, + UTZNM_INDEX_COUNT +}; +static const UChar* EMPTY_NAMES[UTZNM_INDEX_COUNT] = {0,0,0,0,0,0,0}; + U_CDECL_BEGIN static UBool U_CALLCONV tzdbTimeZoneNames_cleanup(void) { if (gTZDBNamesMap != NULL) { @@ -81,6 +88,26 @@ static UBool U_CALLCONV tzdbTimeZoneNames_cleanup(void) { } U_CDECL_END +/** + * ZNameInfo stores zone name information in the trie + */ +struct ZNameInfo { + UTimeZoneNameType type; + const UChar* tzID; + const UChar* mzID; +}; + +/** + * ZMatchInfo stores zone name match information used by find method + */ +struct ZMatchInfo { + const ZNameInfo* znameInfo; + int32_t matchLength; +}; + +// Helper functions +static void mergeTimeZoneKey(const UnicodeString& mzID, char* result); + #define DEFAULT_CHARACTERNODE_CAPACITY 1 // --------------------------------------------------- @@ -182,7 +209,7 @@ TextTrieMap::put(const UnicodeString &key, void *value, ZNStringPool &sp, UError put(s, value, status); } -// This method is for designed for a persistent key, such as string key stored in +// This method is designed for a persistent key, such as string key stored in // resource bundle. void TextTrieMap::put(const UChar *key, void *value, UErrorCode &status) { @@ -194,11 +221,22 @@ TextTrieMap::put(const UChar *key, void *value, UErrorCode &status) { } } if (U_FAILURE(status)) { + if (fValueDeleter) { + fValueDeleter((void*) key); + } return; } U_ASSERT(fLazyContents != NULL); + UChar *s = const_cast<UChar *>(key); fLazyContents->addElement(s, status); + if (U_FAILURE(status)) { + if (fValueDeleter) { + fValueDeleter((void*) key); + } + return; + } + fLazyContents->addElement(value, status); } @@ -207,6 +245,10 @@ TextTrieMap::putImpl(const UnicodeString &key, void *value, UErrorCode &status) if (fNodes == NULL) { fNodesCapacity = 512; fNodes = (CharacterNode *)uprv_malloc(fNodesCapacity * sizeof(CharacterNode)); + if (fNodes == NULL) { + status = U_MEMORY_ALLOCATION_ERROR; + return; + } fNodes[0].clear(); // Init root node. fNodesCount = 1; } @@ -517,196 +559,283 @@ void ZNStringPool::freeze() { } -// --------------------------------------------------- -// ZNames - names common for time zone and meta zone -// --------------------------------------------------- +/** + * This class stores name data for a meta zone or time zone. + */ class ZNames : public UMemory { -public: - virtual ~ZNames(); +private: + friend class TimeZoneNamesImpl; + + static UTimeZoneNameTypeIndex getTZNameTypeIndex(UTimeZoneNameType type) { + switch(type) { + case UTZNM_EXEMPLAR_LOCATION: return UTZNM_INDEX_EXEMPLAR_LOCATION; + case UTZNM_LONG_GENERIC: return UTZNM_INDEX_LONG_GENERIC; + case UTZNM_LONG_STANDARD: return UTZNM_INDEX_LONG_STANDARD; + case UTZNM_LONG_DAYLIGHT: return UTZNM_INDEX_LONG_DAYLIGHT; + case UTZNM_SHORT_GENERIC: return UTZNM_INDEX_SHORT_GENERIC; + case UTZNM_SHORT_STANDARD: return UTZNM_INDEX_SHORT_STANDARD; + case UTZNM_SHORT_DAYLIGHT: return UTZNM_INDEX_SHORT_DAYLIGHT; + default: return UTZNM_INDEX_UNKNOWN; + } + } + static UTimeZoneNameType getTZNameType(UTimeZoneNameTypeIndex index) { + switch(index) { + case UTZNM_INDEX_EXEMPLAR_LOCATION: return UTZNM_EXEMPLAR_LOCATION; + case UTZNM_INDEX_LONG_GENERIC: return UTZNM_LONG_GENERIC; + case UTZNM_INDEX_LONG_STANDARD: return UTZNM_LONG_STANDARD; + case UTZNM_INDEX_LONG_DAYLIGHT: return UTZNM_LONG_DAYLIGHT; + case UTZNM_INDEX_SHORT_GENERIC: return UTZNM_SHORT_GENERIC; + case UTZNM_INDEX_SHORT_STANDARD: return UTZNM_SHORT_STANDARD; + case UTZNM_INDEX_SHORT_DAYLIGHT: return UTZNM_SHORT_DAYLIGHT; + default: return UTZNM_UNKNOWN; + } + } - static ZNames* createInstance(UResourceBundle* rb, const char* key); - virtual const UChar* getName(UTimeZoneNameType type); + const UChar* fNames[UTZNM_INDEX_COUNT]; + UBool fDidAddIntoTrie; -protected: - ZNames(const UChar** names); - static const UChar** loadData(UResourceBundle* rb, const char* key); + // Whether we own the location string, if computed rather than loaded from a bundle. + // A meta zone names instance never has an exemplar location string. + UBool fOwnsLocationName; + + ZNames(const UChar* names[], const UChar* locationName) + : fDidAddIntoTrie(FALSE) { + uprv_memcpy(fNames, names, sizeof(fNames)); + if (locationName != NULL) { + fOwnsLocationName = TRUE; + fNames[UTZNM_INDEX_EXEMPLAR_LOCATION] = locationName; + } else { + fOwnsLocationName = FALSE; + } + } + +public: + ~ZNames() { + if (fOwnsLocationName) { + const UChar* locationName = fNames[UTZNM_INDEX_EXEMPLAR_LOCATION]; + U_ASSERT(locationName != NULL); + uprv_free((void*) locationName); + } + } private: - const UChar** fNames; -}; + static void* createMetaZoneAndPutInCache(UHashtable* cache, const UChar* names[], + const UnicodeString& mzID, UErrorCode& status) { + if (U_FAILURE(status)) { return NULL; } + U_ASSERT(names != NULL); -ZNames::ZNames(const UChar** names) -: fNames(names) { -} + // Use the persistent ID as the resource key, so we can + // avoid duplications. + // TODO: Is there a more efficient way, like intern() in Java? + void* key = (void*) ZoneMeta::findMetaZoneID(mzID); + void* value; + if (uprv_memcmp(names, EMPTY_NAMES, sizeof(EMPTY_NAMES)) == 0) { + value = (void*) EMPTY; + } else { + value = (void*) (new ZNames(names, NULL)); + if (value == NULL) { + status = U_MEMORY_ALLOCATION_ERROR; + return NULL; + } + } + uhash_put(cache, key, value, &status); + return value; + } + + static void* createTimeZoneAndPutInCache(UHashtable* cache, const UChar* names[], + const UnicodeString& tzID, UErrorCode& status) { + if (U_FAILURE(status)) { return NULL; } + U_ASSERT(names != NULL); + + // If necessary, compute the location name from the time zone name. + UChar* locationName = NULL; + if (names[UTZNM_INDEX_EXEMPLAR_LOCATION] == NULL) { + UnicodeString locationNameUniStr; + TimeZoneNamesImpl::getDefaultExemplarLocationName(tzID, locationNameUniStr); + + // Copy the computed location name to the heap + if (locationNameUniStr.length() > 0) { + const UChar* buff = locationNameUniStr.getTerminatedBuffer(); + int32_t len = sizeof(UChar) * (locationNameUniStr.length() + 1); + locationName = (UChar*) uprv_malloc(len); + if (locationName == NULL) { + status = U_MEMORY_ALLOCATION_ERROR; + return NULL; + } + uprv_memcpy(locationName, buff, len); + } + } -ZNames::~ZNames() { - if (fNames != NULL) { - uprv_free(fNames); + // Use the persistent ID as the resource key, so we can + // avoid duplications. + // TODO: Is there a more efficient way, like intern() in Java? + void* key = (void*) ZoneMeta::findTimeZoneID(tzID); + void* value = (void*) (new ZNames(names, locationName)); + if (value == NULL) { + status = U_MEMORY_ALLOCATION_ERROR; + return NULL; + } + uhash_put(cache, key, value, &status); + return value; } -} -ZNames* -ZNames::createInstance(UResourceBundle* rb, const char* key) { - const UChar** names = loadData(rb, key); - if (names == NULL) { - // No names data available - return NULL; + const UChar* getName(UTimeZoneNameType type) const { + UTimeZoneNameTypeIndex index = getTZNameTypeIndex(type); + return index >= 0 ? fNames[index] : NULL; } - return new ZNames(names); -} -const UChar* -ZNames::getName(UTimeZoneNameType type) { - if (fNames == NULL) { - return NULL; - } - const UChar *name = NULL; - switch(type) { - case UTZNM_LONG_GENERIC: - name = fNames[0]; - break; - case UTZNM_LONG_STANDARD: - name = fNames[1]; - break; - case UTZNM_LONG_DAYLIGHT: - name = fNames[2]; - break; - case UTZNM_SHORT_GENERIC: - name = fNames[3]; - break; - case UTZNM_SHORT_STANDARD: - name = fNames[4]; - break; - case UTZNM_SHORT_DAYLIGHT: - name = fNames[5]; - break; - case UTZNM_EXEMPLAR_LOCATION: // implemeted by subclass - default: - name = NULL; + void addAsMetaZoneIntoTrie(const UChar* mzID, TextTrieMap& trie, UErrorCode& status) { + addNamesIntoTrie(mzID, NULL, trie, status); } - return name; -} - -const UChar** -ZNames::loadData(UResourceBundle* rb, const char* key) { - if (rb == NULL || key == NULL || *key == 0) { - return NULL; + void addAsTimeZoneIntoTrie(const UChar* tzID, TextTrieMap& trie, UErrorCode& status) { + addNamesIntoTrie(NULL, tzID, trie, status); } - UErrorCode status = U_ZERO_ERROR; - const UChar **names = NULL; + void addNamesIntoTrie(const UChar* mzID, const UChar* tzID, TextTrieMap& trie, + UErrorCode& status) { + if (U_FAILURE(status)) { return; } + if (fDidAddIntoTrie) { return; } + fDidAddIntoTrie = TRUE; - UResourceBundle* rbTable = NULL; - rbTable = ures_getByKeyWithFallback(rb, key, rbTable, &status); - if (U_SUCCESS(status)) { - names = (const UChar **)uprv_malloc(sizeof(const UChar*) * KEYS_SIZE); - if (names != NULL) { - UBool isEmpty = TRUE; - for (int32_t i = 0; i < KEYS_SIZE; i++) { - status = U_ZERO_ERROR; - int32_t len = 0; - const UChar *value = ures_getStringByKeyWithFallback(rbTable, KEYS[i], &len, &status); - if (U_FAILURE(status) || len == 0) { - names[i] = NULL; - } else { - names[i] = value; - isEmpty = FALSE; + for (int32_t i = 0; i < UTZNM_INDEX_COUNT; i++) { + const UChar* name = fNames[i]; + if (name != NULL) { + ZNameInfo *nameinfo = (ZNameInfo *)uprv_malloc(sizeof(ZNameInfo)); + if (nameinfo == NULL) { + status = U_MEMORY_ALLOCATION_ERROR; + return; + } + nameinfo->mzID = mzID; + nameinfo->tzID = tzID; + nameinfo->type = getTZNameType((UTimeZoneNameTypeIndex)i); + trie.put(name, nameinfo, status); // trie.put() takes ownership of the key + if (U_FAILURE(status)) { + return; } - } - if (isEmpty) { - // No need to keep the names array - uprv_free(names); - names = NULL; } } } - ures_close(rbTable); - return names; -} -// --------------------------------------------------- -// TZNames - names for a time zone -// --------------------------------------------------- -class TZNames : public ZNames { public: - virtual ~TZNames(); - - static TZNames* createInstance(UResourceBundle* rb, const char* key, const UnicodeString& tzID); - virtual const UChar* getName(UTimeZoneNameType type); - -private: - TZNames(const UChar** names); - const UChar* fLocationName; - UChar* fLocationNameOwned; + struct ZNamesLoader; }; -TZNames::TZNames(const UChar** names) -: ZNames(names), fLocationName(NULL), fLocationNameOwned(NULL) { -} +struct ZNames::ZNamesLoader : public ResourceSink { + const UChar *names[UTZNM_INDEX_COUNT]; -TZNames::~TZNames() { - if (fLocationNameOwned) { - uprv_free(fLocationNameOwned); + ZNamesLoader() { + clear(); } -} + virtual ~ZNamesLoader(); -const UChar* -TZNames::getName(UTimeZoneNameType type) { - if (type == UTZNM_EXEMPLAR_LOCATION) { - return fLocationName; + /** Reset for loading another set of names. */ + void clear() { + uprv_memcpy(names, EMPTY_NAMES, sizeof(names)); } - return ZNames::getName(type); -} -TZNames* -TZNames::createInstance(UResourceBundle* rb, const char* key, const UnicodeString& tzID) { - if (rb == NULL || key == NULL || *key == 0) { - return NULL; + void loadMetaZone(const UResourceBundle* zoneStrings, const UnicodeString& mzID, UErrorCode& errorCode) { + if (U_FAILURE(errorCode)) { return; } + + char key[ZID_KEY_MAX + 1]; + mergeTimeZoneKey(mzID, key); + + loadNames(zoneStrings, key, errorCode); } - const UChar** names = loadData(rb, key); - const UChar* locationName = NULL; - UChar* locationNameOwned = NULL; + void loadTimeZone(const UResourceBundle* zoneStrings, const UnicodeString& tzID, UErrorCode& errorCode) { + // Replace "/" with ":". + UnicodeString uKey(tzID); + for (int32_t i = 0; i < uKey.length(); i++) { + if (uKey.charAt(i) == (UChar)0x2F) { + uKey.setCharAt(i, (UChar)0x3A); + } + } + + char key[ZID_KEY_MAX + 1]; + uKey.extract(0, uKey.length(), key, sizeof(key), US_INV); - UErrorCode status = U_ZERO_ERROR; - int32_t len = 0; + loadNames(zoneStrings, key, errorCode); + } + + void loadNames(const UResourceBundle* zoneStrings, const char* key, UErrorCode& errorCode) { + U_ASSERT(zoneStrings != NULL); + U_ASSERT(key != NULL); + U_ASSERT(key[0] != '\0'); - UResourceBundle* table = ures_getByKeyWithFallback(rb, key, NULL, &status); - locationName = ures_getStringByKeyWithFallback(table, gEcTag, &len, &status); - // ignore missing resource here - status = U_ZERO_ERROR; + UErrorCode localStatus = U_ZERO_ERROR; + clear(); + ures_getAllItemsWithFallback(zoneStrings, key, *this, localStatus); - ures_close(table); + // Ignore errors, but propogate possible warnings. + if (U_SUCCESS(localStatus)) { + errorCode = localStatus; + } + } - if (locationName == NULL) { - UnicodeString tmpName; - int32_t tmpNameLen = 0; - TimeZoneNamesImpl::getDefaultExemplarLocationName(tzID, tmpName); - tmpNameLen = tmpName.length(); + void setNameIfEmpty(const char* key, const ResourceValue* value, UErrorCode& errorCode) { + UTimeZoneNameTypeIndex type = nameTypeFromKey(key); + if (type == UTZNM_INDEX_UNKNOWN) { return; } + if (names[type] == NULL) { + int32_t length; + // 'NO_NAME' indicates internally that this field should remain empty. It will be + // replaced by 'NULL' in getNames() + names[type] = (value == NULL) ? NO_NAME : value->getString(length, errorCode); + } + } - if (tmpNameLen > 0) { - locationNameOwned = (UChar*) uprv_malloc(sizeof(UChar) * (tmpNameLen + 1)); - if (locationNameOwned) { - tmpName.extract(locationNameOwned, tmpNameLen + 1, status); - locationName = locationNameOwned; + virtual void put(const char* key, ResourceValue& value, UBool /*noFallback*/, + UErrorCode &errorCode) { + ResourceTable namesTable = value.getTable(errorCode); + if (U_FAILURE(errorCode)) { return; } + for (int32_t i = 0; namesTable.getKeyAndValue(i, key, value); ++i) { + if (value.isNoInheritanceMarker()) { + setNameIfEmpty(key, NULL, errorCode); + } else { + setNameIfEmpty(key, &value, errorCode); } } } - TZNames* tznames = NULL; - if (locationName != NULL || names != NULL) { - tznames = new TZNames(names); - if (tznames == NULL) { - if (locationNameOwned) { - uprv_free(locationNameOwned); + static UTimeZoneNameTypeIndex nameTypeFromKey(const char *key) { + char c0, c1; + if ((c0 = key[0]) == 0 || (c1 = key[1]) == 0 || key[2] != 0) { + return UTZNM_INDEX_UNKNOWN; + } + if (c0 == 'l') { + return c1 == 'g' ? UTZNM_INDEX_LONG_GENERIC : + c1 == 's' ? UTZNM_INDEX_LONG_STANDARD : + c1 == 'd' ? UTZNM_INDEX_LONG_DAYLIGHT : UTZNM_INDEX_UNKNOWN; + } else if (c0 == 's') { + return c1 == 'g' ? UTZNM_INDEX_SHORT_GENERIC : + c1 == 's' ? UTZNM_INDEX_SHORT_STANDARD : + c1 == 'd' ? UTZNM_INDEX_SHORT_DAYLIGHT : UTZNM_INDEX_UNKNOWN; + } else if (c0 == 'e' && c1 == 'c') { + return UTZNM_INDEX_EXEMPLAR_LOCATION; + } + return UTZNM_INDEX_UNKNOWN; + } + + /** + * Returns an array of names. It is the caller's responsibility to copy the data into a + * permanent location, as the returned array is owned by the loader instance and may be + * cleared or leave scope. + * + * This is different than Java, where the array will no longer be modified and null + * may be returned. + */ + const UChar** getNames() { + // Remove 'NO_NAME' references in the array and replace with 'NULL' + for (int32_t i = 0; i < UTZNM_INDEX_COUNT; ++i) { + if (names[i] == NO_NAME) { + names[i] = NULL; } } - tznames->fLocationName = locationName; - tznames->fLocationNameOwned = locationNameOwned; + return names; } +}; + +ZNames::ZNamesLoader::~ZNamesLoader() {} - return tznames; -} // --------------------------------------------------- // The meta zone ID enumeration class @@ -772,25 +901,6 @@ MetaZoneIDsEnumeration::~MetaZoneIDsEnumeration() { } } -U_CDECL_BEGIN -/** - * ZNameInfo stores zone name information in the trie - */ -typedef struct ZNameInfo { - UTimeZoneNameType type; - const UChar* tzID; - const UChar* mzID; -} ZNameInfo; - -/** - * ZMatchInfo stores zone name match information used by find method - */ -typedef struct ZMatchInfo { - const ZNameInfo* znameInfo; - int32_t matchLength; -} ZMatchInfo; -U_CDECL_END - // --------------------------------------------------- // ZNameSearchHandler @@ -883,16 +993,7 @@ U_CDECL_BEGIN static void U_CALLCONV deleteZNames(void *obj) { if (obj != EMPTY) { - delete (ZNames *)obj; - } -} -/** - * Deleter for TZNames - */ -static void U_CALLCONV -deleteTZNames(void *obj) { - if (obj != EMPTY) { - delete (TZNames *)obj; + delete (ZNames*) obj; } } @@ -906,14 +1007,13 @@ deleteZNameInfo(void *obj) { U_CDECL_END -static UMutex gLock = U_MUTEX_INITIALIZER; - TimeZoneNamesImpl::TimeZoneNamesImpl(const Locale& locale, UErrorCode& status) : fLocale(locale), fZoneStrings(NULL), fTZNamesMap(NULL), fMZNamesMap(NULL), fNamesTrieFullyLoaded(FALSE), + fNamesFullyLoaded(FALSE), fNamesTrie(TRUE, deleteZNameInfo) { initialize(locale, status); } @@ -943,14 +1043,14 @@ TimeZoneNamesImpl::initialize(const Locale& locale, UErrorCode& status) { } uhash_setValueDeleter(fMZNamesMap, deleteZNames); - uhash_setValueDeleter(fTZNamesMap, deleteTZNames); + uhash_setValueDeleter(fTZNamesMap, deleteZNames); // no key deleters for name maps // preload zone strings for the default zone TimeZone *tz = TimeZone::createDefault(); const UChar *tzID = ZoneMeta::getCanonicalCLDRID(*tz); if (tzID != NULL) { - loadStrings(UnicodeString(tzID)); + loadStrings(UnicodeString(tzID), status); } delete tz; @@ -962,20 +1062,15 @@ TimeZoneNamesImpl::initialize(const Locale& locale, UErrorCode& status) { * except initializer. */ void -TimeZoneNamesImpl::loadStrings(const UnicodeString& tzCanonicalID) { - loadTimeZoneNames(tzCanonicalID); +TimeZoneNamesImpl::loadStrings(const UnicodeString& tzCanonicalID, UErrorCode& status) { + loadTimeZoneNames(tzCanonicalID, status); + LocalPointer<StringEnumeration> mzIDs(getAvailableMetaZoneIDs(tzCanonicalID, status)); + if (U_FAILURE(status)) { return; } + U_ASSERT(!mzIDs.isNull()); - UErrorCode status = U_ZERO_ERROR; - StringEnumeration *mzIDs = getAvailableMetaZoneIDs(tzCanonicalID, status); - if (U_SUCCESS(status) && mzIDs != NULL) { - const UnicodeString *mzID; - while ((mzID = mzIDs->snext(status))) { - if (U_FAILURE(status)) { - break; - } - loadMetaZoneNames(*mzID); - } - delete mzIDs; + const UnicodeString *mzID; + while ((mzID = mzIDs->snext(status)) && U_SUCCESS(status)) { + loadMetaZoneNames(*mzID, status); } } @@ -1096,7 +1191,6 @@ TimeZoneNamesImpl::_getReferenceZoneID(const UnicodeString& mzID, const char* re return tzID; } - UnicodeString& TimeZoneNamesImpl::getMetaZoneDisplayName(const UnicodeString& mzID, UTimeZoneNameType type, @@ -1109,11 +1203,12 @@ TimeZoneNamesImpl::getMetaZoneDisplayName(const UnicodeString& mzID, ZNames *znames = NULL; TimeZoneNamesImpl *nonConstThis = const_cast<TimeZoneNamesImpl *>(this); - umtx_lock(&gLock); { - znames = nonConstThis->loadMetaZoneNames(mzID); + Mutex lock(&gDataMutex); + UErrorCode status = U_ZERO_ERROR; + znames = nonConstThis->loadMetaZoneNames(mzID, status); + if (U_FAILURE(status)) { return name; } } - umtx_unlock(&gLock); if (znames != NULL) { const UChar* s = znames->getName(type); @@ -1131,14 +1226,15 @@ TimeZoneNamesImpl::getTimeZoneDisplayName(const UnicodeString& tzID, UTimeZoneNa return name; } - TZNames *tznames = NULL; + ZNames *tznames = NULL; TimeZoneNamesImpl *nonConstThis = const_cast<TimeZoneNamesImpl *>(this); - umtx_lock(&gLock); { - tznames = nonConstThis->loadTimeZoneNames(tzID); + Mutex lock(&gDataMutex); + UErrorCode status = U_ZERO_ERROR; + tznames = nonConstThis->loadTimeZoneNames(tzID, status); + if (U_FAILURE(status)) { return name; } } - umtx_unlock(&gLock); if (tznames != NULL) { const UChar *s = tznames->getName(type); @@ -1153,14 +1249,15 @@ UnicodeString& TimeZoneNamesImpl::getExemplarLocationName(const UnicodeString& tzID, UnicodeString& name) const { name.setToBogus(); // cleanup result. const UChar* locName = NULL; - TZNames *tznames = NULL; + ZNames *tznames = NULL; TimeZoneNamesImpl *nonConstThis = const_cast<TimeZoneNamesImpl *>(this); - umtx_lock(&gLock); { - tznames = nonConstThis->loadTimeZoneNames(tzID); + Mutex lock(&gDataMutex); + UErrorCode status = U_ZERO_ERROR; + tznames = nonConstThis->loadTimeZoneNames(tzID, status); + if (U_FAILURE(status)) { return name; } } - umtx_unlock(&gLock); if (tznames != NULL) { locName = tznames->getName(UTZNM_EXEMPLAR_LOCATION); @@ -1193,215 +1290,386 @@ static void mergeTimeZoneKey(const UnicodeString& mzID, char* result) { * This method updates the cache and must be called with a lock */ ZNames* -TimeZoneNamesImpl::loadMetaZoneNames(const UnicodeString& mzID) { - if (mzID.length() > (ZID_KEY_MAX - MZ_PREFIX_LEN)) { - return NULL; - } +TimeZoneNamesImpl::loadMetaZoneNames(const UnicodeString& mzID, UErrorCode& status) { + if (U_FAILURE(status)) { return NULL; } + U_ASSERT(mzID.length() <= ZID_KEY_MAX - MZ_PREFIX_LEN); - ZNames *znames = NULL; - - UErrorCode status = U_ZERO_ERROR; UChar mzIDKey[ZID_KEY_MAX + 1]; mzID.extract(mzIDKey, ZID_KEY_MAX + 1, status); - U_ASSERT(status == U_ZERO_ERROR); // already checked length above + U_ASSERT(U_SUCCESS(status)); // already checked length above mzIDKey[mzID.length()] = 0; - void *cacheVal = uhash_get(fMZNamesMap, mzIDKey); - if (cacheVal == NULL) { - char key[ZID_KEY_MAX + 1]; - mergeTimeZoneKey(mzID, key); - znames = ZNames::createInstance(fZoneStrings, key); - - if (znames == NULL) { - cacheVal = (void *)EMPTY; - } else { - cacheVal = znames; - } - // Use the persistent ID as the resource key, so we can - // avoid duplications. - const UChar* newKey = ZoneMeta::findMetaZoneID(mzID); - if (newKey != NULL) { - uhash_put(fMZNamesMap, (void *)newKey, cacheVal, &status); - if (U_FAILURE(status)) { - if (znames != NULL) { - delete znames; - znames = NULL; - } - } else if (znames != NULL) { - // put the name info into the trie - for (int32_t i = 0; ALL_NAME_TYPES[i] != UTZNM_UNKNOWN; i++) { - const UChar* name = znames->getName(ALL_NAME_TYPES[i]); - if (name != NULL) { - ZNameInfo *nameinfo = (ZNameInfo *)uprv_malloc(sizeof(ZNameInfo)); - if (nameinfo != NULL) { - nameinfo->type = ALL_NAME_TYPES[i]; - nameinfo->tzID = NULL; - nameinfo->mzID = newKey; - fNamesTrie.put(name, nameinfo, status); - } - } - } - } - - } else { - // Should never happen with a valid input - if (znames != NULL) { - // It's not possible that we get a valid ZNames with unknown ID. - // But just in case.. - delete znames; - znames = NULL; - } - } - } else if (cacheVal != EMPTY) { - znames = (ZNames *)cacheVal; + void* mznames = uhash_get(fMZNamesMap, mzIDKey); + if (mznames == NULL) { + ZNames::ZNamesLoader loader; + loader.loadMetaZone(fZoneStrings, mzID, status); + mznames = ZNames::createMetaZoneAndPutInCache(fMZNamesMap, loader.getNames(), mzID, status); + if (U_FAILURE(status)) { return NULL; } } - return znames; + if (mznames != EMPTY) { + return (ZNames*)mznames; + } else { + return NULL; + } } /* * This method updates the cache and must be called with a lock */ -TZNames* -TimeZoneNamesImpl::loadTimeZoneNames(const UnicodeString& tzID) { - if (tzID.length() > ZID_KEY_MAX) { - return NULL; - } - - TZNames *tznames = NULL; +ZNames* +TimeZoneNamesImpl::loadTimeZoneNames(const UnicodeString& tzID, UErrorCode& status) { + if (U_FAILURE(status)) { return NULL; } + U_ASSERT(tzID.length() <= ZID_KEY_MAX); - UErrorCode status = U_ZERO_ERROR; UChar tzIDKey[ZID_KEY_MAX + 1]; int32_t tzIDKeyLen = tzID.extract(tzIDKey, ZID_KEY_MAX + 1, status); - U_ASSERT(status == U_ZERO_ERROR); // already checked length above + U_ASSERT(U_SUCCESS(status)); // already checked length above tzIDKey[tzIDKeyLen] = 0; - void *cacheVal = uhash_get(fTZNamesMap, tzIDKey); - if (cacheVal == NULL) { - char key[ZID_KEY_MAX + 1]; - UErrorCode status = U_ZERO_ERROR; - // Replace "/" with ":". - UnicodeString uKey(tzID); - for (int32_t i = 0; i < uKey.length(); i++) { - if (uKey.charAt(i) == (UChar)0x2F) { - uKey.setCharAt(i, (UChar)0x3A); - } - } - uKey.extract(0, uKey.length(), key, sizeof(key), US_INV); - tznames = TZNames::createInstance(fZoneStrings, key, tzID); - - if (tznames == NULL) { - cacheVal = (void *)EMPTY; - } else { - cacheVal = tznames; - } - // Use the persistent ID as the resource key, so we can - // avoid duplications. - const UChar* newKey = ZoneMeta::findTimeZoneID(tzID); - if (newKey != NULL) { - uhash_put(fTZNamesMap, (void *)newKey, cacheVal, &status); - if (U_FAILURE(status)) { - if (tznames != NULL) { - delete tznames; - tznames = NULL; - } - } else if (tznames != NULL) { - // put the name info into the trie - for (int32_t i = 0; ALL_NAME_TYPES[i] != UTZNM_UNKNOWN; i++) { - const UChar* name = tznames->getName(ALL_NAME_TYPES[i]); - if (name != NULL) { - ZNameInfo *nameinfo = (ZNameInfo *)uprv_malloc(sizeof(ZNameInfo)); - if (nameinfo != NULL) { - nameinfo->type = ALL_NAME_TYPES[i]; - nameinfo->tzID = newKey; - nameinfo->mzID = NULL; - fNamesTrie.put(name, nameinfo, status); - } - } - } - } - } else { - // Should never happen with a valid input - if (tznames != NULL) { - // It's not possible that we get a valid TZNames with unknown ID. - // But just in case.. - delete tznames; - tznames = NULL; - } - } - } else if (cacheVal != EMPTY) { - tznames = (TZNames *)cacheVal; + void *tznames = uhash_get(fTZNamesMap, tzIDKey); + if (tznames == NULL) { + ZNames::ZNamesLoader loader; + loader.loadTimeZone(fZoneStrings, tzID, status); + tznames = ZNames::createTimeZoneAndPutInCache(fTZNamesMap, loader.getNames(), tzID, status); + if (U_FAILURE(status)) { return NULL; } } - return tznames; + // tznames is never EMPTY + return (ZNames*)tznames; } TimeZoneNames::MatchInfoCollection* TimeZoneNamesImpl::find(const UnicodeString& text, int32_t start, uint32_t types, UErrorCode& status) const { ZNameSearchHandler handler(types); + TimeZoneNames::MatchInfoCollection* matches; + TimeZoneNamesImpl* nonConstThis = const_cast<TimeZoneNamesImpl*>(this); - TimeZoneNamesImpl *nonConstThis = const_cast<TimeZoneNamesImpl *>(this); - - umtx_lock(&gLock); + // Synchronize so that data is not loaded multiple times. + // TODO: Consider more fine-grained synchronization. { - fNamesTrie.search(text, start, (TextTrieMapSearchResultHandler *)&handler, status); - } - umtx_unlock(&gLock); + Mutex lock(&gDataMutex); - if (U_FAILURE(status)) { - return NULL; + // First try of lookup. + matches = doFind(handler, text, start, status); + if (U_FAILURE(status)) { return NULL; } + if (matches != NULL) { + return matches; + } + + // All names are not yet loaded into the trie. + // We may have loaded names for formatting several time zones, + // and might be parsing one of those. + // Populate the parsing trie from all of the already-loaded names. + nonConstThis->addAllNamesIntoTrie(status); + + // Second try of lookup. + matches = doFind(handler, text, start, status); + if (U_FAILURE(status)) { return NULL; } + if (matches != NULL) { + return matches; + } + + // There are still some names we haven't loaded into the trie yet. + // Load everything now. + nonConstThis->internalLoadAllDisplayNames(status); + nonConstThis->addAllNamesIntoTrie(status); + nonConstThis->fNamesTrieFullyLoaded = TRUE; + if (U_FAILURE(status)) { return NULL; } + + // Third try: we must return this one. + return doFind(handler, text, start, status); } +} + +TimeZoneNames::MatchInfoCollection* +TimeZoneNamesImpl::doFind(ZNameSearchHandler& handler, + const UnicodeString& text, int32_t start, UErrorCode& status) const { + + fNamesTrie.search(text, start, (TextTrieMapSearchResultHandler *)&handler, status); + if (U_FAILURE(status)) { return NULL; } int32_t maxLen = 0; TimeZoneNames::MatchInfoCollection* matches = handler.getMatches(maxLen); if (matches != NULL && ((maxLen == (text.length() - start)) || fNamesTrieFullyLoaded)) { - // perfect match + // perfect match, or no more names available return matches; } - delete matches; + return NULL; +} - // All names are not yet loaded into the trie - umtx_lock(&gLock); - { - if (!fNamesTrieFullyLoaded) { - const UnicodeString *id; +// Caller must synchronize. +void TimeZoneNamesImpl::addAllNamesIntoTrie(UErrorCode& status) { + if (U_FAILURE(status)) return; + int32_t pos; + const UHashElement* element; - // load strings for all zones - StringEnumeration *tzIDs = TimeZone::createTimeZoneIDEnumeration(UCAL_ZONE_TYPE_CANONICAL, NULL, NULL, status); - if (U_SUCCESS(status)) { - while ((id = tzIDs->snext(status))) { - if (U_FAILURE(status)) { - break; + pos = UHASH_FIRST; + while ((element = uhash_nextElement(fMZNamesMap, &pos)) != NULL) { + if (element->value.pointer == EMPTY) { continue; } + UChar* mzID = (UChar*) element->key.pointer; + ZNames* znames = (ZNames*) element->value.pointer; + znames->addAsMetaZoneIntoTrie(mzID, fNamesTrie, status); + if (U_FAILURE(status)) { return; } + } + + pos = UHASH_FIRST; + while ((element = uhash_nextElement(fTZNamesMap, &pos)) != NULL) { + if (element->value.pointer == EMPTY) { continue; } + UChar* tzID = (UChar*) element->key.pointer; + ZNames* znames = (ZNames*) element->value.pointer; + znames->addAsTimeZoneIntoTrie(tzID, fNamesTrie, status); + if (U_FAILURE(status)) { return; } + } +} + +U_CDECL_BEGIN +static void U_CALLCONV +deleteZNamesLoader(void* obj) { + if (obj == DUMMY_LOADER) { return; } + const ZNames::ZNamesLoader* loader = (const ZNames::ZNamesLoader*) obj; + delete loader; +} +U_CDECL_END + +struct TimeZoneNamesImpl::ZoneStringsLoader : public ResourceSink { + TimeZoneNamesImpl& tzn; + UHashtable* keyToLoader; + + ZoneStringsLoader(TimeZoneNamesImpl& _tzn, UErrorCode& status) + : tzn(_tzn) { + keyToLoader = uhash_open(uhash_hashChars, uhash_compareChars, NULL, &status); + if (U_FAILURE(status)) { return; } + uhash_setKeyDeleter(keyToLoader, uprv_free); + uhash_setValueDeleter(keyToLoader, deleteZNamesLoader); + } + virtual ~ZoneStringsLoader(); + + void* createKey(const char* key, UErrorCode& status) { + int32_t len = sizeof(char) * (uprv_strlen(key) + 1); + char* newKey = (char*) uprv_malloc(len); + if (newKey == NULL) { + status = U_MEMORY_ALLOCATION_ERROR; + return NULL; + } + uprv_memcpy(newKey, key, len); + newKey[len-1] = '\0'; + return (void*) newKey; + } + + UBool isMetaZone(const char* key) { + return (uprv_strlen(key) >= MZ_PREFIX_LEN && uprv_memcmp(key, gMZPrefix, MZ_PREFIX_LEN) == 0); + } + + UnicodeString mzIDFromKey(const char* key) { + return UnicodeString(key + MZ_PREFIX_LEN, uprv_strlen(key) - MZ_PREFIX_LEN, US_INV); + } + + UnicodeString tzIDFromKey(const char* key) { + UnicodeString tzID(key, -1, US_INV); + // Replace all colons ':' with slashes '/' + for (int i=0; i<tzID.length(); i++) { + if (tzID.charAt(i) == 0x003A) { + tzID.setCharAt(i, 0x002F); + } + } + return tzID; + } + + void load(UErrorCode& status) { + ures_getAllItemsWithFallback(tzn.fZoneStrings, "", *this, status); + if (U_FAILURE(status)) { return; } + + int32_t pos = UHASH_FIRST; + const UHashElement* element; + while ((element = uhash_nextElement(keyToLoader, &pos)) != NULL) { + if (element->value.pointer == DUMMY_LOADER) { continue; } + ZNames::ZNamesLoader* loader = (ZNames::ZNamesLoader*) element->value.pointer; + char* key = (char*) element->key.pointer; + + if (isMetaZone(key)) { + UnicodeString mzID = mzIDFromKey(key); + ZNames::createMetaZoneAndPutInCache(tzn.fMZNamesMap, loader->getNames(), mzID, status); + } else { + UnicodeString tzID = tzIDFromKey(key); + ZNames::createTimeZoneAndPutInCache(tzn.fTZNamesMap, loader->getNames(), tzID, status); + } + if (U_FAILURE(status)) { return; } + } + } + + void consumeNamesTable(const char *key, ResourceValue &value, UBool noFallback, + UErrorCode &status) { + if (U_FAILURE(status)) { return; } + + void* loader = uhash_get(keyToLoader, key); + if (loader == NULL) { + if (isMetaZone(key)) { + UnicodeString mzID = mzIDFromKey(key); + void* cacheVal = uhash_get(tzn.fMZNamesMap, mzID.getTerminatedBuffer()); + if (cacheVal != NULL) { + // We have already loaded the names for this meta zone. + loader = (void*) DUMMY_LOADER; + } else { + loader = (void*) new ZNames::ZNamesLoader(); + if (loader == NULL) { + status = U_MEMORY_ALLOCATION_ERROR; + return; + } + } + } else { + UnicodeString tzID = tzIDFromKey(key); + void* cacheVal = uhash_get(tzn.fTZNamesMap, tzID.getTerminatedBuffer()); + if (cacheVal != NULL) { + // We have already loaded the names for this time zone. + loader = (void*) DUMMY_LOADER; + } else { + loader = (void*) new ZNames::ZNamesLoader(); + if (loader == NULL) { + status = U_MEMORY_ALLOCATION_ERROR; + return; } - // loadStrings also load related metazone strings - nonConstThis->loadStrings(*id); } } - if (tzIDs != NULL) { - delete tzIDs; + + void* newKey = createKey(key, status); + if (U_FAILURE(status)) { + deleteZNamesLoader(loader); + return; } - if (U_SUCCESS(status)) { - nonConstThis->fNamesTrieFullyLoaded = TRUE; + + uhash_put(keyToLoader, newKey, loader, &status); + if (U_FAILURE(status)) { return; } + } + + if (loader != DUMMY_LOADER) { + // Let the ZNamesLoader consume the names table. + ((ZNames::ZNamesLoader*)loader)->put(key, value, noFallback, status); + } + } + + virtual void put(const char *key, ResourceValue &value, UBool noFallback, + UErrorCode &status) { + ResourceTable timeZonesTable = value.getTable(status); + if (U_FAILURE(status)) { return; } + for (int32_t i = 0; timeZonesTable.getKeyAndValue(i, key, value); ++i) { + U_ASSERT(!value.isNoInheritanceMarker()); + if (value.getType() == URES_TABLE) { + consumeNamesTable(key, value, noFallback, status); + } else { + // Ignore fields that aren't tables (e.g., fallbackFormat and regionFormatStandard). + // All time zone fields are tables. } + if (U_FAILURE(status)) { return; } } } - umtx_unlock(&gLock); +}; - if (U_FAILURE(status)) { - return NULL; +// Virtual destructors must be defined out of line. +TimeZoneNamesImpl::ZoneStringsLoader::~ZoneStringsLoader() { + uhash_close(keyToLoader); +} + +void TimeZoneNamesImpl::loadAllDisplayNames(UErrorCode& status) { + if (U_FAILURE(status)) return; + + { + Mutex lock(&gDataMutex); + internalLoadAllDisplayNames(status); } +} + +void TimeZoneNamesImpl::getDisplayNames(const UnicodeString& tzID, + const UTimeZoneNameType types[], int32_t numTypes, + UDate date, UnicodeString dest[], UErrorCode& status) const { + if (U_FAILURE(status)) return; + + if (tzID.isEmpty()) { return; } + void* tznames = NULL; + void* mznames = NULL; + TimeZoneNamesImpl *nonConstThis = const_cast<TimeZoneNamesImpl*>(this); - umtx_lock(&gLock); + // Load the time zone strings { - // now try it again - fNamesTrie.search(text, start, (TextTrieMapSearchResultHandler *)&handler, status); + Mutex lock(&gDataMutex); + tznames = (void*) nonConstThis->loadTimeZoneNames(tzID, status); + if (U_FAILURE(status)) { return; } + } + U_ASSERT(tznames != NULL); + + // Load the values into the dest array + for (int i = 0; i < numTypes; i++) { + UTimeZoneNameType type = types[i]; + const UChar* name = ((ZNames*)tznames)->getName(type); + if (name == NULL) { + if (mznames == NULL) { + // Load the meta zone name + UnicodeString mzID; + getMetaZoneID(tzID, date, mzID); + if (mzID.isEmpty()) { + mznames = (void*) EMPTY; + } else { + // Load the meta zone strings + // Mutex is scoped to the "else" statement + Mutex lock(&gDataMutex); + mznames = (void*) nonConstThis->loadMetaZoneNames(mzID, status); + if (U_FAILURE(status)) { return; } + // Note: when the metazone doesn't exist, in Java, loadMetaZoneNames returns + // a dummy object instead of NULL. + if (mznames == NULL) { + mznames = (void*) EMPTY; + } + } + } + U_ASSERT(mznames != NULL); + if (mznames != EMPTY) { + name = ((ZNames*)mznames)->getName(type); + } + } + if (name != NULL) { + dest[i].setTo(TRUE, name, -1); + } else { + dest[i].setToBogus(); + } } - umtx_unlock(&gLock); +} - return handler.getMatches(maxLen); +// Caller must synchronize. +void TimeZoneNamesImpl::internalLoadAllDisplayNames(UErrorCode& status) { + if (!fNamesFullyLoaded) { + fNamesFullyLoaded = TRUE; + + ZoneStringsLoader loader(*this, status); + loader.load(status); + if (U_FAILURE(status)) { return; } + + const UnicodeString *id; + + // load strings for all zones + StringEnumeration *tzIDs = TimeZone::createTimeZoneIDEnumeration( + UCAL_ZONE_TYPE_CANONICAL, NULL, NULL, status); + if (U_SUCCESS(status)) { + while ((id = tzIDs->snext(status))) { + if (U_FAILURE(status)) { + break; + } + UnicodeString copy(*id); + void* value = uhash_get(fTZNamesMap, copy.getTerminatedBuffer()); + if (value == NULL) { + // loadStrings also loads related metazone strings + loadStrings(*id, status); + } + } + } + if (tzIDs != NULL) { + delete tzIDs; + } + } } + + static const UChar gEtcPrefix[] = { 0x45, 0x74, 0x63, 0x2F }; // "Etc/" static const int32_t gEtcPrefixLen = 4; static const UChar gSystemVPrefix[] = { 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x56, 0x2F }; // "SystemV/ @@ -1554,7 +1822,7 @@ TZDBNames::createInstance(UResourceBundle* rb, const char* key) { if (regions != NULL) { char **p = regions; for (int32_t i = 0; i < numRegions; p++, i++) { - uprv_free(p); + uprv_free(*p); } uprv_free(regions); } @@ -1982,9 +2250,10 @@ TZDBTimeZoneNames::getMetaZoneNames(const UnicodeString& mzID, UErrorCode& statu } // Use the persistent ID as the resource key, so we can // avoid duplications. - const UChar* newKey = ZoneMeta::findMetaZoneID(mzID); + // TODO: Is there a more efficient way, like intern() in Java? + void* newKey = (void*) ZoneMeta::findMetaZoneID(mzID); if (newKey != NULL) { - uhash_put(gTZDBNamesMap, (void *)newKey, cacheVal, &status); + uhash_put(gTZDBNamesMap, newKey, cacheVal, &status); if (U_FAILURE(status)) { if (tzdbNames != NULL) { delete tzdbNames; diff --git a/deps/icu-small/source/i18n/tznames_impl.h b/deps/icu-small/source/i18n/tznames_impl.h index 5e5d96829e..6b913bb6bf 100644 --- a/deps/icu-small/source/i18n/tznames_impl.h +++ b/deps/icu-small/source/i18n/tznames_impl.h @@ -1,7 +1,9 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* - * Copyright (C) 2011-2014, International Business Machines Corporation and * - * others. All Rights Reserved. * + * Copyright (C) 2011-2016, International Business Machines Corporation and + * others. All Rights Reserved. ******************************************************************************* */ @@ -159,8 +161,8 @@ private: class ZNames; -class TZNames; class TextTrieMap; +class ZNameSearchHandler; class TimeZoneNamesImpl : public TimeZoneNames { public: @@ -184,6 +186,9 @@ public: TimeZoneNames::MatchInfoCollection* find(const UnicodeString& text, int32_t start, uint32_t types, UErrorCode& status) const; + void loadAllDisplayNames(UErrorCode& status); + void getDisplayNames(const UnicodeString& tzID, const UTimeZoneNameType types[], int32_t numTypes, UDate date, UnicodeString dest[], UErrorCode& status) const; + static UnicodeString& getDefaultExemplarLocationName(const UnicodeString& tzID, UnicodeString& name); static StringEnumeration* _getAvailableMetaZoneIDs(UErrorCode& status); @@ -201,15 +206,23 @@ private: UHashtable* fMZNamesMap; UBool fNamesTrieFullyLoaded; + UBool fNamesFullyLoaded; TextTrieMap fNamesTrie; void initialize(const Locale& locale, UErrorCode& status); void cleanup(); - void loadStrings(const UnicodeString& tzCanonicalID); + void loadStrings(const UnicodeString& tzCanonicalID, UErrorCode& status); + + ZNames* loadMetaZoneNames(const UnicodeString& mzId, UErrorCode& status); + ZNames* loadTimeZoneNames(const UnicodeString& mzId, UErrorCode& status); + TimeZoneNames::MatchInfoCollection* doFind(ZNameSearchHandler& handler, + const UnicodeString& text, int32_t start, UErrorCode& status) const; + void addAllNamesIntoTrie(UErrorCode& errorCode); + + void internalLoadAllDisplayNames(UErrorCode& status); - ZNames* loadMetaZoneNames(const UnicodeString& mzId); - TZNames* loadTimeZoneNames(const UnicodeString& mzId); + struct ZoneStringsLoader; }; class TZDBNames; diff --git a/deps/icu-small/source/i18n/tzrule.cpp b/deps/icu-small/source/i18n/tzrule.cpp index 59e1f44c87..2ff61302b8 100644 --- a/deps/icu-small/source/i18n/tzrule.cpp +++ b/deps/icu-small/source/i18n/tzrule.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2007-2012, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/tztrans.cpp b/deps/icu-small/source/i18n/tztrans.cpp index 6e0ddf6d39..76e259c5ae 100644 --- a/deps/icu-small/source/i18n/tztrans.cpp +++ b/deps/icu-small/source/i18n/tztrans.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2007-2012, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/ucal.cpp b/deps/icu-small/source/i18n/ucal.cpp index c405701ece..a9377b1e51 100644 --- a/deps/icu-small/source/i18n/ucal.cpp +++ b/deps/icu-small/source/i18n/ucal.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 1996-2016, International Business Machines diff --git a/deps/icu-small/source/i18n/ucln_in.cpp b/deps/icu-small/source/i18n/ucln_in.cpp index 49e6b37fd0..b33a689237 100644 --- a/deps/icu-small/source/i18n/ucln_in.cpp +++ b/deps/icu-small/source/i18n/ucln_in.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * * @@ -28,7 +30,7 @@ static const char copyright[] = U_COPYRIGHT_STRING; static cleanupFunc *gCleanupFunctions[UCLN_I18N_COUNT]; -static UBool i18n_cleanup(void) +static UBool U_CALLCONV i18n_cleanup(void) { int32_t libType = UCLN_I18N_START; (void)copyright; /* Suppress unused variable warning with clang. */ diff --git a/deps/icu-small/source/i18n/ucln_in.h b/deps/icu-small/source/i18n/ucln_in.h index 3fdec6db0d..b609fce0c2 100644 --- a/deps/icu-small/source/i18n/ucln_in.h +++ b/deps/icu-small/source/i18n/ucln_in.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * Copyright (C) 2001-2016, International Business Machines @@ -24,8 +26,8 @@ as the functions are suppose to be called. It's usually best to have child dependencies called first. */ typedef enum ECleanupI18NType { UCLN_I18N_START = -1, - UCLN_I18N_IDENTIFIER_INFO, UCLN_I18N_SPOOF, + UCLN_I18N_SPOOFDATA, UCLN_I18N_TRANSLITERATOR, UCLN_I18N_REGEX, UCLN_I18N_ISLAMIC_CALENDAR, @@ -40,6 +42,7 @@ typedef enum ECleanupI18NType { UCLN_I18N_TIMEZONENAMES, UCLN_I18N_ZONEMETA, UCLN_I18N_TIMEZONE, + UCLN_I18N_DIGITLIST, UCLN_I18N_DECFMT, UCLN_I18N_NUMFMT, UCLN_I18N_ALLOWED_HOUR_FORMATS, diff --git a/deps/icu-small/source/i18n/ucol.cpp b/deps/icu-small/source/i18n/ucol.cpp index b950756d40..c622aef7c2 100644 --- a/deps/icu-small/source/i18n/ucol.cpp +++ b/deps/icu-small/source/i18n/ucol.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 1996-2015, International Business Machines diff --git a/deps/icu-small/source/i18n/ucol_imp.h b/deps/icu-small/source/i18n/ucol_imp.h index bfa2bb445a..7c9e8f6891 100644 --- a/deps/icu-small/source/i18n/ucol_imp.h +++ b/deps/icu-small/source/i18n/ucol_imp.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * @@ -76,7 +78,7 @@ public: const CollationCacheEntry *createCacheEntry(UErrorCode &errorCode); private: - static void loadRootRules(UErrorCode &errorCode); + static void U_CALLCONV loadRootRules(UErrorCode &errorCode); // The following members are used by loadTailoring() // and the cache callback. diff --git a/deps/icu-small/source/i18n/ucol_res.cpp b/deps/icu-small/source/i18n/ucol_res.cpp index d7e2ab427c..314b766ee6 100644 --- a/deps/icu-small/source/i18n/ucol_res.cpp +++ b/deps/icu-small/source/i18n/ucol_res.cpp @@ -1,6 +1,8 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* -* Copyright (C) 1996-2014, International Business Machines +* Copyright (C) 1996-2016, International Business Machines * Corporation and others. All Rights Reserved. ******************************************************************************* * file name: ucol_res.cpp @@ -34,11 +36,13 @@ #include "unicode/uloc.h" #include "unicode/unistr.h" #include "unicode/ures.h" +#include "charstr.h" #include "cmemory.h" #include "cstring.h" #include "collationdatareader.h" #include "collationroot.h" #include "collationtailoring.h" +#include "resource.h" #include "putilimp.h" #include "uassert.h" #include "ucln_in.h" @@ -74,9 +78,7 @@ ucol_res_cleanup() { return TRUE; } -U_CDECL_END - -void +void U_CALLCONV CollationLoader::loadRootRules(UErrorCode &errorCode) { if(U_FAILURE(errorCode)) { return; } rootBundle = ures_open(U_ICUDATA_COLL, kRootLocaleName, &errorCode); @@ -90,6 +92,8 @@ CollationLoader::loadRootRules(UErrorCode &errorCode) { ucln_i18n_registerCleanup(UCLN_I18N_UCOL_RES, ucol_res_cleanup); } +U_CDECL_END + void CollationLoader::appendRootRules(UnicodeString &s) { UErrorCode errorCode = U_ZERO_ERROR; @@ -501,8 +505,6 @@ U_CAPI UCollator* ucol_open(const char *loc, UErrorCode *status) { - U_NAMESPACE_USE - UTRACE_ENTRY_OC(UTRACE_UCOL_OPEN); UTRACE_DATA1(UTRACE_INFO, "locale = \"%s\"", loc); UCollator *result = NULL; @@ -523,8 +525,6 @@ ucol_getDisplayName( const char *objLoc, int32_t resultLength, UErrorCode *status) { - U_NAMESPACE_USE - if(U_FAILURE(*status)) return -1; UnicodeString dst; if(!(result==NULL && resultLength==0)) { @@ -558,8 +558,6 @@ ucol_countAvailable() #if !UCONFIG_NO_SERVICE U_CAPI UEnumeration* U_EXPORT2 ucol_openAvailableLocales(UErrorCode *status) { - U_NAMESPACE_USE - // This is a wrapper over Collator::getAvailableLocales() if (U_FAILURE(*status)) { return NULL; @@ -615,119 +613,75 @@ static const UEnumeration defaultKeywordValues = { ulist_reset_keyword_values_iterator }; -#include <stdio.h> - -U_CAPI UEnumeration* U_EXPORT2 -ucol_getKeywordValuesForLocale(const char* /*key*/, const char* locale, - UBool /*commonlyUsed*/, UErrorCode* status) { - /* Get the locale base name. */ - char localeBuffer[ULOC_FULLNAME_CAPACITY] = ""; - uloc_getBaseName(locale, localeBuffer, sizeof(localeBuffer), status); - - /* Create the 2 lists - * -values is the temp location for the keyword values - * -results hold the actual list used by the UEnumeration object - */ - UList *values = ulist_createEmptyList(status); - UList *results = ulist_createEmptyList(status); - UEnumeration *en = (UEnumeration *)uprv_malloc(sizeof(UEnumeration)); - if (U_FAILURE(*status) || en == NULL) { - if (en == NULL) { - *status = U_MEMORY_ALLOCATION_ERROR; - } else { - uprv_free(en); - } - ulist_deleteList(values); - ulist_deleteList(results); - return NULL; - } +namespace { - memcpy(en, &defaultKeywordValues, sizeof(UEnumeration)); - en->context = results; - - /* Open the resource bundle for collation with the given locale. */ - UResourceBundle bundle, collations, collres, defres; - ures_initStackObject(&bundle); - ures_initStackObject(&collations); - ures_initStackObject(&collres); - ures_initStackObject(&defres); - - ures_openFillIn(&bundle, U_ICUDATA_COLL, localeBuffer, status); - - while (U_SUCCESS(*status)) { - ures_getByKey(&bundle, RESOURCE_NAME, &collations, status); - ures_resetIterator(&collations); - while (U_SUCCESS(*status) && ures_hasNext(&collations)) { - ures_getNextResource(&collations, &collres, status); - const char *key = ures_getKey(&collres); - /* If the key is default, get the string and store it in results list only - * if results list is empty. - */ - if (uprv_strcmp(key, "default") == 0) { - if (ulist_getListSize(results) == 0) { - char *defcoll = (char *)uprv_malloc(sizeof(char) * ULOC_KEYWORDS_CAPACITY); - int32_t defcollLength = ULOC_KEYWORDS_CAPACITY; - - ures_getNextResource(&collres, &defres, status); -#if U_CHARSET_FAMILY==U_ASCII_FAMILY - /* optimize - use the utf-8 string */ - ures_getUTF8String(&defres, defcoll, &defcollLength, TRUE, status); -#else - { - const UChar* defString = ures_getString(&defres, &defcollLength, status); - if(U_SUCCESS(*status)) { - if(defcollLength+1 > ULOC_KEYWORDS_CAPACITY) { - *status = U_BUFFER_OVERFLOW_ERROR; - } else { - u_UCharsToChars(defString, defcoll, defcollLength+1); - } - } +struct KeywordsSink : public ResourceSink { +public: + KeywordsSink(UErrorCode &errorCode) : + values(ulist_createEmptyList(&errorCode)), hasDefault(FALSE) {} + virtual ~KeywordsSink(); + + virtual void put(const char *key, ResourceValue &value, UBool /*noFallback*/, + UErrorCode &errorCode) { + if (U_FAILURE(errorCode)) { return; } + ResourceTable collations = value.getTable(errorCode); + for (int32_t i = 0; collations.getKeyAndValue(i, key, value); ++i) { + UResType type = value.getType(); + if (type == URES_STRING) { + if (!hasDefault && uprv_strcmp(key, "default") == 0) { + CharString defcoll; + defcoll.appendInvariantChars(value.getUnicodeString(errorCode), errorCode); + if (U_SUCCESS(errorCode) && !defcoll.isEmpty()) { + char *ownedDefault = uprv_strdup(defcoll.data()); + if (ownedDefault == NULL) { + errorCode = U_MEMORY_ALLOCATION_ERROR; + return; + } + ulist_removeString(values, defcoll.data()); + ulist_addItemBeginList(values, ownedDefault, TRUE, &errorCode); + hasDefault = TRUE; } -#endif - - ulist_addItemBeginList(results, defcoll, TRUE, status); } - } else if (uprv_strncmp(key, "private-", 8) != 0) { - ulist_addItemEndList(values, key, FALSE, status); - } - } - - /* If the locale is "" this is root so exit. */ - if (uprv_strlen(localeBuffer) == 0) { - break; - } - /* Get the parent locale and open a new resource bundle. */ - uloc_getParent(localeBuffer, localeBuffer, sizeof(localeBuffer), status); - ures_openFillIn(&bundle, U_ICUDATA_COLL, localeBuffer, status); - } - - ures_close(&defres); - ures_close(&collres); - ures_close(&collations); - ures_close(&bundle); - - if (U_SUCCESS(*status)) { - char *value = NULL; - ulist_resetList(values); - while ((value = (char *)ulist_getNext(values)) != NULL) { - if (!ulist_containsString(results, value, (int32_t)uprv_strlen(value))) { - ulist_addItemEndList(results, value, FALSE, status); - if (U_FAILURE(*status)) { - break; + } else if (type == URES_TABLE && uprv_strncmp(key, "private-", 8) != 0) { + if (!ulist_containsString(values, key, (int32_t)uprv_strlen(key))) { + ulist_addItemEndList(values, key, FALSE, &errorCode); } } + if (U_FAILURE(errorCode)) { return; } } } + UList *values; + UBool hasDefault; +}; + +KeywordsSink::~KeywordsSink() { ulist_deleteList(values); +} - if (U_FAILURE(*status)){ - uenum_close(en); - en = NULL; - } else { - ulist_resetList(results); - } +} // namespace + +U_CAPI UEnumeration* U_EXPORT2 +ucol_getKeywordValuesForLocale(const char* /*key*/, const char* locale, + UBool /*commonlyUsed*/, UErrorCode* status) { + // Note: The parameter commonlyUsed is not used. + // The switch is in the method signature for consistency + // with other locale services. + + // Read available collation values from collation bundles. + LocalUResourceBundlePointer bundle(ures_open(U_ICUDATA_COLL, locale, status)); + KeywordsSink sink(*status); + ures_getAllItemsWithFallback(bundle.getAlias(), RESOURCE_NAME, sink, *status); + if (U_FAILURE(*status)) { return NULL; } + UEnumeration *en = (UEnumeration *)uprv_malloc(sizeof(UEnumeration)); + if (en == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + return NULL; + } + memcpy(en, &defaultKeywordValues, sizeof(UEnumeration)); + en->context = sink.values; + sink.values = NULL; // Avoid deletion in the sink destructor. return en; } diff --git a/deps/icu-small/source/i18n/ucol_sit.cpp b/deps/icu-small/source/i18n/ucol_sit.cpp index 5d9e0d4546..c81977b8a3 100644 --- a/deps/icu-small/source/i18n/ucol_sit.cpp +++ b/deps/icu-small/source/i18n/ucol_sit.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2004-2016, International Business Machines diff --git a/deps/icu-small/source/i18n/ucoleitr.cpp b/deps/icu-small/source/i18n/ucoleitr.cpp index 6ccabded67..4b46b205aa 100644 --- a/deps/icu-small/source/i18n/ucoleitr.cpp +++ b/deps/icu-small/source/i18n/ucoleitr.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * Copyright (C) 2001-2016, International Business Machines @@ -34,9 +36,9 @@ U_NAMESPACE_USE #define DEFAULT_BUFFER_SIZE 16 #define BUFFER_GROW 8 -#define ARRAY_COPY(dst, src, count) uprv_memcpy((void *) (dst), (void *) (src), (count) * sizeof (src)[0]) +#define ARRAY_COPY(dst, src, count) uprv_memcpy((void *) (dst), (void *) (src), (size_t)(count) * sizeof (src)[0]) -#define NEW_ARRAY(type, count) (type *) uprv_malloc((count) * sizeof(type)) +#define NEW_ARRAY(type, count) (type *) uprv_malloc((size_t)(count) * sizeof(type)) #define DELETE_ARRAY(array) uprv_free((void *) (array)) diff --git a/deps/icu-small/source/i18n/ucsdet.cpp b/deps/icu-small/source/i18n/ucsdet.cpp index f0445427c7..dd69d9f548 100644 --- a/deps/icu-small/source/i18n/ucsdet.cpp +++ b/deps/icu-small/source/i18n/ucsdet.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** * Copyright (C) 2005-2016, International Business Machines diff --git a/deps/icu-small/source/i18n/udat.cpp b/deps/icu-small/source/i18n/udat.cpp index 7b65aa739a..b07e1ceab7 100644 --- a/deps/icu-small/source/i18n/udat.cpp +++ b/deps/icu-small/source/i18n/udat.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 1996-2015, International Business Machines diff --git a/deps/icu-small/source/i18n/udateintervalformat.cpp b/deps/icu-small/source/i18n/udateintervalformat.cpp index ef6fc197c7..e6eec44847 100644 --- a/deps/icu-small/source/i18n/udateintervalformat.cpp +++ b/deps/icu-small/source/i18n/udateintervalformat.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ***************************************************************************************** * Copyright (C) 2010-2011, International Business Machines diff --git a/deps/icu-small/source/i18n/udatpg.cpp b/deps/icu-small/source/i18n/udatpg.cpp index d0bafa30a8..d8824afdfc 100644 --- a/deps/icu-small/source/i18n/udatpg.cpp +++ b/deps/icu-small/source/i18n/udatpg.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * diff --git a/deps/icu-small/source/i18n/ufieldpositer.cpp b/deps/icu-small/source/i18n/ufieldpositer.cpp index 7f8688425d..b1c9c64805 100644 --- a/deps/icu-small/source/i18n/ufieldpositer.cpp +++ b/deps/icu-small/source/i18n/ufieldpositer.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ***************************************************************************************** * Copyright (C) 2015, International Business Machines diff --git a/deps/icu-small/source/i18n/uitercollationiterator.cpp b/deps/icu-small/source/i18n/uitercollationiterator.cpp index f717282eac..eb71725380 100644 --- a/deps/icu-small/source/i18n/uitercollationiterator.cpp +++ b/deps/icu-small/source/i18n/uitercollationiterator.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2012-2014, International Business Machines diff --git a/deps/icu-small/source/i18n/uitercollationiterator.h b/deps/icu-small/source/i18n/uitercollationiterator.h index a64f88561b..da9f8d3468 100644 --- a/deps/icu-small/source/i18n/uitercollationiterator.h +++ b/deps/icu-small/source/i18n/uitercollationiterator.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2012-2016, International Business Machines diff --git a/deps/icu-small/source/i18n/ulocdata.c b/deps/icu-small/source/i18n/ulocdata.c index fc84756d4c..e1e61ce870 100644 --- a/deps/icu-small/source/i18n/ulocdata.c +++ b/deps/icu-small/source/i18n/ulocdata.c @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * * diff --git a/deps/icu-small/source/i18n/umsg.cpp b/deps/icu-small/source/i18n/umsg.cpp index d4a55818cd..75647e37d6 100644 --- a/deps/icu-small/source/i18n/umsg.cpp +++ b/deps/icu-small/source/i18n/umsg.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * @@ -469,7 +471,7 @@ umsg_vformat( const UMessageFormat *fmt, } } UnicodeString resultStr; - FieldPosition fieldPosition(0); + FieldPosition fieldPosition(FieldPosition::DONT_CARE); /* format the message */ ((const MessageFormat*)fmt)->format(args,count,resultStr,fieldPosition,*status); diff --git a/deps/icu-small/source/i18n/umsg_imp.h b/deps/icu-small/source/i18n/umsg_imp.h index 78bbf966bc..e3538d3971 100644 --- a/deps/icu-small/source/i18n/umsg_imp.h +++ b/deps/icu-small/source/i18n/umsg_imp.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2001, International Business Machines diff --git a/deps/icu-small/source/i18n/unesctrn.cpp b/deps/icu-small/source/i18n/unesctrn.cpp index a4e9358ae6..2e79067dee 100644 --- a/deps/icu-small/source/i18n/unesctrn.cpp +++ b/deps/icu-small/source/i18n/unesctrn.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2001-2011, International Business Machines @@ -85,7 +87,7 @@ static UChar* copySpec(const UChar* spec) { UChar *result = (UChar *)uprv_malloc(len*sizeof(UChar)); // Check for memory allocation error. if (result != NULL) { - uprv_memcpy(result, spec, len*sizeof(result[0])); + uprv_memcpy(result, spec, (size_t)len*sizeof(result[0])); } return result; } diff --git a/deps/icu-small/source/i18n/unesctrn.h b/deps/icu-small/source/i18n/unesctrn.h index bfde6fc134..7ae8302b0f 100644 --- a/deps/icu-small/source/i18n/unesctrn.h +++ b/deps/icu-small/source/i18n/unesctrn.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2001-2007, International Business Machines diff --git a/deps/icu-small/source/i18n/uni2name.cpp b/deps/icu-small/source/i18n/uni2name.cpp index a10fa14c7f..24323b3f60 100644 --- a/deps/icu-small/source/i18n/uni2name.cpp +++ b/deps/icu-small/source/i18n/uni2name.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2001-2011, International Business Machines diff --git a/deps/icu-small/source/i18n/uni2name.h b/deps/icu-small/source/i18n/uni2name.h index aede864564..7d85113f66 100644 --- a/deps/icu-small/source/i18n/uni2name.h +++ b/deps/icu-small/source/i18n/uni2name.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2001-2007, International Business Machines diff --git a/deps/icu-small/source/i18n/unicode/alphaindex.h b/deps/icu-small/source/i18n/unicode/alphaindex.h index 9116ccc26c..e9e8739ed2 100644 --- a/deps/icu-small/source/i18n/unicode/alphaindex.h +++ b/deps/icu-small/source/i18n/unicode/alphaindex.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * diff --git a/deps/icu-small/source/i18n/unicode/basictz.h b/deps/icu-small/source/i18n/unicode/basictz.h index 5b47038250..8da4a00bf8 100644 --- a/deps/icu-small/source/i18n/unicode/basictz.h +++ b/deps/icu-small/source/i18n/unicode/basictz.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2007-2013, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/unicode/calendar.h b/deps/icu-small/source/i18n/unicode/calendar.h index 35252bb9c8..b7da5f3c5b 100644 --- a/deps/icu-small/source/i18n/unicode/calendar.h +++ b/deps/icu-small/source/i18n/unicode/calendar.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** * Copyright (C) 1997-2014, International Business Machines diff --git a/deps/icu-small/source/i18n/unicode/choicfmt.h b/deps/icu-small/source/i18n/unicode/choicfmt.h index cfd520624d..ab3c28fe07 100644 --- a/deps/icu-small/source/i18n/unicode/choicfmt.h +++ b/deps/icu-small/source/i18n/unicode/choicfmt.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** * Copyright (C) 1997-2013, International Business Machines diff --git a/deps/icu-small/source/i18n/unicode/coleitr.h b/deps/icu-small/source/i18n/unicode/coleitr.h index f07ada7b67..628b461f94 100644 --- a/deps/icu-small/source/i18n/unicode/coleitr.h +++ b/deps/icu-small/source/i18n/unicode/coleitr.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * Copyright (C) 1997-2014, International Business Machines diff --git a/deps/icu-small/source/i18n/unicode/coll.h b/deps/icu-small/source/i18n/unicode/coll.h index 5468342716..e41be2ee81 100644 --- a/deps/icu-small/source/i18n/unicode/coll.h +++ b/deps/icu-small/source/i18n/unicode/coll.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * Copyright (C) 1996-2016, International Business Machines diff --git a/deps/icu-small/source/i18n/unicode/compactdecimalformat.h b/deps/icu-small/source/i18n/unicode/compactdecimalformat.h index ced6bee599..1fcc5c581e 100644 --- a/deps/icu-small/source/i18n/unicode/compactdecimalformat.h +++ b/deps/icu-small/source/i18n/unicode/compactdecimalformat.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** * Copyright (C) 2012-2016, International Business Machines @@ -157,7 +159,6 @@ public: FieldPositionIterator* posIter, UErrorCode& status) const; - /* Cannot use #ifndef U_HIDE_DRAFT_API for the following draft method since it is virtual. */ /** * Format a long number using base-10 representation. * @@ -167,7 +168,7 @@ public: * @param pos On input: an alignment field, if desired. * On output: the offsets of the alignment field. * @return Reference to 'appendTo' parameter. - * @draft ICU 56 + * @stable ICU 56 */ virtual UnicodeString& format(int32_t number, UnicodeString& appendTo, @@ -274,7 +275,7 @@ public: * @return Reference to 'appendTo' parameter. * @internal */ - virtual UnicodeString& format(const StringPiece &number, + virtual UnicodeString& format(StringPiece number, UnicodeString& appendTo, FieldPositionIterator* posIter, UErrorCode& status) const; diff --git a/deps/icu-small/source/i18n/unicode/curramt.h b/deps/icu-small/source/i18n/unicode/curramt.h index ce9acbfd5c..268d53c0b1 100644 --- a/deps/icu-small/source/i18n/unicode/curramt.h +++ b/deps/icu-small/source/i18n/unicode/curramt.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2004-2006, International Business Machines diff --git a/deps/icu-small/source/i18n/unicode/currpinf.h b/deps/icu-small/source/i18n/unicode/currpinf.h index 4f1f8962c3..133de38fc2 100644 --- a/deps/icu-small/source/i18n/unicode/currpinf.h +++ b/deps/icu-small/source/i18n/unicode/currpinf.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2009-2015, International Business Machines Corporation and * diff --git a/deps/icu-small/source/i18n/unicode/currunit.h b/deps/icu-small/source/i18n/unicode/currunit.h index 93ecd2c489..313c92a6ac 100644 --- a/deps/icu-small/source/i18n/unicode/currunit.h +++ b/deps/icu-small/source/i18n/unicode/currunit.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2004-2014, International Business Machines diff --git a/deps/icu-small/source/i18n/unicode/datefmt.h b/deps/icu-small/source/i18n/unicode/datefmt.h index 2ccac79760..6e3a78f291 100644 --- a/deps/icu-small/source/i18n/unicode/datefmt.h +++ b/deps/icu-small/source/i18n/unicode/datefmt.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** * Copyright (C) 1997-2016, International Business Machines diff --git a/deps/icu-small/source/i18n/unicode/dcfmtsym.h b/deps/icu-small/source/i18n/unicode/dcfmtsym.h index 9b406b1417..946227addb 100644 --- a/deps/icu-small/source/i18n/unicode/dcfmtsym.h +++ b/deps/icu-small/source/i18n/unicode/dcfmtsym.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** * Copyright (C) 1997-2016, International Business Machines diff --git a/deps/icu-small/source/i18n/unicode/decimfmt.h b/deps/icu-small/source/i18n/unicode/decimfmt.h index e7f8ea592e..7339399f72 100644 --- a/deps/icu-small/source/i18n/unicode/decimfmt.h +++ b/deps/icu-small/source/i18n/unicode/decimfmt.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** * Copyright (C) 1997-2016, International Business Machines @@ -968,7 +970,7 @@ public: * Can be NULL. * @param status Output param filled with success/failure status. * @return Reference to 'appendTo' parameter. - * @stable 4.4 + * @stable ICU 4.4 */ virtual UnicodeString& format(double number, UnicodeString& appendTo, @@ -1017,7 +1019,7 @@ public: * Can be NULL. * @param status Output param filled with success/failure status. * @return Reference to 'appendTo' parameter. - * @stable 4.4 + * @stable ICU 4.4 */ virtual UnicodeString& format(int32_t number, UnicodeString& appendTo, @@ -1066,7 +1068,7 @@ public: * Can be NULL. * @param status Output param filled with success/failure status. * @return Reference to 'appendTo' parameter. - * @stable 4.4 + * @stable ICU 4.4 */ virtual UnicodeString& format(int64_t number, UnicodeString& appendTo, @@ -1087,9 +1089,9 @@ public: * Can be NULL. * @param status Output param filled with success/failure status. * @return Reference to 'appendTo' parameter. - * @stable 4.4 + * @stable ICU 4.4 */ - virtual UnicodeString& format(const StringPiece &number, + virtual UnicodeString& format(StringPiece number, UnicodeString& appendTo, FieldPositionIterator* posIter, UErrorCode& status) const; @@ -2101,6 +2103,8 @@ private: DecimalFormatSymbols* symbolsToAdopt = 0 ); + void handleCurrencySignInPattern(UErrorCode& status); + void parse(const UnicodeString& text, Formattable& result, ParsePosition& pos, diff --git a/deps/icu-small/source/i18n/unicode/dtfmtsym.h b/deps/icu-small/source/i18n/unicode/dtfmtsym.h index c338c46fac..507868e2c3 100644 --- a/deps/icu-small/source/i18n/unicode/dtfmtsym.h +++ b/deps/icu-small/source/i18n/unicode/dtfmtsym.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** * Copyright (C) 1997-2016, International Business Machines @@ -270,9 +272,15 @@ public: * @stable ICU 3.6 */ enum DtContextType { - FORMAT, - STANDALONE, - DT_CONTEXT_COUNT + FORMAT, + STANDALONE, +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal DtContextType value. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ + DT_CONTEXT_COUNT +#endif // U_HIDE_DEPRECATED_API }; /** @@ -280,17 +288,21 @@ public: * @stable ICU 3.6 */ enum DtWidthType { - ABBREVIATED, - WIDE, - NARROW, - /** - * Short width is currently only supported for weekday names. - * @stable ICU 51 - */ - SHORT, - /** - */ - DT_WIDTH_COUNT = 4 + ABBREVIATED, + WIDE, + NARROW, + /** + * Short width is currently only supported for weekday names. + * @stable ICU 51 + */ + SHORT, +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal DtWidthType value. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ + DT_WIDTH_COUNT = 4 +#endif // U_HIDE_DEPRECATED_API }; /** diff --git a/deps/icu-small/source/i18n/unicode/dtitvfmt.h b/deps/icu-small/source/i18n/unicode/dtitvfmt.h index 181d46c8e0..68360b87df 100644 --- a/deps/icu-small/source/i18n/unicode/dtitvfmt.h +++ b/deps/icu-small/source/i18n/unicode/dtitvfmt.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /******************************************************************************** * Copyright (C) 2008-2016, International Business Machines Corporation and * others. All Rights Reserved. diff --git a/deps/icu-small/source/i18n/unicode/dtitvinf.h b/deps/icu-small/source/i18n/unicode/dtitvinf.h index 1c7f3983df..b31061e16a 100644 --- a/deps/icu-small/source/i18n/unicode/dtitvinf.h +++ b/deps/icu-small/source/i18n/unicode/dtitvinf.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2008-2016, International Business Machines Corporation and @@ -150,7 +152,8 @@ U_NAMESPACE_BEGIN class U_I18N_API DateIntervalInfo U_FINAL : public UObject { public: -#ifndef U_HIDE_INTERNAL_API + // Do not enclose the protected default constructor with #ifndef U_HIDE_INTERNAL_API + // or else the compiler will create a public default constructor. /** * Default constructor. * It does not initialize any interval patterns except @@ -165,7 +168,6 @@ public: * @internal ICU 4.0 */ DateIntervalInfo(UErrorCode& status); -#endif /* U_HIDE_INTERNAL_API */ /** @@ -339,7 +341,10 @@ private: */ friend class DateIntervalFormat; - friend struct DateIntervalSink; + /** + * Internal struct used to load resource bundle data. + */ + struct DateIntervalSink; /** * Following is for saving the interval patterns. diff --git a/deps/icu-small/source/i18n/unicode/dtptngen.h b/deps/icu-small/source/i18n/unicode/dtptngen.h index eb8a44541e..fd617ce3cd 100644 --- a/deps/icu-small/source/i18n/unicode/dtptngen.h +++ b/deps/icu-small/source/i18n/unicode/dtptngen.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2007-2016, International Business Machines Corporation and @@ -116,7 +118,6 @@ public: */ UBool operator!=(const DateTimePatternGenerator& other) const; -#ifndef U_HIDE_DRAFT_API /** * Utility to return a unique skeleton from a given pattern. For example, * both "MMM-dd" and "dd/MMM" produce the skeleton "MMMdd". @@ -125,10 +126,9 @@ public: * @param status Output param set to success/failure code on exit, * which must not indicate a failure before the function call. * @return skeleton such as "MMMdd" - * @draft ICU 56 + * @stable ICU 56 */ static UnicodeString staticGetSkeleton(const UnicodeString& pattern, UErrorCode& status); -#endif /* U_HIDE_DRAFT_API */ /** * Utility to return a unique skeleton from a given pattern. For example, @@ -149,7 +149,6 @@ public: return staticGetSkeleton(pattern, status); }*/ -#ifndef U_HIDE_DRAFT_API /** * Utility to return a unique base skeleton from a given pattern. This is * the same as the skeleton, except that differences in length are minimized @@ -161,10 +160,9 @@ public: * @param status Output param set to success/failure code on exit, * which must not indicate a failure before the function call. * @return base skeleton, such as "MMMd" - * @draft ICU 56 + * @stable ICU 56 */ static UnicodeString staticGetBaseSkeleton(const UnicodeString& pattern, UErrorCode& status); -#endif /* U_HIDE_DRAFT_API */ /** * Utility to return a unique base skeleton from a given pattern. This is @@ -518,7 +516,6 @@ private: UnicodeString decimal; DateTimeMatcher *skipMatcher; Hashtable *fAvailableFormatKeyHash; - UnicodeString hackPattern; UnicodeString emptyString; UChar fDefaultHourFormatChar; @@ -534,9 +531,11 @@ private: }; void initData(const Locale &locale, UErrorCode &status); - void addCanonicalItems(); + void addCanonicalItems(UErrorCode &status); void addICUPatterns(const Locale& locale, UErrorCode& status); void hackTimes(const UnicodeString& hackPattern, UErrorCode& status); + void getCalendarTypeToUse(const Locale& locale, CharString& destination, UErrorCode& err); + void consumeShortTimePattern(const UnicodeString& shortTimePattern, UErrorCode& status); void addCLDRData(const Locale& locale, UErrorCode& status); UDateTimePatternConflict addPatternWithSkeleton(const UnicodeString& pattern, const UnicodeString * skeletonToUse, UBool override, UnicodeString& conflictingPattern, UErrorCode& status); void initHashtable(UErrorCode& status); @@ -544,6 +543,7 @@ private: void setDecimalSymbols(const Locale& locale, UErrorCode& status); UDateTimePatternField getAppendFormatNumber(const char* field) const; UDateTimePatternField getAppendNameNumber(const char* field) const; + UnicodeString& getMutableAppendItemName(UDateTimePatternField field); void getAppendName(UDateTimePatternField field, UnicodeString& value); int32_t getCanonicalIndex(const UnicodeString& field); const UnicodeString* getBestRaw(DateTimeMatcher& source, int32_t includeMask, DistanceInfo* missingFields, const PtnSkeleton** specifiedSkeletonPtr = 0); @@ -554,8 +554,12 @@ private: UBool isAvailableFormatSet(const UnicodeString &key) const; void copyHashtable(Hashtable *other, UErrorCode &status); UBool isCanonicalItem(const UnicodeString& item) const; - static void loadAllowedHourFormatsData(UErrorCode &status); + static void U_CALLCONV loadAllowedHourFormatsData(UErrorCode &status); void getAllowedHourFormats(const Locale &locale, UErrorCode &status); + + struct AppendItemFormatsSink; + struct AppendItemNamesSink; + struct AvailableFormatsSink; } ;// end class DateTimePatternGenerator U_NAMESPACE_END diff --git a/deps/icu-small/source/i18n/unicode/dtrule.h b/deps/icu-small/source/i18n/unicode/dtrule.h index 3ef080b4eb..32d230ea77 100644 --- a/deps/icu-small/source/i18n/unicode/dtrule.h +++ b/deps/icu-small/source/i18n/unicode/dtrule.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2007-2008, International Business Machines Corporation and * diff --git a/deps/icu-small/source/i18n/unicode/fieldpos.h b/deps/icu-small/source/i18n/unicode/fieldpos.h index b3d64b4e84..6091941106 100644 --- a/deps/icu-small/source/i18n/unicode/fieldpos.h +++ b/deps/icu-small/source/i18n/unicode/fieldpos.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** * Copyright (C) 1997-2006, International Business Machines @@ -56,7 +58,7 @@ U_NAMESPACE_BEGIN * to perform partial formatting or to get information about the * formatted output (such as the position of a field). * - * The FieldPosition class is not suitable for subclassing. + * The FieldPosition class is not intended for public subclassing. * * <p> * Below is an example of using <code>FieldPosition</code> to aid @@ -107,7 +109,8 @@ class U_I18N_API FieldPosition : public UObject { public: /** * DONT_CARE may be specified as the field to indicate that the - * caller doesn't need to specify a field. Do not subclass. + * caller doesn't need to specify a field. + * @stable ICU 2.0 */ enum { DONT_CARE = -1 }; diff --git a/deps/icu-small/source/i18n/unicode/fmtable.h b/deps/icu-small/source/i18n/unicode/fmtable.h index 6cad276f42..ac5daba893 100644 --- a/deps/icu-small/source/i18n/unicode/fmtable.h +++ b/deps/icu-small/source/i18n/unicode/fmtable.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** * Copyright (C) 1997-2014, International Business Machines @@ -134,7 +136,7 @@ public: * decimal number. * @stable ICU 4.4 */ - Formattable(const StringPiece &number, UErrorCode &status); + Formattable(StringPiece number, UErrorCode &status); /** * Creates a Formattable object with a UnicodeString object to copy from. @@ -581,7 +583,7 @@ public: * incoming string is not a valid decimal number. * @stable ICU 4.4 */ - void setDecimalNumber(const StringPiece &numberString, + void setDecimalNumber(StringPiece numberString, UErrorCode &status); /** diff --git a/deps/icu-small/source/i18n/unicode/format.h b/deps/icu-small/source/i18n/unicode/format.h index 7bbd32df6a..1484e9f00e 100644 --- a/deps/icu-small/source/i18n/unicode/format.h +++ b/deps/icu-small/source/i18n/unicode/format.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** * Copyright (C) 1997-2011, International Business Machines Corporation and others. diff --git a/deps/icu-small/source/i18n/unicode/fpositer.h b/deps/icu-small/source/i18n/unicode/fpositer.h index 20e78714dc..694a1d8770 100644 --- a/deps/icu-small/source/i18n/unicode/fpositer.h +++ b/deps/icu-small/source/i18n/unicode/fpositer.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** * Copyright (C) 2010-2012, International Business Machines diff --git a/deps/icu-small/source/i18n/unicode/gender.h b/deps/icu-small/source/i18n/unicode/gender.h index cbb73916c6..0294895184 100644 --- a/deps/icu-small/source/i18n/unicode/gender.h +++ b/deps/icu-small/source/i18n/unicode/gender.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2008-2013, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/unicode/gregocal.h b/deps/icu-small/source/i18n/unicode/gregocal.h index 1e507d3bb7..60ba0cc6ac 100644 --- a/deps/icu-small/source/i18n/unicode/gregocal.h +++ b/deps/icu-small/source/i18n/unicode/gregocal.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* * Copyright (C) 1997-2013, International Business Machines Corporation and others. * All Rights Reserved. diff --git a/deps/icu-small/source/i18n/unicode/measfmt.h b/deps/icu-small/source/i18n/unicode/measfmt.h index c177a963f8..866d7d3227 100644 --- a/deps/icu-small/source/i18n/unicode/measfmt.h +++ b/deps/icu-small/source/i18n/unicode/measfmt.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2004-2016, International Business Machines @@ -59,11 +61,13 @@ enum UMeasureFormatWidth { */ UMEASFMT_WIDTH_NUMERIC, +#ifndef U_HIDE_DEPRECATED_API /** - * Count of values in this enum. - * @stable ICU 53 + * One more than the highest normal UMeasureFormatWidth value. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. */ UMEASFMT_WIDTH_COUNT = 4 +#endif // U_HIDE_DEPRECATED_API }; /** @stable ICU 53 */ typedef enum UMeasureFormatWidth UMeasureFormatWidth; @@ -206,6 +210,21 @@ class U_I18N_API MeasureFormat : public Format { FieldPosition &pos, UErrorCode &status) const; +#ifndef U_HIDE_DRAFT_API + /** + * Gets the display name of the specified {@link MeasureUnit} corresponding to the current + * locale and format width. + * @param unit The unit for which to get a display name. + * @param status the error. + * @return The display name in the locale and width specified in + * {@link MeasureFormat#getInstance}, or null if there is no display name available + * for the specified unit. + * + * @draft ICU 58 + */ + UnicodeString getUnitDisplayName(const MeasureUnit& unit, UErrorCode &status) const; +#endif /* U_HIDE_DRAFT_API */ + /** * Return a formatter for CurrencyAmount objects in the given diff --git a/deps/icu-small/source/i18n/unicode/measunit.h b/deps/icu-small/source/i18n/unicode/measunit.h index 8f8c92415b..9810b91194 100644 --- a/deps/icu-small/source/i18n/unicode/measunit.h +++ b/deps/icu-small/source/i18n/unicode/measunit.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2004-2016, International Business Machines @@ -255,15 +257,13 @@ class U_I18N_API MeasureUnit: public UObject { */ static MeasureUnit *createRadian(UErrorCode &status); -#ifndef U_HIDE_DRAFT_API /** * Returns unit of angle: revolution. * Caller owns returned value and must free it. * @param status ICU error code. - * @draft ICU 56 + * @stable ICU 56 */ static MeasureUnit *createRevolutionAngle(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ /** * Returns unit of area: acre. @@ -375,15 +375,13 @@ class U_I18N_API MeasureUnit: public UObject { static MeasureUnit *createPartPerMillion(UErrorCode &status); #endif /* U_HIDE_DRAFT_API */ -#ifndef U_HIDE_DRAFT_API /** * Returns unit of consumption: liter-per-100kilometers. * Caller owns returned value and must free it. * @param status ICU error code. - * @draft ICU 56 + * @stable ICU 56 */ static MeasureUnit *createLiterPer100Kilometers(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ /** * Returns unit of consumption: liter-per-kilometer. @@ -411,6 +409,46 @@ class U_I18N_API MeasureUnit: public UObject { static MeasureUnit *createMilePerGallonImperial(UErrorCode &status); #endif /* U_HIDE_DRAFT_API */ +#ifndef U_HIDE_DRAFT_API + /** + * Returns unit of coordinate: east. + * Caller owns returned value and must free it. + * @param status ICU error code. + * @draft ICU 58 + */ + static MeasureUnit *createEast(UErrorCode &status); +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API + /** + * Returns unit of coordinate: north. + * Caller owns returned value and must free it. + * @param status ICU error code. + * @draft ICU 58 + */ + static MeasureUnit *createNorth(UErrorCode &status); +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API + /** + * Returns unit of coordinate: south. + * Caller owns returned value and must free it. + * @param status ICU error code. + * @draft ICU 58 + */ + static MeasureUnit *createSouth(UErrorCode &status); +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API + /** + * Returns unit of coordinate: west. + * Caller owns returned value and must free it. + * @param status ICU error code. + * @draft ICU 58 + */ + static MeasureUnit *createWest(UErrorCode &status); +#endif /* U_HIDE_DRAFT_API */ + /** * Returns unit of digital: bit. * Caller owns returned value and must free it. @@ -491,15 +529,13 @@ class U_I18N_API MeasureUnit: public UObject { */ static MeasureUnit *createTerabyte(UErrorCode &status); -#ifndef U_HIDE_DRAFT_API /** * Returns unit of duration: century. * Caller owns returned value and must free it. * @param status ICU error code. - * @draft ICU 56 + * @stable ICU 56 */ static MeasureUnit *createCentury(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ /** * Returns unit of duration: day. @@ -789,15 +825,13 @@ class U_I18N_API MeasureUnit: public UObject { */ static MeasureUnit *createMile(UErrorCode &status); -#ifndef U_HIDE_DRAFT_API /** * Returns unit of length: mile-scandinavian. * Caller owns returned value and must free it. * @param status ICU error code. - * @draft ICU 56 + * @stable ICU 56 */ static MeasureUnit *createMileScandinavian(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ /** * Returns unit of length: millimeter. @@ -1039,15 +1073,13 @@ class U_I18N_API MeasureUnit: public UObject { */ static MeasureUnit *createKilometerPerHour(UErrorCode &status); -#ifndef U_HIDE_DRAFT_API /** * Returns unit of speed: knot. * Caller owns returned value and must free it. * @param status ICU error code. - * @draft ICU 56 + * @stable ICU 56 */ static MeasureUnit *createKnot(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ /** * Returns unit of speed: meter-per-second. @@ -1081,15 +1113,13 @@ class U_I18N_API MeasureUnit: public UObject { */ static MeasureUnit *createFahrenheit(UErrorCode &status); -#ifndef U_HIDE_DRAFT_API /** * Returns unit of temperature: generic. * Caller owns returned value and must free it. * @param status ICU error code. - * @draft ICU 56 + * @stable ICU 56 */ static MeasureUnit *createGenericTemperature(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ /** * Returns unit of temperature: kelvin. @@ -1187,15 +1217,13 @@ class U_I18N_API MeasureUnit: public UObject { */ static MeasureUnit *createCup(UErrorCode &status); -#ifndef U_HIDE_DRAFT_API /** * Returns unit of volume: cup-metric. * Caller owns returned value and must free it. * @param status ICU error code. - * @draft ICU 56 + * @stable ICU 56 */ static MeasureUnit *createCupMetric(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ /** * Returns unit of volume: deciliter. @@ -1271,15 +1299,13 @@ class U_I18N_API MeasureUnit: public UObject { */ static MeasureUnit *createPint(UErrorCode &status); -#ifndef U_HIDE_DRAFT_API /** * Returns unit of volume: pint-metric. * Caller owns returned value and must free it. * @param status ICU error code. - * @draft ICU 56 + * @stable ICU 56 */ static MeasureUnit *createPintMetric(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ /** * Returns unit of volume: quart. diff --git a/deps/icu-small/source/i18n/unicode/measure.h b/deps/icu-small/source/i18n/unicode/measure.h index a9c7598996..719bc6bc8f 100644 --- a/deps/icu-small/source/i18n/unicode/measure.h +++ b/deps/icu-small/source/i18n/unicode/measure.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2004-2015, International Business Machines diff --git a/deps/icu-small/source/i18n/unicode/msgfmt.h b/deps/icu-small/source/i18n/unicode/msgfmt.h index 5de91e41ff..1a9973872d 100644 --- a/deps/icu-small/source/i18n/unicode/msgfmt.h +++ b/deps/icu-small/source/i18n/unicode/msgfmt.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* * Copyright (C) 2007-2013, International Business Machines Corporation and * others. All Rights Reserved. diff --git a/deps/icu-small/source/i18n/unicode/numfmt.h b/deps/icu-small/source/i18n/unicode/numfmt.h index 072b566da1..9e3d5d34ec 100644 --- a/deps/icu-small/source/i18n/unicode/numfmt.h +++ b/deps/icu-small/source/i18n/unicode/numfmt.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** * Copyright (C) 1997-2016, International Business Machines Corporation and others. @@ -266,7 +268,7 @@ public: * NULL. * @param status Output param filled with success/failure status. * @return Reference to 'appendTo' parameter. - * @stable 4.4 + * @stable ICU 4.4 */ virtual UnicodeString& format(const Formattable& obj, UnicodeString& appendTo, @@ -389,7 +391,7 @@ public: * Can be NULL. * @param status Output param filled with success/failure status. * @return Reference to 'appendTo' parameter. - * @stable 4.4 + * @stable ICU 4.4 */ virtual UnicodeString& format(double number, UnicodeString& appendTo, @@ -441,7 +443,7 @@ public: * Can be NULL. * @param status Output param filled with success/failure status. * @return Reference to 'appendTo' parameter. - * @stable 4.4 + * @stable ICU 4.4 */ virtual UnicodeString& format(int32_t number, UnicodeString& appendTo, @@ -494,7 +496,7 @@ public: * Can be NULL. * @param status Output param filled with success/failure status. * @return Reference to 'appendTo' parameter. - * @stable 4.4 + * @stable ICU 4.4 */ virtual UnicodeString& format(int64_t number, UnicodeString& appendTo, @@ -515,9 +517,9 @@ public: * Can be NULL. * @param status Output param filled with success/failure status. * @return Reference to 'appendTo' parameter. - * @stable 4.4 + * @stable ICU 4.4 */ - virtual UnicodeString& format(const StringPiece &number, + virtual UnicodeString& format(StringPiece number, UnicodeString& appendTo, FieldPositionIterator* posIter, UErrorCode& status) const; diff --git a/deps/icu-small/source/i18n/unicode/numsys.h b/deps/icu-small/source/i18n/unicode/numsys.h index 2b21afc074..da181551c2 100644 --- a/deps/icu-small/source/i18n/unicode/numsys.h +++ b/deps/icu-small/source/i18n/unicode/numsys.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2010-2014, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/unicode/plurfmt.h b/deps/icu-small/source/i18n/unicode/plurfmt.h index 6b417b8d57..b10e4179b6 100644 --- a/deps/icu-small/source/i18n/unicode/plurfmt.h +++ b/deps/icu-small/source/i18n/unicode/plurfmt.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2007-2014, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/unicode/plurrule.h b/deps/icu-small/source/i18n/unicode/plurrule.h index 7abd657408..146e6bea83 100644 --- a/deps/icu-small/source/i18n/unicode/plurrule.h +++ b/deps/icu-small/source/i18n/unicode/plurrule.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2008-2015, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/unicode/rbnf.h b/deps/icu-small/source/i18n/unicode/rbnf.h index 2cd02e70f1..14230f8982 100644 --- a/deps/icu-small/source/i18n/unicode/rbnf.h +++ b/deps/icu-small/source/i18n/unicode/rbnf.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 1997-2015, International Business Machines Corporation and others. @@ -54,7 +56,13 @@ enum URBNFRuleSetTag { URBNF_ORDINAL, URBNF_DURATION, URBNF_NUMBERING_SYSTEM, +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal URBNFRuleSetTag value. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ URBNF_COUNT +#endif // U_HIDE_DEPRECATED_API }; /** diff --git a/deps/icu-small/source/i18n/unicode/rbtz.h b/deps/icu-small/source/i18n/unicode/rbtz.h index 79805dd64e..20de34bb17 100644 --- a/deps/icu-small/source/i18n/unicode/rbtz.h +++ b/deps/icu-small/source/i18n/unicode/rbtz.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2007-2013, International Business Machines Corporation and * diff --git a/deps/icu-small/source/i18n/unicode/regex.h b/deps/icu-small/source/i18n/unicode/regex.h index 2333f96b25..96c64874a4 100644 --- a/deps/icu-small/source/i18n/unicode/regex.h +++ b/deps/icu-small/source/i18n/unicode/regex.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2002-2016, International Business Machines diff --git a/deps/icu-small/source/i18n/unicode/region.h b/deps/icu-small/source/i18n/unicode/region.h index 2e1ac82a62..47829944a3 100644 --- a/deps/icu-small/source/i18n/unicode/region.h +++ b/deps/icu-small/source/i18n/unicode/region.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2014-2016, International Business Machines Corporation and others. @@ -210,7 +212,7 @@ private: * anything meaningful. */ - static void loadRegionData(UErrorCode &status); + static void U_CALLCONV loadRegionData(UErrorCode &status); }; diff --git a/deps/icu-small/source/i18n/unicode/reldatefmt.h b/deps/icu-small/source/i18n/unicode/reldatefmt.h index b336e2fe3d..8e659e2bc8 100644 --- a/deps/icu-small/source/i18n/unicode/reldatefmt.h +++ b/deps/icu-small/source/i18n/unicode/reldatefmt.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ***************************************************************************** * Copyright (C) 2014-2016, International Business Machines Corporation and @@ -23,7 +25,7 @@ * \brief C++ API: Formats relative dates such as "1 day ago" or "tomorrow" */ -#if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_BREAK_ITERATION +#if !UCONFIG_NO_FORMATTING /** * Represents the unit for formatting a relative date. e.g "in 5 days" @@ -74,11 +76,13 @@ typedef enum UDateRelativeUnit { */ UDAT_RELATIVE_YEARS, +#ifndef U_HIDE_DEPRECATED_API /** - * Count of items in this enum. - * @stable ICU 53 + * One more than the highest normal UDateRelativeUnit value. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. */ UDAT_RELATIVE_UNIT_COUNT +#endif // U_HIDE_DEPRECATED_API } UDateRelativeUnit; /** @@ -161,11 +165,13 @@ typedef enum UDateAbsoluteUnit { */ UDAT_ABSOLUTE_NOW, +#ifndef U_HIDE_DEPRECATED_API /** - * Count of items in this enum. - * @stable ICU 53 + * One more than the highest normal UDateAbsoluteUnit value. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. */ UDAT_ABSOLUTE_UNIT_COUNT +#endif // U_HIDE_DEPRECATED_API } UDateAbsoluteUnit; /** @@ -211,13 +217,16 @@ typedef enum UDateDirection { */ UDAT_DIRECTION_PLAIN, +#ifndef U_HIDE_DEPRECATED_API /** - * Count of items in this enum. - * @stable ICU 53 + * One more than the highest normal UDateDirection value. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. */ UDAT_DIRECTION_COUNT +#endif // U_HIDE_DEPRECATED_API } UDateDirection; +#if !UCONFIG_NO_BREAK_ITERATION U_NAMESPACE_BEGIN @@ -509,5 +518,6 @@ private: U_NAMESPACE_END -#endif /* !UCONFIG_NO_FORMATTING && !UCONFIG_NO_BREAK_ITERATION*/ -#endif +#endif /* !UCONFIG_NO_BREAK_ITERATION */ +#endif /* !UCONFIG_NO_FORMATTING */ +#endif /* __RELDATEFMT_H */ diff --git a/deps/icu-small/source/i18n/unicode/scientificnumberformatter.h b/deps/icu-small/source/i18n/unicode/scientificnumberformatter.h index 710238a796..0b34755dc2 100644 --- a/deps/icu-small/source/i18n/unicode/scientificnumberformatter.h +++ b/deps/icu-small/source/i18n/unicode/scientificnumberformatter.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2014-2016, International Business Machines diff --git a/deps/icu-small/source/i18n/unicode/search.h b/deps/icu-small/source/i18n/unicode/search.h index 5b65e88b9c..35a0552623 100644 --- a/deps/icu-small/source/i18n/unicode/search.h +++ b/deps/icu-small/source/i18n/unicode/search.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2001-2011 IBM and others. All rights reserved. diff --git a/deps/icu-small/source/i18n/unicode/selfmt.h b/deps/icu-small/source/i18n/unicode/selfmt.h index 635144bb9b..37a8f2b821 100644..100755 --- a/deps/icu-small/source/i18n/unicode/selfmt.h +++ b/deps/icu-small/source/i18n/unicode/selfmt.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /******************************************************************** * COPYRIGHT: * Copyright (c) 1997-2011, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/unicode/simpletz.h b/deps/icu-small/source/i18n/unicode/simpletz.h index a0639d6a70..7e41a4ab8a 100644 --- a/deps/icu-small/source/i18n/unicode/simpletz.h +++ b/deps/icu-small/source/i18n/unicode/simpletz.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** * Copyright (C) 1997-2013, International Business Machines * diff --git a/deps/icu-small/source/i18n/unicode/smpdtfmt.h b/deps/icu-small/source/i18n/unicode/smpdtfmt.h index b7fa42054d..e6cf28d22b 100644 --- a/deps/icu-small/source/i18n/unicode/smpdtfmt.h +++ b/deps/icu-small/source/i18n/unicode/smpdtfmt.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* * Copyright (C) 1997-2016, International Business Machines Corporation and * others. All Rights Reserved. @@ -651,7 +653,7 @@ class SimpleDateFormatMutableNFs; * = new SimpleDateFormat ("yyyy.MM.dd G 'at' hh:mm:ss a zzz", success ); * GregorianCalendar cal(success); * UDate currentTime_1 = cal.getTime(success); - * FieldPosition fp(0); + * FieldPosition fp(FieldPosition::DONT_CARE); * UnicodeString dateString; * formatter->format( currentTime_1, dateString, fp ); * cout << "result: " << dateString << endl; @@ -999,6 +1001,12 @@ public: * (Presumably, letters that would be more mnemonic in that locale's * language.) This function would produce a pattern using those * letters. + * <p> + * <b>Note:</b> This implementation depends on DateFormatSymbols::getLocalPatternChars() + * to get localized format pattern characters. ICU does not include + * localized pattern character data, therefore, unless user sets localized + * pattern characters manually, this method returns the same result as + * toPattern(). * * @param result Receives the localized pattern. * @param status Output param set to success/failure code on diff --git a/deps/icu-small/source/i18n/unicode/sortkey.h b/deps/icu-small/source/i18n/unicode/sortkey.h index b4629d4e24..6f1543da40 100644 --- a/deps/icu-small/source/i18n/unicode/sortkey.h +++ b/deps/icu-small/source/i18n/unicode/sortkey.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ***************************************************************************** * Copyright (C) 1996-2014, International Business Machines Corporation and others. diff --git a/deps/icu-small/source/i18n/unicode/stsearch.h b/deps/icu-small/source/i18n/unicode/stsearch.h index 64317608b5..1cae53d128 100644 --- a/deps/icu-small/source/i18n/unicode/stsearch.h +++ b/deps/icu-small/source/i18n/unicode/stsearch.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2001-2014 IBM and others. All rights reserved. diff --git a/deps/icu-small/source/i18n/unicode/tblcoll.h b/deps/icu-small/source/i18n/unicode/tblcoll.h index 020c4b9606..c48ea38c13 100644 --- a/deps/icu-small/source/i18n/unicode/tblcoll.h +++ b/deps/icu-small/source/i18n/unicode/tblcoll.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * Copyright (C) 1996-2016, International Business Machines Corporation and @@ -854,7 +856,7 @@ private: */ UBool isUnsafe(UChar32 c) const; - static void computeMaxExpansions(const CollationTailoring *t, UErrorCode &errorCode); + static void U_CALLCONV computeMaxExpansions(const CollationTailoring *t, UErrorCode &errorCode); UBool initMaxExpansions(UErrorCode &errorCode) const; void setFastLatinOptions(CollationSettings &ownedSettings) const; diff --git a/deps/icu-small/source/i18n/unicode/timezone.h b/deps/icu-small/source/i18n/unicode/timezone.h index 6c72095537..58c84d062b 100644 --- a/deps/icu-small/source/i18n/unicode/timezone.h +++ b/deps/icu-small/source/i18n/unicode/timezone.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /************************************************************************* * Copyright (c) 1997-2016, International Business Machines Corporation * and others. All Rights Reserved. diff --git a/deps/icu-small/source/i18n/unicode/tmunit.h b/deps/icu-small/source/i18n/unicode/tmunit.h index e398ab96bd..a19a1f3c17 100644 --- a/deps/icu-small/source/i18n/unicode/tmunit.h +++ b/deps/icu-small/source/i18n/unicode/tmunit.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2009-2016, International Business Machines Corporation, * @@ -41,7 +43,13 @@ public: UTIMEUNIT_HOUR, UTIMEUNIT_MINUTE, UTIMEUNIT_SECOND, +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal UTimeUnitFields value. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ UTIMEUNIT_FIELD_COUNT +#endif // U_HIDE_DEPRECATED_API }; /** diff --git a/deps/icu-small/source/i18n/unicode/tmutamt.h b/deps/icu-small/source/i18n/unicode/tmutamt.h index ad8047a1f1..887150121f 100644 --- a/deps/icu-small/source/i18n/unicode/tmutamt.h +++ b/deps/icu-small/source/i18n/unicode/tmutamt.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2009-2010, Google, International Business Machines Corporation and * diff --git a/deps/icu-small/source/i18n/unicode/tmutfmt.h b/deps/icu-small/source/i18n/unicode/tmutfmt.h index 728ff13219..b90d4a096d 100644 --- a/deps/icu-small/source/i18n/unicode/tmutfmt.h +++ b/deps/icu-small/source/i18n/unicode/tmutfmt.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2008-2014, Google, International Business Machines Corporation @@ -50,6 +52,8 @@ U_NAMESPACE_BEGIN class Hashtable; class UVector; +struct TimeUnitFormatReadSink; + /** * Format or parse a TimeUnitAmount, using plural rules for the units where available. * @@ -227,6 +231,7 @@ private: // UTIMEUNIT_YEAR. static const char* getTimeUnitName(TimeUnit::UTimeUnitFields field, UErrorCode& status); + friend struct TimeUnitFormatReadSink; }; inline UBool diff --git a/deps/icu-small/source/i18n/unicode/translit.h b/deps/icu-small/source/i18n/unicode/translit.h index d41b5c0a80..1e49bfb969 100644 --- a/deps/icu-small/source/i18n/unicode/translit.h +++ b/deps/icu-small/source/i18n/unicode/translit.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 1999-2014, International Business Machines diff --git a/deps/icu-small/source/i18n/unicode/tzfmt.h b/deps/icu-small/source/i18n/unicode/tzfmt.h index 9b39bf0ee4..dd86f1b48c 100644 --- a/deps/icu-small/source/i18n/unicode/tzfmt.h +++ b/deps/icu-small/source/i18n/unicode/tzfmt.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2011-2015, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/unicode/tznames.h b/deps/icu-small/source/i18n/unicode/tznames.h index cbc9c1f3a8..8861a7d026 100644 --- a/deps/icu-small/source/i18n/unicode/tznames.h +++ b/deps/icu-small/source/i18n/unicode/tznames.h @@ -1,6 +1,8 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* -* Copyright (C) 2011-2015, International Business Machines Corporation and +* Copyright (C) 2011-2016, International Business Machines Corporation and * others. All Rights Reserved. ******************************************************************************* */ @@ -133,7 +135,7 @@ public: virtual ~TimeZoneNames(); /** - * Return true if the given TimeZoneNames objects are emantically equal. + * Return true if the given TimeZoneNames objects are semantically equal. * @param other the object to be compared with. * @return Return TRUE if the given Format objects are semantically equal. * @stable ICU 50 @@ -289,6 +291,18 @@ public: virtual UnicodeString& getDisplayName(const UnicodeString& tzID, UTimeZoneNameType type, UDate date, UnicodeString& name) const; /** + * @internal For specific users only until proposed publicly. + * @deprecated This API is ICU internal only. + */ + virtual void loadAllDisplayNames(UErrorCode& status); + + /** + * @internal For specific users only until proposed publicly. + * @deprecated This API is ICU internal only. + */ + virtual void getDisplayNames(const UnicodeString& tzID, const UTimeZoneNameType types[], int32_t numTypes, UDate date, UnicodeString dest[], UErrorCode& status) const; + + /** * <code>MatchInfoCollection</code> represents a collection of time zone name matches used by * {@link TimeZoneNames#find}. * @internal diff --git a/deps/icu-small/source/i18n/unicode/tzrule.h b/deps/icu-small/source/i18n/unicode/tzrule.h index c153afa1e9..5e020bc1a3 100644 --- a/deps/icu-small/source/i18n/unicode/tzrule.h +++ b/deps/icu-small/source/i18n/unicode/tzrule.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2007-2008, International Business Machines Corporation and * diff --git a/deps/icu-small/source/i18n/unicode/tztrans.h b/deps/icu-small/source/i18n/unicode/tztrans.h index f5934d9125..b2e09999bb 100644 --- a/deps/icu-small/source/i18n/unicode/tztrans.h +++ b/deps/icu-small/source/i18n/unicode/tztrans.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2007-2008, International Business Machines Corporation and * diff --git a/deps/icu-small/source/i18n/unicode/ucal.h b/deps/icu-small/source/i18n/unicode/ucal.h index 8f3bf71f99..18522f6475 100644 --- a/deps/icu-small/source/i18n/unicode/ucal.h +++ b/deps/icu-small/source/i18n/unicode/ucal.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 1996-2015, International Business Machines Corporation and @@ -423,10 +425,12 @@ enum UCalendarDateFields { */ UCAL_IS_LEAP_MONTH, - /** - * Field count - * @stable ICU 2.6 - */ + // Do not conditionalize with #ifndef U_HIDE_DEPRECATED_API, + // it is needed for layout of Calendar, DateFormat, and other objects + /** + * One more than the highest normal UCalendarDateFields value. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ UCAL_FIELD_COUNT, /** diff --git a/deps/icu-small/source/i18n/unicode/ucol.h b/deps/icu-small/source/i18n/unicode/ucol.h index 25f90408c9..0b3fab90b1 100644 --- a/deps/icu-small/source/i18n/unicode/ucol.h +++ b/deps/icu-small/source/i18n/unicode/ucol.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (c) 1996-2015, International Business Machines Corporation and others. @@ -123,8 +125,13 @@ typedef enum { /** upper case sorts before lower case */ UCOL_UPPER_FIRST = 25, +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal UColAttributeValue value. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ UCOL_ATTRIBUTE_VALUE_COUNT - +#endif // U_HIDE_DEPRECATED_API } UColAttributeValue; /** @@ -191,12 +198,13 @@ typedef enum { * @stable ICU 4.8 */ UCOL_REORDER_CODE_DIGIT = 0x1004, - /** - * The limit of the reorder codes. This is intended for use in range checking - * and enumeration of the reorder codes. - * @stable ICU 4.8 - */ +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal UColReorderCode value. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ UCOL_REORDER_CODE_LIMIT = 0x1005 +#endif // U_HIDE_DEPRECATED_API } UColReorderCode; /** @@ -333,10 +341,13 @@ typedef enum { * @stable ICU 2.8 */ UCOL_NUMERIC_COLLATION = UCOL_STRENGTH + 2, - /** - * The number of UColAttribute constants. - * @stable ICU 2.0 - */ + + // Do not conditionalize the following with #ifndef U_HIDE_DEPRECATED_API, + // it is needed for layout of RuleBasedCollator object. + /** + * One more than the highest normal UColAttribute value. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ UCOL_ATTRIBUTE_COUNT } UColAttribute; @@ -1050,7 +1061,13 @@ typedef enum { UCOL_BOUND_UPPER = 1, /** upper bound that will match all the strings that have the same initial substring as the given string */ UCOL_BOUND_UPPER_LONG = 2, - UCOL_BOUND_VALUE_COUNT +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal UColBoundMode value. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ + UCOL_BOUND_VALUE_COUNT +#endif // U_HIDE_DEPRECATED_API } UColBoundMode; /** diff --git a/deps/icu-small/source/i18n/unicode/ucoleitr.h b/deps/icu-small/source/i18n/unicode/ucoleitr.h index 7af783d37c..89fd9e85cf 100644 --- a/deps/icu-small/source/i18n/unicode/ucoleitr.h +++ b/deps/icu-small/source/i18n/unicode/ucoleitr.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2001-2014, International Business Machines diff --git a/deps/icu-small/source/i18n/unicode/ucsdet.h b/deps/icu-small/source/i18n/unicode/ucsdet.h index b737b16047..a926d2f22c 100644 --- a/deps/icu-small/source/i18n/unicode/ucsdet.h +++ b/deps/icu-small/source/i18n/unicode/ucsdet.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2005-2013, International Business Machines diff --git a/deps/icu-small/source/i18n/unicode/udat.h b/deps/icu-small/source/i18n/unicode/udat.h index 5baec62137..cacfbe8500 100644 --- a/deps/icu-small/source/i18n/unicode/udat.h +++ b/deps/icu-small/source/i18n/unicode/udat.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 1996-2016, International Business Machines @@ -787,16 +789,15 @@ typedef enum UDateFormatField { UDAT_TIME_SEPARATOR_FIELD = 37, #endif /* U_HIDE_INTERNAL_API */ - /** +#ifndef U_HIDE_DEPRECATED_API + /** * Number of FieldPosition and UFieldPosition selectors for * DateFormat and UDateFormat. * Valid selectors range from 0 to UDAT_FIELD_COUNT-1. - * This value is subject to change if new fields are defined - * in the future. - * @stable ICU 3.0 + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. */ UDAT_FIELD_COUNT = 38 - +#endif // U_HIDE_DEPRECATED_API } UDateFormatField; @@ -888,23 +889,24 @@ typedef enum UDateFormatBooleanAttribute { * @stable ICU 53 */ UDAT_PARSE_ALLOW_NUMERIC = 1, -#ifndef U_HIDE_DRAFT_API /** * indicates tolerance of a partial literal match * e.g. accepting "--mon-02-march-2011" for a pattern of "'--: 'EEE-WW-MMMM-yyyy" - * @draft ICU 56 + * @stable ICU 56 */ UDAT_PARSE_PARTIAL_LITERAL_MATCH = 2, /** * indicates tolerance of pattern mismatch between input data and specified format pattern. * e.g. accepting "September" for a month pattern of MMM ("Sep") - * @draft ICU 56 + * @stable ICU 56 */ UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH = 3, -#endif /* U_HIDE_DRAFT_API */ + + // Do not conditionalize the following with #ifndef U_HIDE_DEPRECATED_API, + // it is needed for layout of DateFormat object. /** - * count boolean date format constants - * @stable ICU 53 + * One more than the highest normal UDateFormatBooleanAttribute value. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. */ UDAT_BOOLEAN_ATTRIBUTE_COUNT = 4 } UDateFormatBooleanAttribute; diff --git a/deps/icu-small/source/i18n/unicode/udateintervalformat.h b/deps/icu-small/source/i18n/unicode/udateintervalformat.h index 26d9b5a9dd..81bff16d6e 100644 --- a/deps/icu-small/source/i18n/unicode/udateintervalformat.h +++ b/deps/icu-small/source/i18n/unicode/udateintervalformat.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ***************************************************************************************** * Copyright (C) 2010-2012,2015 International Business Machines diff --git a/deps/icu-small/source/i18n/unicode/udatpg.h b/deps/icu-small/source/i18n/unicode/udatpg.h index f52ed4c34a..365d51c493 100644 --- a/deps/icu-small/source/i18n/unicode/udatpg.h +++ b/deps/icu-small/source/i18n/unicode/udatpg.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * @@ -83,7 +85,13 @@ typedef enum UDateTimePatternField { UDATPG_FRACTIONAL_SECOND_FIELD, /** @stable ICU 3.8 */ UDATPG_ZONE_FIELD, - /** @stable ICU 3.8 */ + + // Do not conditionalize the following with #ifndef U_HIDE_DEPRECATED_API, + // it is needed for layout of DateTimePatternGenerator object. + /** + * One more than the highest normal UDateTimePatternField value. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ UDATPG_FIELD_COUNT } UDateTimePatternField; @@ -120,8 +128,13 @@ typedef enum UDateTimePatternConflict { UDATPG_BASE_CONFLICT, /** @stable ICU 3.8 */ UDATPG_CONFLICT, - /** @stable ICU 3.8 */ +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal UDateTimePatternConflict value. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ UDATPG_CONFLICT_COUNT +#endif // U_HIDE_DEPRECATED_API } UDateTimePatternConflict; /** diff --git a/deps/icu-small/source/i18n/unicode/ufieldpositer.h b/deps/icu-small/source/i18n/unicode/ufieldpositer.h index 836bfdf279..8dfa3df5a4 100644 --- a/deps/icu-small/source/i18n/unicode/ufieldpositer.h +++ b/deps/icu-small/source/i18n/unicode/ufieldpositer.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ***************************************************************************************** * Copyright (C) 2015-2016, International Business Machines @@ -84,8 +86,8 @@ U_NAMESPACE_END /** * Get information for the next field in the formatted string to which this - * UFieldPositionIterator currently applies, or return FALSE if there are - * no more fields. + * UFieldPositionIterator currently applies, or return a negative value if there + * are no more fields. * @param fpositer * A pointer to the UFieldPositionIterator object containing iteration * state for the format fields. diff --git a/deps/icu-small/source/i18n/unicode/uformattable.h b/deps/icu-small/source/i18n/unicode/uformattable.h index a64ae14653..e4683d56c3 100644 --- a/deps/icu-small/source/i18n/unicode/uformattable.h +++ b/deps/icu-small/source/i18n/unicode/uformattable.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** * Copyright (C) 2013-2014, International Business Machines Corporation and others. @@ -49,7 +51,13 @@ typedef enum UFormattableType { UFMT_ARRAY, /**< ufmt_countArray() and ufmt_getArray() will return the value. @see ufmt_getArrayItemByIndex */ UFMT_INT64, /**< ufmt_getInt64() will return without conversion. @see ufmt_getInt64 */ UFMT_OBJECT, /**< ufmt_getObject() will return without conversion. @see ufmt_getObject*/ - UFMT_COUNT /**< Count of defined UFormattableType values */ +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal UFormattableType value. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ + UFMT_COUNT +#endif // U_HIDE_DEPRECATED_API } UFormattableType; diff --git a/deps/icu-small/source/i18n/unicode/ugender.h b/deps/icu-small/source/i18n/unicode/ugender.h index 86e229df61..c1e591ed28 100644 --- a/deps/icu-small/source/i18n/unicode/ugender.h +++ b/deps/icu-small/source/i18n/unicode/ugender.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ***************************************************************************************** * Copyright (C) 2010-2013, International Business Machines diff --git a/deps/icu-small/source/i18n/unicode/ulocdata.h b/deps/icu-small/source/i18n/unicode/ulocdata.h index 63495f681c..ecf6fdcb3f 100644 --- a/deps/icu-small/source/i18n/unicode/ulocdata.h +++ b/deps/icu-small/source/i18n/unicode/ulocdata.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * * @@ -47,8 +49,13 @@ typedef enum ULocaleDataExemplarSetType { ULOCDATA_ES_INDEX=2, /** Punctuation set @stable ICU 51 */ ULOCDATA_ES_PUNCTUATION=3, - /** One higher than the last valid type @stable ICU 3.4 */ +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal ULocaleDataExemplarSetType value. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ ULOCDATA_ES_COUNT=4 +#endif // U_HIDE_DEPRECATED_API } ULocaleDataExemplarSetType; /** The possible types of delimiters. @@ -63,8 +70,13 @@ typedef enum ULocaleDataDelimiterType { ULOCDATA_ALT_QUOTATION_START = 2, /** Alternate quotation end @stable ICU 3.4 */ ULOCDATA_ALT_QUOTATION_END = 3, - /** One higher than the last valid type @stable ICU 3.4 */ +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal ULocaleDataDelimiterType value. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ ULOCDATA_DELIMITER_COUNT = 4 +#endif // U_HIDE_DEPRECATED_API } ULocaleDataDelimiterType; /** @@ -189,7 +201,13 @@ typedef enum UMeasurementSystem { UMS_SI, /**< Measurement system specified by SI otherwise known as Metric system. @stable ICU 2.8 */ UMS_US, /**< Measurement system followed in the United States of America. @stable ICU 2.8 */ UMS_UK, /**< Mix of metric and imperial units used in Great Britain. @stable ICU 55 */ +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal UMeasurementSystem value. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ UMS_LIMIT +#endif // U_HIDE_DEPRECATED_API } UMeasurementSystem; /** diff --git a/deps/icu-small/source/i18n/unicode/umsg.h b/deps/icu-small/source/i18n/unicode/umsg.h index e79026f72e..0beb39d5ab 100644 --- a/deps/icu-small/source/i18n/unicode/umsg.h +++ b/deps/icu-small/source/i18n/unicode/umsg.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /******************************************************************** * COPYRIGHT: * Copyright (c) 1997-2011, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/unicode/unirepl.h b/deps/icu-small/source/i18n/unicode/unirepl.h index 974a3f5401..37815a9a24 100644 --- a/deps/icu-small/source/i18n/unicode/unirepl.h +++ b/deps/icu-small/source/i18n/unicode/unirepl.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2002-2005, International Business Machines Corporation diff --git a/deps/icu-small/source/i18n/unicode/unum.h b/deps/icu-small/source/i18n/unicode/unum.h index 8747cc595f..7c652e09cf 100644 --- a/deps/icu-small/source/i18n/unicode/unum.h +++ b/deps/icu-small/source/i18n/unicode/unum.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 1997-2015, International Business Machines Corporation and others. @@ -219,35 +221,35 @@ typedef enum UNumberFormatStyle { * @stable ICU 54 */ UNUM_CASH_CURRENCY=13, -#ifndef U_HIDE_DRAFT_API /** * Decimal format expressed using compact notation * (short form, corresponds to UNumberCompactStyle=UNUM_SHORT) * e.g. "23K", "45B" - * @draft ICU 56 + * @stable ICU 56 */ UNUM_DECIMAL_COMPACT_SHORT=14, /** * Decimal format expressed using compact notation * (long form, corresponds to UNumberCompactStyle=UNUM_LONG) * e.g. "23 thousand", "45 billion" - * @draft ICU 56 + * @stable ICU 56 */ UNUM_DECIMAL_COMPACT_LONG=15, /** * Currency format with a currency symbol, e.g., "$1.00", * using non-accounting style for negative values (e.g. minus sign). * Overrides any style specified using -cf- key in locale. - * @draft ICU 56 + * @stable ICU 56 */ UNUM_CURRENCY_STANDARD=16, -#endif /* U_HIDE_DRAFT_API */ +#ifndef U_HIDE_DEPRECATED_API /** - * One more than the highest number format style constant. - * @stable ICU 4.8 + * One more than the highest normal UNumberFormatStyle value. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. */ UNUM_FORMAT_STYLE_COUNT=17, +#endif // U_HIDE_DEPRECATED_API /** * Default format @@ -323,7 +325,13 @@ enum UCurrencySpacing { UNUM_CURRENCY_SURROUNDING_MATCH, /** @stable ICU 4.8 */ UNUM_CURRENCY_INSERT, - /** @stable ICU 4.8 */ + + // Do not conditionalize the following with #ifndef U_HIDE_DEPRECATED_API, + // it is needed for layout of DecimalFormatSymbols object. + /** + * One more than the highest normal UCurrencySpacing value. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ UNUM_CURRENCY_SPACING_COUNT }; typedef enum UCurrencySpacing UCurrencySpacing; /**< @stable ICU 4.8 */ @@ -357,8 +365,13 @@ typedef enum UNumberFormatFields { UNUM_PERMILL_FIELD, /** @stable ICU 49 */ UNUM_SIGN_FIELD, - /** @stable ICU 49 */ +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal UNumberFormatFields value. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ UNUM_FIELD_COUNT +#endif // U_HIDE_DEPRECATED_API } UNumberFormatFields; @@ -1272,8 +1285,13 @@ typedef enum UNumberFormatSymbol { */ UNUM_EXPONENT_MULTIPLICATION_SYMBOL = 27, - /** count symbol constants */ +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal UNumberFormatSymbol value. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ UNUM_FORMAT_SYMBOL_COUNT = 28 +#endif // U_HIDE_DEPRECATED_API } UNumberFormatSymbol; /** diff --git a/deps/icu-small/source/i18n/unicode/unumsys.h b/deps/icu-small/source/i18n/unicode/unumsys.h index 8f9d386dd5..396d55d6b7 100644 --- a/deps/icu-small/source/i18n/unicode/unumsys.h +++ b/deps/icu-small/source/i18n/unicode/unumsys.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ***************************************************************************************** * Copyright (C) 2013-2014, International Business Machines diff --git a/deps/icu-small/source/i18n/unicode/upluralrules.h b/deps/icu-small/source/i18n/unicode/upluralrules.h index 5bcadd4bda..52e34d8d25 100644 --- a/deps/icu-small/source/i18n/unicode/upluralrules.h +++ b/deps/icu-small/source/i18n/unicode/upluralrules.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ***************************************************************************************** * Copyright (C) 2010-2013, International Business Machines @@ -52,11 +54,13 @@ enum UPluralType { * @stable ICU 50 */ UPLURAL_TYPE_ORDINAL, +#ifndef U_HIDE_DEPRECATED_API /** - * Number of Plural rules types. - * @stable ICU 50 + * One more than the highest normal UPluralType value. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. */ UPLURAL_TYPE_COUNT +#endif // U_HIDE_DEPRECATED_API }; /** * @stable ICU 50 diff --git a/deps/icu-small/source/i18n/unicode/uregex.h b/deps/icu-small/source/i18n/unicode/uregex.h index c51acd5f40..7806a74afc 100644 --- a/deps/icu-small/source/i18n/unicode/uregex.h +++ b/deps/icu-small/source/i18n/unicode/uregex.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2004-2016, International Business Machines diff --git a/deps/icu-small/source/i18n/unicode/uregion.h b/deps/icu-small/source/i18n/unicode/uregion.h index 29347528e0..b5d03691ca 100644 --- a/deps/icu-small/source/i18n/unicode/uregion.h +++ b/deps/icu-small/source/i18n/unicode/uregion.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ***************************************************************************************** * Copyright (C) 2014, International Business Machines @@ -105,11 +107,13 @@ typedef enum URegionType { */ URGN_DEPRECATED, +#ifndef U_HIDE_DEPRECATED_API /** - * Maximum value for this unumeration. - * @stable ICU 51 + * One more than the highest normal URegionType value. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. */ URGN_LIMIT +#endif // U_HIDE_DEPRECATED_API } URegionType; #if !UCONFIG_NO_FORMATTING diff --git a/deps/icu-small/source/i18n/unicode/ureldatefmt.h b/deps/icu-small/source/i18n/unicode/ureldatefmt.h index fce016f564..fad8ffd9e1 100644 --- a/deps/icu-small/source/i18n/unicode/ureldatefmt.h +++ b/deps/icu-small/source/i18n/unicode/ureldatefmt.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ***************************************************************************************** * Copyright (C) 2016, International Business Machines @@ -58,11 +60,13 @@ typedef enum UDateRelativeDateTimeFormatterStyle { */ UDAT_STYLE_NARROW, - /** - * The number of styles. - * @stable ICU 54 - */ - UDAT_STYLE_COUNT +#ifndef U_HIDE_DEPRECATED_API + /** + * One more than the highest normal UDateRelativeDateTimeFormatterStyle value. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. + */ + UDAT_STYLE_COUNT +#endif // U_HIDE_DEPRECATED_API } UDateRelativeDateTimeFormatterStyle; #ifndef U_HIDE_DRAFT_API @@ -162,11 +166,13 @@ typedef enum URelativeDateTimeUnit { * @draft ICU 57 */ UDAT_REL_UNIT_SATURDAY, +#ifndef U_HIDE_DEPRECATED_API /** - * Count of URelativeDateTimeUnit values - * @draft ICU 57 + * One more than the highest normal URelativeDateTimeUnit value. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. */ UDAT_REL_UNIT_COUNT +#endif // U_HIDE_DEPRECATED_API } URelativeDateTimeUnit; #endif /* U_HIDE_DRAFT_API */ diff --git a/deps/icu-small/source/i18n/unicode/usearch.h b/deps/icu-small/source/i18n/unicode/usearch.h index 10721bc726..dcdb7fe420 100644 --- a/deps/icu-small/source/i18n/unicode/usearch.h +++ b/deps/icu-small/source/i18n/unicode/usearch.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2001-2011,2014 IBM and others. All rights reserved. @@ -188,11 +190,13 @@ typedef enum { */ USEARCH_ELEMENT_COMPARISON = 2, +#ifndef U_HIDE_DEPRECATED_API /** - * Count of attribute types - * @stable ICU 2.4 + * One more than the highest normal USearchAttribute value. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. */ USEARCH_ATTRIBUTE_COUNT = 3 +#endif // U_HIDE_DEPRECATED_API } USearchAttribute; /** @@ -262,11 +266,13 @@ typedef enum { */ USEARCH_ANY_BASE_WEIGHT_IS_WILDCARD, +#ifndef U_HIDE_DEPRECATED_API /** - * Count of attribute values - * @stable ICU 2.4 + * One more than the highest normal USearchAttributeValue value. + * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. */ USEARCH_ATTRIBUTE_VALUE_COUNT +#endif // U_HIDE_DEPRECATED_API } USearchAttributeValue; /* open and close ------------------------------------------------------ */ diff --git a/deps/icu-small/source/i18n/unicode/uspoof.h b/deps/icu-small/source/i18n/unicode/uspoof.h index c2285a700e..40b73380c5 100644 --- a/deps/icu-small/source/i18n/unicode/uspoof.h +++ b/deps/icu-small/source/i18n/unicode/uspoof.h @@ -1,6 +1,8 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* *************************************************************************** -* Copyright (C) 2008-2015, International Business Machines Corporation +* Copyright (C) 2008-2016, International Business Machines Corporation * and others. All Rights Reserved. *************************************************************************** * file name: uspoof.h @@ -35,123 +37,350 @@ * \file * \brief Unicode Security and Spoofing Detection, C API. * - * These functions are intended to check strings, typically - * identifiers of some type, such as URLs, for the presence of - * characters that are likely to be visually confusing - - * for cases where the displayed form of an identifier may - * not be what it appears to be. - * - * Unicode Technical Report #36, http://unicode.org/reports/tr36, and - * Unicode Technical Standard #39, http://unicode.org/reports/tr39 - * "Unicode security considerations", give more background on - * security an spoofing issues with Unicode identifiers. - * The tests and checks provided by this module implement the recommendations - * from those Unicode documents. - * - * The tests available on identifiers fall into two general categories: - * -# Single identifier tests. Check whether an identifier is - * potentially confusable with any other string, or is suspicious - * for other reasons. - * -# Two identifier tests. Check whether two specific identifiers are confusable. - * This does not consider whether either of strings is potentially - * confusable with any string other than the exact one specified. - * - * The steps to perform confusability testing are - * -# Open a USpoofChecker. - * -# Configure the USPoofChecker for the desired set of tests. The tests that will - * be performed are specified by a set of USpoofChecks flags. - * -# Perform the checks using the pre-configured USpoofChecker. The results indicate - * which (if any) of the selected tests have identified possible problems with the identifier. - * Results are reported as a set of USpoofChecks flags; this mirrors the form in which - * the set of tests to perform was originally specified to the USpoofChecker. - * - * A USpoofChecker may be used repeatedly to perform checks on any number of identifiers. - * - * Thread Safety: The test functions for checking a single identifier, or for testing - * whether two identifiers are possible confusable, are thread safe. - * They may called concurrently, from multiple threads, using the same USpoofChecker instance. - * - * More generally, the standard ICU thread safety rules apply: functions that take a - * const USpoofChecker parameter are thread safe. Those that take a non-const - * USpoofChecier are not thread safe. - * - * - * Descriptions of the available checks. - * - * When testing whether pairs of identifiers are confusable, with the uspoof_areConfusable() - * family of functions, the relevant tests are - * - * -# USPOOF_SINGLE_SCRIPT_CONFUSABLE: All of the characters from the two identifiers are - * from a single script, and the two identifiers are visually confusable. - * -# USPOOF_MIXED_SCRIPT_CONFUSABLE: At least one of the identifiers contains characters - * from more than one script, and the two identifiers are visually confusable. - * -# USPOOF_WHOLE_SCRIPT_CONFUSABLE: Each of the two identifiers is of a single script, but - * the two identifiers are from different scripts, and they are visually confusable. - * - * The safest approach is to enable all three of these checks as a group. - * - * USPOOF_ANY_CASE is a modifier for the above tests. If the identifiers being checked can - * be of mixed case and are used in a case-sensitive manner, this option should be specified. - * - * If the identifiers being checked are used in a case-insensitive manner, and if they are - * displayed to users in lower-case form only, the USPOOF_ANY_CASE option should not be - * specified. Confusabality issues involving upper case letters will not be reported. - * - * When performing tests on a single identifier, with the uspoof_check() family of functions, - * the relevant tests are: - * - * -# USPOOF_MIXED_SCRIPT_CONFUSABLE: the identifier contains characters from multiple - * scripts, and there exists an identifier of a single script that is visually confusable. - * -# USPOOF_WHOLE_SCRIPT_CONFUSABLE: the identifier consists of characters from a single - * script, and there exists a visually confusable identifier. - * The visually confusable identifier also consists of characters from a single script. - * but not the same script as the identifier being checked. - * -# USPOOF_ANY_CASE: modifies the mixed script and whole script confusables tests. If - * specified, the checks will consider confusable characters of any case. If this flag is not - * set, the test is performed assuming case folded identifiers. - * -# USPOOF_SINGLE_SCRIPT: check that the identifier contains only characters from a - * single script. (Characters from the 'common' and 'inherited' scripts are ignored.) - * This is not a test for confusable identifiers - * -# USPOOF_INVISIBLE: check an identifier for the presence of invisible characters, - * such as zero-width spaces, or character sequences that are - * likely not to display, such as multiple occurrences of the same - * non-spacing mark. This check does not test the input string as a whole - * for conformance to any particular syntax for identifiers. - * -# USPOOF_CHAR_LIMIT: check that an identifier contains only characters from a specified set - * of acceptable characters. See uspoof_setAllowedChars() and - * uspoof_setAllowedLocales(). - * - * Note on Scripts: - * Characters from the Unicode Scripts "Common" and "Inherited" are ignored when considering - * the script of an identifier. Common characters include digits and symbols that - * are normally used with text from more than one script. - * - * Identifier Skeletons: A skeleton is a transformation of an identifier, such that - * all identifiers that are confusable with each other have the same skeleton. - * Using skeletons, it is possible to build a dictionary data structure for - * a set of identifiers, and then quickly test whether a new identifier is - * confusable with an identifier already in the set. The uspoof_getSkeleton() - * family of functions will produce the skeleton from an identifier. - * - * Note that skeletons are not guaranteed to be stable between versions - * of Unicode or ICU, so an applications should not rely on creating a permanent, - * or difficult to update, database of skeletons. Instabilities result from - * identifying new pairs or sequences of characters that are visually - * confusable, and thus must be mapped to the same skeleton character(s). - * - * Skeletons are computed using the algorithm and data describe in Unicode UAX 39. - * The latest proposed update, UAX 39 Version 8 draft 1, says "the tables SL, SA, and ML - * were still problematic, and discouraged from use in [Uniocde] 7.0. - * They were thus removed from version 8.0" - * - * In light of this, the default mapping data included with ICU 55 uses the - * Unicode 7 MA (Multi script Any case) table data for the other type options - * (Single Script, Any Case), (Single Script, Lower Case) and (Multi Script, Lower Case). + * <p> + * This class, based on <a href="http://unicode.org/reports/tr36">Unicode Technical Report #36</a> and + * <a href="http://unicode.org/reports/tr39">Unicode Technical Standard #39</a>, has two main functions: + * + * <ol> + * <li>Checking whether two strings are visually <em>confusable</em> with each other, such as "Harvest" and + * "Ηarvest", where the second string starts with the Greek capital letter Eta.</li> + * <li>Checking whether an individual string is likely to be an attempt at confusing the reader (<em>spoof + * detection</em>), such as "paypal" with some Latin characters substituted with Cyrillic look-alikes.</li> + * </ol> + * + * <p> + * Although originally designed as a method for flagging suspicious identifier strings such as URLs, + * <code>USpoofChecker</code> has a number of other practical use cases, such as preventing attempts to evade bad-word + * content filters. + * + * <p> + * The functions of this class are exposed as C API, with a handful of syntactical conveniences for C++. + * + * <h2>Confusables</h2> + * + * <p> + * The following example shows how to use <code>USpoofChecker</code> to check for confusability between two strings: + * + * \code{.c} + * UErrorCode status = U_ZERO_ERROR; + * UChar* str1 = (UChar*) u"Harvest"; + * UChar* str2 = (UChar*) u"\u0397arvest"; // with U+0397 GREEK CAPITAL LETTER ETA + * + * USpoofChecker* sc = uspoof_open(&status); + * uspoof_setChecks(sc, USPOOF_CONFUSABLE, &status); + * + * int32_t bitmask = uspoof_areConfusable(sc, str1, -1, str2, -1, &status); + * UBool result = bitmask != 0; + * // areConfusable: 1 (status: U_ZERO_ERROR) + * printf("areConfusable: %d (status: %s)\n", result, u_errorName(status)); + * uspoof_close(sc); + * \endcode + * + * <p> + * The call to {@link uspoof_open} creates a <code>USpoofChecker</code> object; the call to {@link uspoof_setChecks} + * enables confusable checking and disables all other checks; the call to {@link uspoof_areConfusable} performs the + * confusability test; and the following line extracts the result out of the return value. For best performance, + * the instance should be created once (e.g., upon application startup), and the efficient + * {@link uspoof_areConfusable} method can be used at runtime. + * + * <p> + * The type {@link LocalUSpoofCheckerPointer} is exposed for C++ programmers. It will automatically call + * {@link uspoof_close} when the object goes out of scope: + * + * \code{.cpp} + * UErrorCode status = U_ZERO_ERROR; + * LocalUSpoofCheckerPointer sc(uspoof_open(&status)); + * uspoof_setChecks(sc.getAlias(), USPOOF_CONFUSABLE, &status); + * // ... + * \endcode + * + * <p> + * UTS 39 defines two strings to be <em>confusable</em> if they map to the same <em>skeleton string</em>. A skeleton can + * be thought of as a "hash code". {@link uspoof_getSkeleton} computes the skeleton for a particular string, so + * the following snippet is equivalent to the example above: + * + * \code{.c} + * UErrorCode status = U_ZERO_ERROR; + * UChar* str1 = (UChar*) u"Harvest"; + * UChar* str2 = (UChar*) u"\u0397arvest"; // with U+0397 GREEK CAPITAL LETTER ETA + * + * USpoofChecker* sc = uspoof_open(&status); + * uspoof_setChecks(sc, USPOOF_CONFUSABLE, &status); + * + * // Get skeleton 1 + * int32_t skel1Len = uspoof_getSkeleton(sc, 0, str1, -1, NULL, 0, &status); + * UChar* skel1 = (UChar*) malloc(++skel1Len * sizeof(UChar)); + * status = U_ZERO_ERROR; + * uspoof_getSkeleton(sc, 0, str1, -1, skel1, skel1Len, &status); + * + * // Get skeleton 2 + * int32_t skel2Len = uspoof_getSkeleton(sc, 0, str2, -1, NULL, 0, &status); + * UChar* skel2 = (UChar*) malloc(++skel2Len * sizeof(UChar)); + * status = U_ZERO_ERROR; + * uspoof_getSkeleton(sc, 0, str2, -1, skel2, skel2Len, &status); + * + * // Are the skeletons the same? + * UBool result = u_strcmp(skel1, skel2) == 0; + * // areConfusable: 1 (status: U_ZERO_ERROR) + * printf("areConfusable: %d (status: %s)\n", result, u_errorName(status)); + * uspoof_close(sc); + * free(skel1); + * free(skel2); + * \endcode + * + * <p> + * If you need to check if a string is confusable with any string in a dictionary of many strings, rather than calling + * {@link uspoof_areConfusable} many times in a loop, {@link uspoof_getSkeleton} can be used instead, as shown below: + * + * \code{.c} + * UErrorCode status = U_ZERO_ERROR; + * #define DICTIONARY_LENGTH 2 + * UChar* dictionary[DICTIONARY_LENGTH] = { (UChar*) u"lorem", (UChar*) u"ipsum" }; + * UChar* skeletons[DICTIONARY_LENGTH]; + * UChar* str = (UChar*) u"1orern"; + * + * // Setup: + * USpoofChecker* sc = uspoof_open(&status); + * uspoof_setChecks(sc, USPOOF_CONFUSABLE, &status); + * for (size_t i=0; i<DICTIONARY_LENGTH; i++) { + * UChar* word = dictionary[i]; + * int32_t len = uspoof_getSkeleton(sc, 0, word, -1, NULL, 0, &status); + * skeletons[i] = (UChar*) malloc(++len * sizeof(UChar)); + * status = U_ZERO_ERROR; + * uspoof_getSkeleton(sc, 0, word, -1, skeletons[i], len, &status); + * } + * + * // Live Check: + * { + * int32_t len = uspoof_getSkeleton(sc, 0, str, -1, NULL, 0, &status); + * UChar* skel = (UChar*) malloc(++len * sizeof(UChar)); + * status = U_ZERO_ERROR; + * uspoof_getSkeleton(sc, 0, str, -1, skel, len, &status); + * UBool result = FALSE; + * for (size_t i=0; i<DICTIONARY_LENGTH; i++) { + * result = u_strcmp(skel, skeletons[i]) == 0; + * if (result == TRUE) { break; } + * } + * // Has confusable in dictionary: 1 (status: U_ZERO_ERROR) + * printf("Has confusable in dictionary: %d (status: %s)\n", result, u_errorName(status)); + * free(skel); + * } + * + * for (size_t i=0; i<DICTIONARY_LENGTH; i++) { + * free(skeletons[i]); + * } + * uspoof_close(sc); + * \endcode + * + * <p> + * <b>Note:</b> Since the Unicode confusables mapping table is frequently updated, confusable skeletons are <em>not</em> + * guaranteed to be the same between ICU releases. We therefore recommend that you always compute confusable skeletons + * at runtime and do not rely on creating a permanent, or difficult to update, database of skeletons. + * + * <h2>Spoof Detection</h2> + * + * <p> + * The following snippet shows a minimal example of using <code>USpoofChecker</code> to perform spoof detection on a + * string: + * + * \code{.c} + * UErrorCode status = U_ZERO_ERROR; + * UChar* str = (UChar*) u"p\u0430ypal"; // with U+0430 CYRILLIC SMALL LETTER A + * + * // Get the default set of allowable characters: + * USet* allowed = uset_openEmpty(); + * uset_addAll(allowed, uspoof_getRecommendedSet(&status)); + * uset_addAll(allowed, uspoof_getInclusionSet(&status)); + * + * USpoofChecker* sc = uspoof_open(&status); + * uspoof_setAllowedChars(sc, allowed, &status); + * uspoof_setRestrictionLevel(sc, USPOOF_MODERATELY_RESTRICTIVE); + * + * int32_t bitmask = uspoof_check(sc, str, -1, NULL, &status); + * UBool result = bitmask != 0; + * // fails checks: 1 (status: U_ZERO_ERROR) + * printf("fails checks: %d (status: %s)\n", result, u_errorName(status)); + * uspoof_close(sc); + * uset_close(allowed); + * \endcode + * + * <p> + * As in the case for confusability checking, it is good practice to create one <code>USpoofChecker</code> instance at + * startup, and call the cheaper {@link uspoof_check} online. We specify the set of + * allowed characters to be those with type RECOMMENDED or INCLUSION, according to the recommendation in UTS 39. + * + * <p> + * In addition to {@link uspoof_check}, the function {@link uspoof_checkUTF8} is exposed for UTF8-encoded char* strings, + * and {@link uspoof_checkUnicodeString} is exposed for C++ programmers. + * + * <p> + * If the {@link USPOOF_AUX_INFO} check is enabled, a limited amount of information on why a string failed the checks + * is available in the returned bitmask. For complete information, use the {@link uspoof_check2} class of functions + * with a {@link USpoofCheckResult} parameter: + * + * \code{.c} + * UErrorCode status = U_ZERO_ERROR; + * UChar* str = (UChar*) u"p\u0430ypal"; // with U+0430 CYRILLIC SMALL LETTER A + * + * // Get the default set of allowable characters: + * USet* allowed = uset_openEmpty(); + * uset_addAll(allowed, uspoof_getRecommendedSet(&status)); + * uset_addAll(allowed, uspoof_getInclusionSet(&status)); + * + * USpoofChecker* sc = uspoof_open(&status); + * uspoof_setAllowedChars(sc, allowed, &status); + * uspoof_setRestrictionLevel(sc, USPOOF_MODERATELY_RESTRICTIVE); + * + * USpoofCheckResult* checkResult = uspoof_openCheckResult(&status); + * int32_t bitmask = uspoof_check2(sc, str, -1, checkResult, &status); + * + * int32_t failures1 = bitmask; + * int32_t failures2 = uspoof_getCheckResultChecks(checkResult, &status); + * assert(failures1 == failures2); + * // checks that failed: 0x00000010 (status: U_ZERO_ERROR) + * printf("checks that failed: %#010x (status: %s)\n", failures1, u_errorName(status)); + * + * // Cleanup: + * uspoof_close(sc); + * uset_close(allowed); + * uspoof_closeCheckResult(checkResult); + * \endcode + * + * C++ users can take advantage of a few syntactical conveniences. The following snippet is functionally + * equivalent to the one above: + * + * \code{.cpp} + * UErrorCode status = U_ZERO_ERROR; + * UnicodeString str((UChar*) u"p\u0430ypal"); // with U+0430 CYRILLIC SMALL LETTER A + * + * // Get the default set of allowable characters: + * UnicodeSet allowed; + * allowed.addAll(*uspoof_getRecommendedUnicodeSet(&status)); + * allowed.addAll(*uspoof_getInclusionUnicodeSet(&status)); + * + * LocalUSpoofCheckerPointer sc(uspoof_open(&status)); + * uspoof_setAllowedChars(sc.getAlias(), allowed.toUSet(), &status); + * uspoof_setRestrictionLevel(sc.getAlias(), USPOOF_MODERATELY_RESTRICTIVE); + * + * LocalUSpoofCheckResultPointer checkResult(uspoof_openCheckResult(&status)); + * int32_t bitmask = uspoof_check2UnicodeString(sc.getAlias(), str, checkResult.getAlias(), &status); + * + * int32_t failures1 = bitmask; + * int32_t failures2 = uspoof_getCheckResultChecks(checkResult.getAlias(), &status); + * assert(failures1 == failures2); + * // checks that failed: 0x00000010 (status: U_ZERO_ERROR) + * printf("checks that failed: %#010x (status: %s)\n", failures1, u_errorName(status)); + * + * // Explicit cleanup not necessary. + * \endcode + * + * <p> + * The return value is a bitmask of the checks that failed. In this case, there was one check that failed: + * {@link USPOOF_RESTRICTION_LEVEL}, corresponding to the fifth bit (16). The possible checks are: + * + * <ul> + * <li><code>RESTRICTION_LEVEL</code>: flags strings that violate the + * <a href="http://unicode.org/reports/tr39/#Restriction_Level_Detection">Restriction Level</a> test as specified in UTS + * 39; in most cases, this means flagging strings that contain characters from multiple different scripts.</li> + * <li><code>INVISIBLE</code>: flags strings that contain invisible characters, such as zero-width spaces, or character + * sequences that are likely not to display, such as multiple occurrences of the same non-spacing mark.</li> + * <li><code>CHAR_LIMIT</code>: flags strings that contain characters outside of a specified set of acceptable + * characters. See {@link uspoof_setAllowedChars} and {@link uspoof_setAllowedLocales}.</li> + * <li><code>MIXED_NUMBERS</code>: flags strings that contain digits from multiple different numbering systems.</li> + * </ul> + * + * <p> + * These checks can be enabled independently of each other. For example, if you were interested in checking for only the + * INVISIBLE and MIXED_NUMBERS conditions, you could do: + * + * \code{.c} + * UErrorCode status = U_ZERO_ERROR; + * UChar* str = (UChar*) u"8\u09EA"; // 8 mixed with U+09EA BENGALI DIGIT FOUR + * + * USpoofChecker* sc = uspoof_open(&status); + * uspoof_setChecks(sc, USPOOF_INVISIBLE | USPOOF_MIXED_NUMBERS, &status); + * + * int32_t bitmask = uspoof_check2(sc, str, -1, NULL, &status); + * UBool result = bitmask != 0; + * // fails checks: 1 (status: U_ZERO_ERROR) + * printf("fails checks: %d (status: %s)\n", result, u_errorName(status)); + * uspoof_close(sc); + * \endcode + * + * <p> + * Here is an example in C++ showing how to compute the restriction level of a string: + * + * \code{.cpp} + * UErrorCode status = U_ZERO_ERROR; + * UnicodeString str((UChar*) u"p\u0430ypal"); // with U+0430 CYRILLIC SMALL LETTER A + * + * // Get the default set of allowable characters: + * UnicodeSet allowed; + * allowed.addAll(*uspoof_getRecommendedUnicodeSet(&status)); + * allowed.addAll(*uspoof_getInclusionUnicodeSet(&status)); + * + * LocalUSpoofCheckerPointer sc(uspoof_open(&status)); + * uspoof_setAllowedChars(sc.getAlias(), allowed.toUSet(), &status); + * uspoof_setRestrictionLevel(sc.getAlias(), USPOOF_MODERATELY_RESTRICTIVE); + * uspoof_setChecks(sc.getAlias(), USPOOF_RESTRICTION_LEVEL | USPOOF_AUX_INFO, &status); + * + * LocalUSpoofCheckResultPointer checkResult(uspoof_openCheckResult(&status)); + * int32_t bitmask = uspoof_check2UnicodeString(sc.getAlias(), str, checkResult.getAlias(), &status); + * + * URestrictionLevel restrictionLevel = uspoof_getCheckResultRestrictionLevel(checkResult.getAlias(), &status); + * // Since USPOOF_AUX_INFO was enabled, the restriction level is also available in the upper bits of the bitmask: + * assert((restrictionLevel & bitmask) == restrictionLevel); + * // Restriction level: 0x50000000 (status: U_ZERO_ERROR) + * printf("Restriction level: %#010x (status: %s)\n", restrictionLevel, u_errorName(status)); + * \endcode + * + * <p> + * The code '0x50000000' corresponds to the restriction level USPOOF_MINIMALLY_RESTRICTIVE. Since + * USPOOF_MINIMALLY_RESTRICTIVE is weaker than USPOOF_MODERATELY_RESTRICTIVE, the string fails the check. + * + * <p> + * <b>Note:</b> The Restriction Level is the most powerful of the checks. The full logic is documented in + * <a href="http://unicode.org/reports/tr39/#Restriction_Level_Detection">UTS 39</a>, but the basic idea is that strings + * are restricted to contain characters from only a single script, <em>except</em> that most scripts are allowed to have + * Latin characters interspersed. Although the default restriction level is <code>HIGHLY_RESTRICTIVE</code>, it is + * recommended that users set their restriction level to <code>MODERATELY_RESTRICTIVE</code>, which allows Latin mixed + * with all other scripts except Cyrillic, Greek, and Cherokee, with which it is often confusable. For more details on + * the levels, see UTS 39 or {@link URestrictionLevel}. The Restriction Level test is aware of the set of + * allowed characters set in {@link uspoof_setAllowedChars}. Note that characters which have script code + * COMMON or INHERITED, such as numbers and punctuation, are ignored when computing whether a string has multiple + * scripts. + * + * <h2>Additional Information</h2> + * + * <p> + * A <code>USpoofChecker</code> instance may be used repeatedly to perform checks on any number of identifiers. + * + * <p> + * <b>Thread Safety:</b> The test functions for checking a single identifier, or for testing whether + * two identifiers are possible confusable, are thread safe. They may called concurrently, from multiple threads, + * using the same USpoofChecker instance. + * + * <p> + * More generally, the standard ICU thread safety rules apply: functions that take a const USpoofChecker parameter are + * thread safe. Those that take a non-const USpoofChecker are not thread safe.. + * + * @stable ICU 4.6 */ struct USpoofChecker; typedef struct USpoofChecker USpoofChecker; /**< typedef for C of USpoofChecker */ +#ifndef U_HIDE_DRAFT_API +/** + * @see uspoof_openCheckResult + */ +struct USpoofCheckResult; +/** + * @see uspoof_openCheckResult + */ +typedef struct USpoofCheckResult USpoofCheckResult; +#endif /* U_HIDE_DRAFT_API */ + /** * Enum for the kinds of checks that USpoofChecker can perform. * These enum values are used both to select the set of checks that @@ -160,45 +389,61 @@ typedef struct USpoofChecker USpoofChecker; /**< typedef for C of USpoofChecker * @stable ICU 4.2 */ typedef enum USpoofChecks { - /** Single script confusable test. - * When testing whether two identifiers are confusable, report that they are if - * both are from the same script and they are visually confusable. - * Note: this test is not applicable to a check of a single identifier. - */ + /** + * When performing the two-string {@link uspoof_areConfusable} test, this flag in the return value indicates + * that the two strings are visually confusable and that they are from the same script, according to UTS 39 section + * 4. + * + * @see uspoof_areConfusable + * @stable ICU 4.2 + */ USPOOF_SINGLE_SCRIPT_CONFUSABLE = 1, - /** Mixed script confusable test. - * When checking a single identifier, report a problem if - * the identifier contains multiple scripts, and - * is confusable with some other identifier in a single script - * When testing whether two identifiers are confusable, report that they are if - * the two IDs are visually confusable, - * and at least one contains characters from more than one script. + /** + * When performing the two-string {@link uspoof_areConfusable} test, this flag in the return value indicates + * that the two strings are visually confusable and that they are <b>not</b> from the same script, according to UTS + * 39 section 4. + * + * @see uspoof_areConfusable + * @stable ICU 4.2 */ USPOOF_MIXED_SCRIPT_CONFUSABLE = 2, - /** Whole script confusable test. - * When checking a single identifier, report a problem if - * The identifier is of a single script, and - * there exists a confusable identifier in another script. - * When testing whether two identifiers are confusable, report that they are if - * each is of a single script, - * the scripts of the two identifiers are different, and - * the identifiers are visually confusable. + /** + * When performing the two-string {@link uspoof_areConfusable} test, this flag in the return value indicates + * that the two strings are visually confusable and that they are not from the same script but both of them are + * single-script strings, according to UTS 39 section 4. + * + * @see uspoof_areConfusable + * @stable ICU 4.2 */ USPOOF_WHOLE_SCRIPT_CONFUSABLE = 4, - /** Any Case Modifier for confusable identifier tests. - If specified, consider all characters, of any case, when looking for confusables. - If USPOOF_ANY_CASE is not specified, identifiers being checked are assumed to have been - case folded. Upper case confusable characters will not be checked. - Selects between Lower Case Confusable and - Any Case Confusable. */ +#ifndef U_HIDE_DRAFT_API + /** + * Enable this flag in {@link uspoof_setChecks} to turn on all types of confusables. You may set + * the checks to some subset of SINGLE_SCRIPT_CONFUSABLE, MIXED_SCRIPT_CONFUSABLE, or WHOLE_SCRIPT_CONFUSABLE to + * make {@link uspoof_areConfusable} return only those types of confusables. + * + * @see uspoof_areConfusable + * @see uspoof_getSkeleton + * @draft ICU 58 + */ + USPOOF_CONFUSABLE = USPOOF_SINGLE_SCRIPT_CONFUSABLE | USPOOF_MIXED_SCRIPT_CONFUSABLE | USPOOF_WHOLE_SCRIPT_CONFUSABLE, +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DEPRECATED_API + /** + * This flag is deprecated and no longer affects the behavior of SpoofChecker. + * + * @deprecated ICU 58 Any case confusable mappings were removed from UTS 39; the corresponding ICU API was deprecated. + */ USPOOF_ANY_CASE = 8, +#endif /* U_HIDE_DEPRECATED_API */ /** * Check that an identifier is no looser than the specified RestrictionLevel. - * The default if uspoof_setRestrctionLevel() is not called is HIGHLY_RESTRICTIVE. + * The default if {@link uspoof_setRestrictionLevel} is not called is HIGHLY_RESTRICTIVE. * * If USPOOF_AUX_INFO is enabled the actual restriction level of the * identifier being tested will also be returned by uspoof_check(). @@ -229,14 +474,15 @@ typedef enum USpoofChecks { USPOOF_INVISIBLE = 32, /** Check that an identifier contains only characters from a specified set - * of acceptable characters. See uspoof_setAllowedChars() and - * uspoof_setAllowedLocales(). + * of acceptable characters. See {@link uspoof_setAllowedChars} and + * {@link uspoof_setAllowedLocales}. Note that a string that fails this check + * will also fail the {@link USPOOF_RESTRICTION_LEVEL} check. */ USPOOF_CHAR_LIMIT = 64, /** - * Check that an identifier does not include decimal digits from - * more than one numbering system. + * Check that an identifier does not mix numbers from different numbering systems. + * For more information, see UTS 39 section 5.3. * * @stable ICU 51 */ @@ -253,11 +499,11 @@ typedef enum USpoofChecks { * Enable the return of auxillary (non-error) information in the * upper bits of the check results value. * - * If this "check" is not enabled, the results of uspoof_check() will be zero when an - * identifier passes all of the enabled checks. + * If this "check" is not enabled, the results of {@link uspoof_check} will be + * zero when an identifier passes all of the enabled checks. * - * If this "check" is enabled, (uspoof_check() & USPOOF_ALL_CHECKS) will be zero - * when an identifier passes all checks. + * If this "check" is enabled, (uspoof_check() & {@link USPOOF_ALL_CHECKS}) will + * be zero when an identifier passes all checks. * * @stable ICU 51 */ @@ -267,39 +513,53 @@ typedef enum USpoofChecks { /** - * Constants from UAX #39 for use in setRestrictionLevel(), and + * Constants from UAX #39 for use in {@link uspoof_setRestrictionLevel}, and * for returned identifier restriction levels in check results. + * * @stable ICU 51 + * + * @see uspoof_setRestrictionLevel + * @see uspoof_check */ typedef enum URestrictionLevel { /** - * Only ASCII characters: U+0000..U+007F + * All characters in the string are in the identifier profile and all characters in the string are in the + * ASCII range. * * @stable ICU 51 */ USPOOF_ASCII = 0x10000000, /** - * All characters in each identifier must be from a single script. - * - * @stable ICU 53 - */ + * The string classifies as ASCII-Only, or all characters in the string are in the identifier profile and + * the string is single-script, according to the definition in UTS 39 section 5.1. + * + * @stable ICU 53 + */ USPOOF_SINGLE_SCRIPT_RESTRICTIVE = 0x20000000, /** - * All characters in each identifier must be from a single script, or from the combinations: Latin + Han + - * Hiragana + Katakana; Latin + Han + Bopomofo; or Latin + Han + Hangul. Note that this level will satisfy the - * vast majority of Latin-script users; also that TR36 has ASCII instead of Latin. + * The string classifies as Single Script, or all characters in the string are in the identifier profile and + * the string is covered by any of the following sets of scripts, according to the definition in UTS 39 + * section 5.1: + * <ul> + * <li>Latin + Han + Bopomofo (or equivalently: Latn + Hanb)</li> + * <li>Latin + Han + Hiragana + Katakana (or equivalently: Latn + Jpan)</li> + * <li>Latin + Han + Hangul (or equivalently: Latn +Kore)</li> + * </ul> + * This is the default restriction in ICU. * * @stable ICU 51 */ USPOOF_HIGHLY_RESTRICTIVE = 0x30000000, /** - * Allow Latin with other scripts except Cyrillic, Greek, Cherokee Otherwise, the same as Highly Restrictive + * The string classifies as Highly Restrictive, or all characters in the string are in the identifier profile + * and the string is covered by Latin and any one other Recommended or Aspirational script, except Cyrillic, + * Greek, and Cherokee. * * @stable ICU 51 */ USPOOF_MODERATELY_RESTRICTIVE = 0x40000000, /** - * Allow arbitrary mixtures of scripts. Otherwise, the same as Moderately Restrictive. + * All characters in the string are in the identifier profile. Allow arbitrary mixtures of scripts. * * @stable ICU 51 */ @@ -311,11 +571,18 @@ typedef enum USpoofChecks { */ USPOOF_UNRESTRICTIVE = 0x60000000, /** - * Mask for selecting the Restriction Level bits from the return value of uspoof_check(). - * - * @stable ICU 53 - */ - USPOOF_RESTRICTION_LEVEL_MASK = 0x7F000000 + * Mask for selecting the Restriction Level bits from the return value of {@link uspoof_check}. + * + * @stable ICU 53 + */ + USPOOF_RESTRICTION_LEVEL_MASK = 0x7F000000, +#ifndef U_HIDE_INTERNAL_API + /** + * An undefined restriction level. + * @internal + */ + USPOOF_UNDEFINED_RESTRICTIVE = -1 +#endif /* U_HIDE_INTERNAL_API */ } URestrictionLevel; /** @@ -359,10 +626,10 @@ uspoof_openFromSerialized(const void *data, int32_t length, int32_t *pActualLeng /** * Open a Spoof Checker from the source form of the spoof data. - * The two inputs correspond to the Unicode data files confusables.txt - * and confusablesWholeScript.txt as described in Unicode UAX #39. - * The syntax of the source data is as described in UAX #39 for - * these files, and the content of these files is acceptable input. + * The input corresponds to the Unicode data file confusables.txt + * as described in Unicode UAX #39. The syntax of the source data + * is as described in UAX #39 for this file, and the content of + * this file is acceptable input. * * The character encoding of the (char *) input text is UTF-8. * @@ -371,10 +638,9 @@ uspoof_openFromSerialized(const void *data, int32_t length, int32_t *pActualLeng * @param confusablesLen The length of the confusables text, or -1 if the * input string is zero terminated. * @param confusablesWholeScript - * a pointer to the whole script confusables definitions, - * as found in the file confusablesWholeScript.txt from unicode.org. - * @param confusablesWholeScriptLen The length of the whole script confusables text, or - * -1 if the input string is zero terminated. + * Deprecated in ICU 58. No longer used. + * @param confusablesWholeScriptLen + * Deprecated in ICU 58. No longer used. * @param errType In the event of an error in the input, indicates * which of the input files contains the error. * The value is one of USPOOF_SINGLE_SCRIPT_CONFUSABLE or @@ -435,8 +701,33 @@ uspoof_clone(const USpoofChecker *sc, UErrorCode *status); /** - * Specify the set of checks that will be performed by the check - * functions of this Spoof Checker. + * Specify the bitmask of checks that will be performed by {@link uspoof_check}. Calling this method + * overwrites any checks that may have already been enabled. By default, all checks are enabled. + * + * To enable specific checks and disable all others, the "whitelisted" checks should be ORed together. For + * example, to fail strings containing characters outside of the set specified by {@link uspoof_setAllowedChars} and + * also strings that contain digits from mixed numbering systems: + * + * <pre> + * {@code + * uspoof_setChecks(USPOOF_CHAR_LIMIT | USPOOF_MIXED_NUMBERS); + * } + * </pre> + * + * To disable specific checks and enable all others, the "blacklisted" checks should be ANDed away from + * ALL_CHECKS. For example, if you are not planning to use the {@link uspoof_areConfusable} functionality, + * it is good practice to disable the CONFUSABLE check: + * + * <pre> + * {@code + * uspoof_setChecks(USPOOF_ALL_CHECKS & ~USPOOF_CONFUSABLE); + * } + * </pre> + * + * Note that methods such as {@link uspoof_setAllowedChars}, {@link uspoof_setAllowedLocales}, and + * {@link uspoof_setRestrictionLevel} will enable certain checks when called. Those methods will OR the check they + * enable onto the existing bitmask specified by this method. For more details, see the documentation of those + * methods. * * @param sc The USpoofChecker * @param checks The set of checks that this spoof checker will perform. @@ -464,19 +755,22 @@ U_STABLE int32_t U_EXPORT2 uspoof_getChecks(const USpoofChecker *sc, UErrorCode *status); /** - * Set the loosest restriction level allowed. The default if this function - * is not called is HIGHLY_RESTRICTIVE. - * Calling this function also enables the RESTRICTION_LEVEL check. - * @param restrictionLevel The loosest restriction level allowed. - * @see URestrictionLevel - * @stable ICU 51 - */ + * Set the loosest restriction level allowed for strings. The default if this is not called is + * {@link USPOOF_HIGHLY_RESTRICTIVE}. Calling this method enables the {@link USPOOF_RESTRICTION_LEVEL} and + * {@link USPOOF_MIXED_NUMBERS} checks, corresponding to Sections 5.1 and 5.2 of UTS 39. To customize which checks are + * to be performed by {@link uspoof_check}, see {@link uspoof_setChecks}. + * + * @param sc The USpoofChecker + * @param restrictionLevel The loosest restriction level allowed. + * @see URestrictionLevel + * @stable ICU 51 + */ U_STABLE void U_EXPORT2 uspoof_setRestrictionLevel(USpoofChecker *sc, URestrictionLevel restrictionLevel); /** - * Get the Restriction Level that will be tested if the checks include RESTRICTION_LEVEL. + * Get the Restriction Level that will be tested if the checks include {@link USPOOF_RESTRICTION_LEVEL}. * * @return The restriction level * @see URestrictionLevel @@ -499,7 +793,7 @@ uspoof_getRestrictionLevel(const USpoofChecker *sc); * Supplying an empty string removes all restrictions; * characters from any script will be allowed. * - * The USPOOF_CHAR_LIMIT test is automatically enabled for this + * The {@link USPOOF_CHAR_LIMIT} test is automatically enabled for this * USpoofChecker when calling this function with a non-empty list * of locales. * @@ -511,7 +805,7 @@ uspoof_getRestrictionLevel(const USpoofChecker *sc); * can be made to the result of uspoof_setAllowedLocales() by * fetching the resulting set with uspoof_getAllowedChars(), * manipulating it with the Unicode Set API, then resetting the - * spoof detectors limits with uspoof_setAllowedChars() + * spoof detectors limits with uspoof_setAllowedChars(). * * @param sc The USpoofChecker * @param localesList A list list of locales, from which the language @@ -654,16 +948,21 @@ uspoof_getAllowedUnicodeSet(const USpoofChecker *sc, UErrorCode *status); * The text to be checked will typically be an identifier of some sort. * The set of checks to be performed is specified with uspoof_setChecks(). * + * \note + * Consider using the newer API, {@link uspoof_check2}, instead. + * The newer API exposes additional information from the check procedure + * and is otherwise identical to this method. + * * @param sc The USpoofChecker * @param id The identifier to be checked for possible security issues, * in UTF-16 format. * @param length the length of the string to be checked, expressed in * 16 bit UTF-16 code units, or -1 if the string is * zero terminated. - * @param position An out parameter. - * Originally, the index of the first string position that failed a check. - * Now, always returns zero. - * This parameter may be null. + * @param position Deprecated in ICU 51. Always returns zero. + * Originally, an out parameter for the index of the first + * string position that failed a check. + * This parameter may be NULL. * @param status The error code, set if an error occurred while attempting to * perform the check. * Spoofing or security issues detected with the input string are @@ -673,6 +972,7 @@ uspoof_getAllowedUnicodeSet(const USpoofChecker *sc, UErrorCode *status); * enum USpoofChecks. (returned_value & USPOOF_ALL_CHECKS) * will be zero if the input string passes all of the * enabled checks. + * @see uspoof_check2 * @stable ICU 4.2 */ U_STABLE int32_t U_EXPORT2 @@ -687,15 +987,19 @@ uspoof_check(const USpoofChecker *sc, * The text to be checked will typically be an identifier of some sort. * The set of checks to be performed is specified with uspoof_setChecks(). * + * \note + * Consider using the newer API, {@link uspoof_check2UTF8}, instead. + * The newer API exposes additional information from the check procedure + * and is otherwise identical to this method. + * * @param sc The USpoofChecker * @param id A identifier to be checked for possible security issues, in UTF8 format. * @param length the length of the string to be checked, or -1 if the string is * zero terminated. - * @param position An out parameter. - * Originally, the index of the first string position that failed a check. - * Now, always returns zero. - * This parameter may be null. - * @deprecated ICU 51 + * @param position Deprecated in ICU 51. Always returns zero. + * Originally, an out parameter for the index of the first + * string position that failed a check. + * This parameter may be NULL. * @param status The error code, set if an error occurred while attempting to * perform the check. * Spoofing or security issues detected with the input string are @@ -707,6 +1011,7 @@ uspoof_check(const USpoofChecker *sc, * enum USpoofChecks. (returned_value & USPOOF_ALL_CHECKS) * will be zero if the input string passes all of the * enabled checks. + * @see uspoof_check2UTF8 * @stable ICU 4.2 */ U_STABLE int32_t U_EXPORT2 @@ -722,13 +1027,17 @@ uspoof_checkUTF8(const USpoofChecker *sc, * The text to be checked will typically be an identifier of some sort. * The set of checks to be performed is specified with uspoof_setChecks(). * + * \note + * Consider using the newer API, {@link uspoof_check2UnicodeString}, instead. + * The newer API exposes additional information from the check procedure + * and is otherwise identical to this method. + * * @param sc The USpoofChecker * @param id A identifier to be checked for possible security issues. - * @param position An out parameter. - * Originally, the index of the first string position that failed a check. - * Now, always returns zero. - * This parameter may be null. - * @deprecated ICU 51 + * @param position Deprecated in ICU 51. Always returns zero. + * Originally, an out parameter for the index of the first + * string position that failed a check. + * This parameter may be NULL. * @param status The error code, set if an error occurred while attempting to * perform the check. * Spoofing or security issues detected with the input string are @@ -738,6 +1047,7 @@ uspoof_checkUTF8(const USpoofChecker *sc, * enum USpoofChecks. (returned_value & USPOOF_ALL_CHECKS) * will be zero if the input string passes all of the * enabled checks. + * @see uspoof_check2UnicodeString * @stable ICU 4.2 */ U_STABLE int32_t U_EXPORT2 @@ -745,26 +1055,229 @@ uspoof_checkUnicodeString(const USpoofChecker *sc, const icu::UnicodeString &id, int32_t *position, UErrorCode *status); +#endif + + +#ifndef U_HIDE_DRAFT_API +/** + * Check the specified string for possible security issues. + * The text to be checked will typically be an identifier of some sort. + * The set of checks to be performed is specified with uspoof_setChecks(). + * + * @param sc The USpoofChecker + * @param id The identifier to be checked for possible security issues, + * in UTF-16 format. + * @param length the length of the string to be checked, or -1 if the string is + * zero terminated. + * @param checkResult An instance of USpoofCheckResult to be filled with + * details about the identifier. Can be NULL. + * @param status The error code, set if an error occurred while attempting to + * perform the check. + * Spoofing or security issues detected with the input string are + * not reported here, but through the function's return value. + * @return An integer value with bits set for any potential security + * or spoofing issues detected. The bits are defined by + * enum USpoofChecks. (returned_value & USPOOF_ALL_CHECKS) + * will be zero if the input string passes all of the + * enabled checks. Any information in this bitmask will be + * consistent with the information saved in the optional + * checkResult parameter. + * @see uspoof_openCheckResult + * @see uspoof_check2UTF8 + * @see uspoof_check2UnicodeString + * @draft ICU 58 + */ +U_DRAFT int32_t U_EXPORT2 +uspoof_check2(const USpoofChecker *sc, + const UChar* id, int32_t length, + USpoofCheckResult* checkResult, + UErrorCode *status); + +/** + * Check the specified string for possible security issues. + * The text to be checked will typically be an identifier of some sort. + * The set of checks to be performed is specified with uspoof_setChecks(). + * + * This version of {@link uspoof_check} accepts a USpoofCheckResult, which + * returns additional information about the identifier. For more + * information, see {@link uspoof_openCheckResult}. + * + * @param sc The USpoofChecker + * @param id A identifier to be checked for possible security issues, in UTF8 format. + * @param length the length of the string to be checked, or -1 if the string is + * zero terminated. + * @param checkResult An instance of USpoofCheckResult to be filled with + * details about the identifier. Can be NULL. + * @param status The error code, set if an error occurred while attempting to + * perform the check. + * Spoofing or security issues detected with the input string are + * not reported here, but through the function's return value. + * @return An integer value with bits set for any potential security + * or spoofing issues detected. The bits are defined by + * enum USpoofChecks. (returned_value & USPOOF_ALL_CHECKS) + * will be zero if the input string passes all of the + * enabled checks. Any information in this bitmask will be + * consistent with the information saved in the optional + * checkResult parameter. + * @see uspoof_openCheckResult + * @see uspoof_check2 + * @see uspoof_check2UnicodeString + * @draft ICU 58 + */ +U_DRAFT int32_t U_EXPORT2 +uspoof_check2UTF8(const USpoofChecker *sc, + const char *id, int32_t length, + USpoofCheckResult* checkResult, + UErrorCode *status); + +#if U_SHOW_CPLUSPLUS_API +/** + * Check the specified string for possible security issues. + * The text to be checked will typically be an identifier of some sort. + * The set of checks to be performed is specified with uspoof_setChecks(). + * + * @param sc The USpoofChecker + * @param id A identifier to be checked for possible security issues. + * @param checkResult An instance of USpoofCheckResult to be filled with + * details about the identifier. Can be NULL. + * @param status The error code, set if an error occurred while attempting to + * perform the check. + * Spoofing or security issues detected with the input string are + * not reported here, but through the function's return value. + * @return An integer value with bits set for any potential security + * or spoofing issues detected. The bits are defined by + * enum USpoofChecks. (returned_value & USPOOF_ALL_CHECKS) + * will be zero if the input string passes all of the + * enabled checks. Any information in this bitmask will be + * consistent with the information saved in the optional + * checkResult parameter. + * @see uspoof_openCheckResult + * @see uspoof_check2 + * @see uspoof_check2UTF8 + * @draft ICU 58 + */ +U_DRAFT int32_t U_EXPORT2 +uspoof_check2UnicodeString(const USpoofChecker *sc, + const icu::UnicodeString &id, + USpoofCheckResult* checkResult, + UErrorCode *status); +#endif + +/** + * Create a USpoofCheckResult, used by the {@link uspoof_check2} class of functions to return + * information about the identifier. Information includes: + * <ul> + * <li>A bitmask of the checks that failed</li> + * <li>The identifier's restriction level (UTS 39 section 5.2)</li> + * <li>The set of numerics in the string (UTS 39 section 5.3)</li> + * </ul> + * The data held in a USpoofCheckResult is cleared whenever it is passed into a new call + * of {@link uspoof_check2}. + * + * @param status The error code, set if this function encounters a problem. + * @return the newly created USpoofCheckResult + * @see uspoof_check2 + * @see uspoof_check2UTF8 + * @see uspoof_check2UnicodeString + * @draft ICU 58 + */ +U_DRAFT USpoofCheckResult* U_EXPORT2 +uspoof_openCheckResult(UErrorCode *status); + +/** + * Close a USpoofCheckResult, freeing any memory that was being held by + * its implementation. + * + * @param checkResult The instance of USpoofCheckResult to close + * @draft ICU 58 + */ +U_DRAFT void U_EXPORT2 +uspoof_closeCheckResult(USpoofCheckResult *checkResult); + +#if U_SHOW_CPLUSPLUS_API + +U_NAMESPACE_BEGIN + +/** + * \class LocalUSpoofCheckResultPointer + * "Smart pointer" class, closes a USpoofCheckResult via {@link uspoof_closeCheckResult}. + * For most methods see the LocalPointerBase base class. + * + * @see LocalPointerBase + * @see LocalPointer + * @draft ICU 58 + */ +U_DEFINE_LOCAL_OPEN_POINTER(LocalUSpoofCheckResultPointer, USpoofCheckResult, uspoof_closeCheckResult); + +U_NAMESPACE_END #endif +/** + * Indicates which of the spoof check(s) have failed. The value is a bitwise OR of the constants for the tests + * in question: USPOOF_RESTRICTION_LEVEL, USPOOF_CHAR_LIMIT, and so on. + * + * @param checkResult The instance of USpoofCheckResult created by {@link uspoof_openCheckResult} + * @param status The error code, set if an error occurred. + * @return An integer value with bits set for any potential security + * or spoofing issues detected. The bits are defined by + * enum USpoofChecks. (returned_value & USPOOF_ALL_CHECKS) + * will be zero if the input string passes all of the + * enabled checks. + * @see uspoof_setChecks + * @draft ICU 58 + */ +U_DRAFT int32_t U_EXPORT2 +uspoof_getCheckResultChecks(const USpoofCheckResult *checkResult, UErrorCode *status); + +/** + * Gets the restriction level that the text meets, if the USPOOF_RESTRICTION_LEVEL check + * was enabled; otherwise, undefined. + * + * @param checkResult The instance of USpoofCheckResult created by {@link uspoof_openCheckResult} + * @param status The error code, set if an error occurred. + * @return The restriction level contained in the USpoofCheckResult + * @see uspoof_setRestrictionLevel + * @draft ICU 58 + */ +U_DRAFT URestrictionLevel U_EXPORT2 +uspoof_getCheckResultRestrictionLevel(const USpoofCheckResult *checkResult, UErrorCode *status); + +/** + * Gets the set of numerics found in the string, if the USPOOF_MIXED_NUMBERS check was enabled; + * otherwise, undefined. The set will contain the zero digit from each decimal number system found + * in the input string. Ownership of the returned USet remains with the USpoofCheckResult. + * The USet will be free'd when {@link uspoof_closeCheckResult} is called. + * + * @param checkResult The instance of USpoofCheckResult created by {@link uspoof_openCheckResult} + * @return The set of numerics contained in the USpoofCheckResult + * @param status The error code, set if an error occurred. + * @draft ICU 58 + */ +U_DRAFT const USet* U_EXPORT2 +uspoof_getCheckResultNumerics(const USpoofCheckResult *checkResult, UErrorCode *status); +#endif /* U_HIDE_DRAFT_API */ + /** * Check the whether two specified strings are visually confusable. - * The types of confusability to be tested - single script, mixed script, - * or whole script - are determined by the check options set for the - * USpoofChecker. * - * The tests to be performed are controlled by the flags - * USPOOF_SINGLE_SCRIPT_CONFUSABLE - * USPOOF_MIXED_SCRIPT_CONFUSABLE - * USPOOF_WHOLE_SCRIPT_CONFUSABLE - * At least one of these tests must be selected. + * If the strings are confusable, the return value will be nonzero, as long as + * {@link USPOOF_CONFUSABLE} was enabled in uspoof_setChecks(). + * + * The bits in the return value correspond to flags for each of the classes of + * confusables applicable to the two input strings. According to UTS 39 + * section 4, the possible flags are: + * + * <ul> + * <li>{@link USPOOF_SINGLE_SCRIPT_CONFUSABLE}</li> + * <li>{@link USPOOF_MIXED_SCRIPT_CONFUSABLE}</li> + * <li>{@link USPOOF_WHOLE_SCRIPT_CONFUSABLE}</li> + * </ul> * - * USPOOF_ANY_CASE is a modifier for the tests. Select it if the identifiers - * may be of mixed case. - * If identifiers are case folded for comparison and - * display to the user, do not select the USPOOF_ANY_CASE option. + * If one or more of the above flags were not listed in uspoof_setChecks(), this + * function will never report that class of confusable. The check + * {@link USPOOF_CONFUSABLE} enables all three flags. * * * @param sc The USpoofChecker @@ -786,6 +1299,7 @@ uspoof_checkUnicodeString(const USpoofChecker *sc, * the type of confusability found, as defined by * enum USpoofChecks. Zero is returned if the identifiers * are not confusable. + * * @stable ICU 4.2 */ U_STABLE int32_t U_EXPORT2 @@ -797,10 +1311,7 @@ uspoof_areConfusable(const USpoofChecker *sc, /** - * Check the whether two specified strings are visually confusable. - * The types of confusability to be tested - single script, mixed script, - * or whole script - are determined by the check options set for the - * USpoofChecker. + * A version of {@link uspoof_areConfusable} accepting strings in UTF-8 format. * * @param sc The USpoofChecker * @param id1 The first of the two identifiers to be compared for @@ -819,7 +1330,10 @@ uspoof_areConfusable(const USpoofChecker *sc, * the type of confusability found, as defined by * enum USpoofChecks. Zero is returned if the strings * are not confusable. + * * @stable ICU 4.2 + * + * @see uspoof_areConfusable */ U_STABLE int32_t U_EXPORT2 uspoof_areConfusableUTF8(const USpoofChecker *sc, @@ -832,10 +1346,7 @@ uspoof_areConfusableUTF8(const USpoofChecker *sc, #if U_SHOW_CPLUSPLUS_API /** - * Check the whether two specified strings are visually confusable. - * The types of confusability to be tested - single script, mixed script, - * or whole script - are determined by the check options set for the - * USpoofChecker. + * A version of {@link uspoof_areConfusable} accepting UnicodeStrings. * * @param sc The USpoofChecker * @param s1 The first of the two identifiers to be compared for @@ -850,7 +1361,10 @@ uspoof_areConfusableUTF8(const USpoofChecker *sc, * the type of confusability found, as defined by * enum USpoofChecks. Zero is returned if the identifiers * are not confusable. + * * @stable ICU 4.2 + * + * @see uspoof_areConfusable */ U_STABLE int32_t U_EXPORT2 uspoof_areConfusableUnicodeString(const USpoofChecker *sc, @@ -861,37 +1375,36 @@ uspoof_areConfusableUnicodeString(const USpoofChecker *sc, /** - * Get the "skeleton" for an identifier. - * Skeletons are a transformation of the input identifier; - * Two identifiers are confusable if their skeletons are identical. - * See Unicode UAX #39 for additional information. - * - * Using skeletons directly makes it possible to quickly check - * whether an identifier is confusable with any of some large - * set of existing identifiers, by creating an efficiently - * searchable collection of the skeletons. - * - * @param sc The USpoofChecker - * @param type The type of skeleton, corresponding to which - * of the Unicode confusable data tables to use. - * The default is Mixed-Script, Lowercase. - * Allowed options are USPOOF_SINGLE_SCRIPT_CONFUSABLE and - * USPOOF_ANY_CASE. The two flags may be ORed. - * @param id The input identifier whose skeleton will be computed. - * @param length The length of the input identifier, expressed in 16 bit - * UTF-16 code units, or -1 if the string is zero terminated. - * @param dest The output buffer, to receive the skeleton string. - * @param destCapacity The length of the output buffer, in 16 bit units. - * The destCapacity may be zero, in which case the function will - * return the actual length of the skeleton. - * @param status The error code, set if an error occurred while attempting to - * perform the check. - * @return The length of the skeleton string. The returned length - * is always that of the complete skeleton, even when the - * supplied buffer is too small (or of zero length) - * - * @stable ICU 4.2 - */ + * Get the "skeleton" for an identifier. + * Skeletons are a transformation of the input identifier; + * Two identifiers are confusable if their skeletons are identical. + * See Unicode UAX #39 for additional information. + * + * Using skeletons directly makes it possible to quickly check + * whether an identifier is confusable with any of some large + * set of existing identifiers, by creating an efficiently + * searchable collection of the skeletons. + * + * @param sc The USpoofChecker + * @param type Deprecated in ICU 58. You may pass any number. + * Originally, controlled which of the Unicode confusable data + * tables to use. + * @param id The input identifier whose skeleton will be computed. + * @param length The length of the input identifier, expressed in 16 bit + * UTF-16 code units, or -1 if the string is zero terminated. + * @param dest The output buffer, to receive the skeleton string. + * @param destCapacity The length of the output buffer, in 16 bit units. + * The destCapacity may be zero, in which case the function will + * return the actual length of the skeleton. + * @param status The error code, set if an error occurred while attempting to + * perform the check. + * @return The length of the skeleton string. The returned length + * is always that of the complete skeleton, even when the + * supplied buffer is too small (or of zero length) + * + * @stable ICU 4.2 + * @see uspoof_areConfusable + */ U_STABLE int32_t U_EXPORT2 uspoof_getSkeleton(const USpoofChecker *sc, uint32_t type, @@ -900,40 +1413,38 @@ uspoof_getSkeleton(const USpoofChecker *sc, UErrorCode *status); /** - * Get the "skeleton" for an identifier. - * Skeletons are a transformation of the input identifier; - * Two identifiers are confusable if their skeletons are identical. - * See Unicode UAX #39 for additional information. - * - * Using skeletons directly makes it possible to quickly check - * whether an identifier is confusable with any of some large - * set of existing identifiers, by creating an efficiently - * searchable collection of the skeletons. - * - * @param sc The USpoofChecker - * @param type The type of skeleton, corresponding to which - * of the Unicode confusable data tables to use. - * The default is Mixed-Script, Lowercase. - * Allowed options are USPOOF_SINGLE_SCRIPT_CONFUSABLE and - * USPOOF_ANY_CASE. The two flags may be ORed. - * @param id The UTF-8 format identifier whose skeleton will be computed. - * @param length The length of the input string, in bytes, - * or -1 if the string is zero terminated. - * @param dest The output buffer, to receive the skeleton string. - * @param destCapacity The length of the output buffer, in bytes. - * The destCapacity may be zero, in which case the function will - * return the actual length of the skeleton. - * @param status The error code, set if an error occurred while attempting to - * perform the check. Possible Errors include U_INVALID_CHAR_FOUND - * for invalid UTF-8 sequences, and - * U_BUFFER_OVERFLOW_ERROR if the destination buffer is too small - * to hold the complete skeleton. - * @return The length of the skeleton string, in bytes. The returned length - * is always that of the complete skeleton, even when the - * supplied buffer is too small (or of zero length) - * - * @stable ICU 4.2 - */ + * Get the "skeleton" for an identifier. + * Skeletons are a transformation of the input identifier; + * Two identifiers are confusable if their skeletons are identical. + * See Unicode UAX #39 for additional information. + * + * Using skeletons directly makes it possible to quickly check + * whether an identifier is confusable with any of some large + * set of existing identifiers, by creating an efficiently + * searchable collection of the skeletons. + * + * @param sc The USpoofChecker + * @param type Deprecated in ICU 58. You may pass any number. + * Originally, controlled which of the Unicode confusable data + * tables to use. + * @param id The UTF-8 format identifier whose skeleton will be computed. + * @param length The length of the input string, in bytes, + * or -1 if the string is zero terminated. + * @param dest The output buffer, to receive the skeleton string. + * @param destCapacity The length of the output buffer, in bytes. + * The destCapacity may be zero, in which case the function will + * return the actual length of the skeleton. + * @param status The error code, set if an error occurred while attempting to + * perform the check. Possible Errors include U_INVALID_CHAR_FOUND + * for invalid UTF-8 sequences, and + * U_BUFFER_OVERFLOW_ERROR if the destination buffer is too small + * to hold the complete skeleton. + * @return The length of the skeleton string, in bytes. The returned length + * is always that of the complete skeleton, even when the + * supplied buffer is too small (or of zero length) + * + * @stable ICU 4.2 + */ U_STABLE int32_t U_EXPORT2 uspoof_getSkeletonUTF8(const USpoofChecker *sc, uint32_t type, @@ -943,30 +1454,28 @@ uspoof_getSkeletonUTF8(const USpoofChecker *sc, #if U_SHOW_CPLUSPLUS_API /** - * Get the "skeleton" for an identifier. - * Skeletons are a transformation of the input identifier; - * Two identifiers are confusable if their skeletons are identical. - * See Unicode UAX #39 for additional information. - * - * Using skeletons directly makes it possible to quickly check - * whether an identifier is confusable with any of some large - * set of existing identifiers, by creating an efficiently - * searchable collection of the skeletons. - * - * @param sc The USpoofChecker. - * @param type The type of skeleton, corresponding to which - * of the Unicode confusable data tables to use. - * The default is Mixed-Script, Lowercase. - * Allowed options are USPOOF_SINGLE_SCRIPT_CONFUSABLE and - * USPOOF_ANY_CASE. The two flags may be ORed. - * @param id The input identifier whose skeleton will be computed. - * @param dest The output identifier, to receive the skeleton string. - * @param status The error code, set if an error occurred while attempting to - * perform the check. - * @return A reference to the destination (skeleton) string. - * - * @stable ICU 4.2 - */ + * Get the "skeleton" for an identifier. + * Skeletons are a transformation of the input identifier; + * Two identifiers are confusable if their skeletons are identical. + * See Unicode UAX #39 for additional information. + * + * Using skeletons directly makes it possible to quickly check + * whether an identifier is confusable with any of some large + * set of existing identifiers, by creating an efficiently + * searchable collection of the skeletons. + * + * @param sc The USpoofChecker. + * @param type Deprecated in ICU 58. You may pass any number. + * Originally, controlled which of the Unicode confusable data + * tables to use. + * @param id The input identifier whose skeleton will be computed. + * @param dest The output identifier, to receive the skeleton string. + * @param status The error code, set if an error occurred while attempting to + * perform the check. + * @return A reference to the destination (skeleton) string. + * + * @stable ICU 4.2 + */ U_I18N_API icu::UnicodeString & U_EXPORT2 uspoof_getSkeletonUnicodeString(const USpoofChecker *sc, uint32_t type, @@ -977,7 +1486,8 @@ uspoof_getSkeletonUnicodeString(const USpoofChecker *sc, /** * Get the set of Candidate Characters for Inclusion in Identifiers, as defined - * in Unicode UAX #31, http://www.unicode.org/reports/tr31/#Table_Candidate_Characters_for_Inclusion_in_Identifiers + * in http://unicode.org/Public/security/latest/xidmodifications.txt + * and documented in http://www.unicode.org/reports/tr39/, Unicode Security Mechanisms. * * The returned set is frozen. Ownership of the set remains with the ICU library; it must not * be deleted by the caller. @@ -991,7 +1501,8 @@ uspoof_getInclusionSet(UErrorCode *status); /** * Get the set of characters from Recommended Scripts for Inclusion in Identifiers, as defined - * in Unicode UAX #31, http://www.unicode.org/reports/tr31/#Table_Recommended_Scripts + * in http://unicode.org/Public/security/latest/xidmodifications.txt + * and documented in http://www.unicode.org/reports/tr39/, Unicode Security Mechanisms. * * The returned set is frozen. Ownership of the set remains with the ICU library; it must not * be deleted by the caller. @@ -1007,7 +1518,8 @@ uspoof_getRecommendedSet(UErrorCode *status); /** * Get the set of Candidate Characters for Inclusion in Identifiers, as defined - * in Unicode UAX #31, http://www.unicode.org/reports/tr31/#Table_Candidate_Characters_for_Inclusion_in_Identifiers + * in http://unicode.org/Public/security/latest/xidmodifications.txt + * and documented in http://www.unicode.org/reports/tr39/, Unicode Security Mechanisms. * * The returned set is frozen. Ownership of the set remains with the ICU library; it must not * be deleted by the caller. @@ -1021,7 +1533,8 @@ uspoof_getInclusionUnicodeSet(UErrorCode *status); /** * Get the set of characters from Recommended Scripts for Inclusion in Identifiers, as defined - * in Unicode UAX #31, http://www.unicode.org/reports/tr31/#Table_Recommended_Scripts + * in http://unicode.org/Public/security/latest/xidmodifications.txt + * and documented in http://www.unicode.org/reports/tr39/, Unicode Security Mechanisms. * * The returned set is frozen. Ownership of the set remains with the ICU library; it must not * be deleted by the caller. diff --git a/deps/icu-small/source/i18n/unicode/utmscale.h b/deps/icu-small/source/i18n/unicode/utmscale.h index e22b1bc5e6..6b4b389ac8 100644 --- a/deps/icu-small/source/i18n/unicode/utmscale.h +++ b/deps/icu-small/source/i18n/unicode/utmscale.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2004 - 2008, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/unicode/utrans.h b/deps/icu-small/source/i18n/unicode/utrans.h index 4ada5ef93c..661ee5d385 100644 --- a/deps/icu-small/source/i18n/unicode/utrans.h +++ b/deps/icu-small/source/i18n/unicode/utrans.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 1997-2011,2014-2015 International Business Machines diff --git a/deps/icu-small/source/i18n/unicode/vtzone.h b/deps/icu-small/source/i18n/unicode/vtzone.h index 22992b197f..1682a3d526 100644 --- a/deps/icu-small/source/i18n/unicode/vtzone.h +++ b/deps/icu-small/source/i18n/unicode/vtzone.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2007-2013, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/unum.cpp b/deps/icu-small/source/i18n/unum.cpp index 4b617df36f..0e224858db 100644 --- a/deps/icu-small/source/i18n/unum.cpp +++ b/deps/icu-small/source/i18n/unum.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 1996-2015, International Business Machines diff --git a/deps/icu-small/source/i18n/unumsys.cpp b/deps/icu-small/source/i18n/unumsys.cpp index aab769dd03..f643e342eb 100644 --- a/deps/icu-small/source/i18n/unumsys.cpp +++ b/deps/icu-small/source/i18n/unumsys.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ***************************************************************************************** * Copyright (C) 2013, International Business Machines Corporation and others. diff --git a/deps/icu-small/source/i18n/upluralrules.cpp b/deps/icu-small/source/i18n/upluralrules.cpp index 1e92c8840f..5e1eebf53d 100644 --- a/deps/icu-small/source/i18n/upluralrules.cpp +++ b/deps/icu-small/source/i18n/upluralrules.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ***************************************************************************************** * Copyright (C) 2010-2012, International Business Machines diff --git a/deps/icu-small/source/i18n/uregex.cpp b/deps/icu-small/source/i18n/uregex.cpp index a6e6be26a7..03e2586c5f 100644 --- a/deps/icu-small/source/i18n/uregex.cpp +++ b/deps/icu-small/source/i18n/uregex.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2004-2015, International Business Machines diff --git a/deps/icu-small/source/i18n/uregexc.cpp b/deps/icu-small/source/i18n/uregexc.cpp index f430cdbf68..6d0dc2062c 100644 --- a/deps/icu-small/source/i18n/uregexc.cpp +++ b/deps/icu-small/source/i18n/uregexc.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2003-2006, International Business Machines diff --git a/deps/icu-small/source/i18n/uregion.cpp b/deps/icu-small/source/i18n/uregion.cpp index 58bd9d0a0c..8e079ec593 100644 --- a/deps/icu-small/source/i18n/uregion.cpp +++ b/deps/icu-small/source/i18n/uregion.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ***************************************************************************************** * Copyright (C) 2013-2015, International Business Machines Corporation and others. diff --git a/deps/icu-small/source/i18n/usearch.cpp b/deps/icu-small/source/i18n/usearch.cpp index a2aad7c674..5e1617eb3e 100644 --- a/deps/icu-small/source/i18n/usearch.cpp +++ b/deps/icu-small/source/i18n/usearch.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2001-2015 IBM and others. All rights reserved. @@ -222,7 +224,7 @@ inline int32_t * addTouint32_tArray(int32_t *destination, if (U_FAILURE(*status)) { return NULL; } - uprv_memcpy(temp, destination, sizeof(int32_t) * offset); + uprv_memcpy(temp, destination, sizeof(int32_t) * (size_t)offset); *destinationlength = newlength; destination = temp; } @@ -264,7 +266,7 @@ inline int64_t * addTouint64_tArray(int64_t *destination, return NULL; } - uprv_memcpy(temp, destination, sizeof(int64_t) * offset); + uprv_memcpy(temp, destination, sizeof(int64_t) * (size_t)offset); *destinationlength = newlength; destination = temp; } @@ -1379,7 +1381,7 @@ inline UChar * addToUCharArray( UChar *destination, } } if (source1length != 0) { - uprv_memcpy(destination, source1, sizeof(UChar) * source1length); + u_memcpy(destination, source1, source1length); } if (source2length != 0) { uprv_memcpy(destination + source1length, source2, diff --git a/deps/icu-small/source/i18n/uspoof.cpp b/deps/icu-small/source/i18n/uspoof.cpp index 341fff6ecd..3be10862fc 100644 --- a/deps/icu-small/source/i18n/uspoof.cpp +++ b/deps/icu-small/source/i18n/uspoof.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* *************************************************************************** * Copyright (C) 2008-2015, International Business Machines Corporation @@ -20,7 +22,6 @@ #include "unicode/utf16.h" #include "cmemory.h" #include "cstring.h" -#include "identifier_info.h" #include "mutex.h" #include "scriptset.h" #include "uassert.h" @@ -40,9 +41,7 @@ U_NAMESPACE_USE static UnicodeSet *gInclusionSet = NULL; static UnicodeSet *gRecommendedSet = NULL; static const Normalizer2 *gNfdNormalizer = NULL; -static SpoofData *gDefaultSpoofData = NULL; static UInitOnce gSpoofInitStaticsOnce = U_INITONCE_INITIALIZER; -static UInitOnce gSpoofInitDefaultOnce = U_INITONCE_INITIALIZER; static UBool U_CALLCONV uspoof_cleanup(void) { @@ -51,83 +50,78 @@ uspoof_cleanup(void) { delete gRecommendedSet; gRecommendedSet = NULL; gNfdNormalizer = NULL; - if (gDefaultSpoofData) { - gDefaultSpoofData->removeReference(); // Will delete, assuming all user-level spoof checkers were closed. - } - gDefaultSpoofData = NULL; gSpoofInitStaticsOnce.reset(); - gSpoofInitDefaultOnce.reset(); return TRUE; } static void U_CALLCONV initializeStatics(UErrorCode &status) { static const char *inclusionPat = - "[\\u0027\\u002D-\\u002E\\u003A\\u00B7\\u0375\\u058A\\u05F3-\\u05F4" - "\\u06FD-\\u06FE\\u0F0B\\u200C-\\u200D\\u2010\\u2019\\u2027\\u30A0\\u30FB]"; + "['\\-.\\:\\u00B7\\u0375\\u058A\\u05F3\\u05F4\\u06FD\\u06FE\\u0F0B\\u200C\\u200D\\u2010\\u" + "2019\\u2027\\u30A0\\u30FB]"; gInclusionSet = new UnicodeSet(UnicodeString(inclusionPat, -1, US_INV), status); gInclusionSet->freeze(); - // Note: data from http://unicode.org/Public/security/latest/xidmodifications.txt version 8.0.0 - // There is no tooling to generate this from the .txt file, hand extracted with editor macros. - // Ultimately, data will be available as character properties, eliminating this. + // Note: data from http://unicode.org/Public/security/9.0.0/IdentifierStatus.txt + // There is tooling to generate this constant in the unicodetools project: + // org.unicode.text.tools.RecommendedSetGenerator + // It will print the Java and C++ code to the console for easy copy-paste into this file. // Note: concatenated string constants do not work with UNICODE_STRING_SIMPLE on all platforms. static const char *recommendedPat = - "[\\u0030-\\u0039\\u0041-\\u005A\\u005F\\u0061-\\u007A\\u00C0-\\u00D6\\u00D8-\\u00F6" - "\\u00F8-\\u0131\\u0134-\\u013E\\u0141-\\u0148\\u014A-\\u017E\\u018F\\u01A0-\\u01A1" - "\\u01AF-\\u01B0\\u01CD-\\u01DC\\u01DE-\\u01E3\\u01E6-\\u01F0\\u01F4-\\u01F5\\u01F8-\\u021B" - "\\u021E-\\u021F\\u0226-\\u0233\\u0259\\u02BB-\\u02BC\\u02EC\\u0300-\\u0304\\u0306-\\u030C" - "\\u030F-\\u0311\\u0313-\\u0314\\u031B\\u0323-\\u0328\\u032D-\\u032E\\u0330-\\u0331" - "\\u0335\\u0338-\\u0339\\u0342\\u0345\\u037B-\\u037D\\u0386\\u0388-\\u038A\\u038C" - "\\u038E-\\u03A1\\u03A3-\\u03CE\\u03FC-\\u045F\\u048A-\\u0529\\u052E-\\u052F\\u0531-\\u0556" - "\\u0559\\u0561-\\u0586\\u05B4\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0620-\\u063F\\u0641-\\u0655" - "\\u0660-\\u0669\\u0670-\\u0672\\u0674\\u0679-\\u068D\\u068F-\\u06D3\\u06D5\\u06E5-\\u06E6" - "\\u06EE-\\u06FC\\u06FF\\u0750-\\u07B1\\u08A0-\\u08AC\\u08B2\\u0901-\\u094D\\u094F-\\u0950" - "\\u0956-\\u0957\\u0960-\\u0963\\u0966-\\u096F\\u0971-\\u0977\\u0979-\\u097F\\u0981-\\u0983" - "\\u0985-\\u098C\\u098F-\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9" - "\\u09BC-\\u09C4\\u09C7-\\u09C8\\u09CB-\\u09CE\\u09D7\\u09E0-\\u09E3\\u09E6-\\u09F1" - "\\u0A01-\\u0A03\\u0A05-\\u0A0A\\u0A0F-\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32" - "\\u0A35\\u0A38-\\u0A39\\u0A3C\\u0A3E-\\u0A42\\u0A47-\\u0A48\\u0A4B-\\u0A4D\\u0A5C" - "\\u0A66-\\u0A74\\u0A81-\\u0A83\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0" - "\\u0AB2-\\u0AB3\\u0AB5-\\u0AB9\\u0ABC-\\u0AC5\\u0AC7-\\u0AC9\\u0ACB-\\u0ACD\\u0AD0" - "\\u0AE0-\\u0AE3\\u0AE6-\\u0AEF\\u0B01-\\u0B03\\u0B05-\\u0B0C\\u0B0F-\\u0B10\\u0B13-\\u0B28" - "\\u0B2A-\\u0B30\\u0B32-\\u0B33\\u0B35-\\u0B39\\u0B3C-\\u0B43\\u0B47-\\u0B48\\u0B4B-\\u0B4D" - "\\u0B56-\\u0B57\\u0B5F-\\u0B61\\u0B66-\\u0B6F\\u0B71\\u0B82-\\u0B83\\u0B85-\\u0B8A" - "\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99-\\u0B9A\\u0B9C\\u0B9E-\\u0B9F\\u0BA3-\\u0BA4" - "\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BBE-\\u0BC2\\u0BC6-\\u0BC8\\u0BCA-\\u0BCD\\u0BD0" - "\\u0BD7\\u0BE6-\\u0BEF\\u0C01-\\u0C03\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28" - "\\u0C2A-\\u0C33\\u0C35-\\u0C39\\u0C3D-\\u0C44\\u0C46-\\u0C48\\u0C4A-\\u0C4D\\u0C55-\\u0C56" - "\\u0C60-\\u0C61\\u0C66-\\u0C6F\\u0C82-\\u0C83\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8" - "\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBC-\\u0CC4\\u0CC6-\\u0CC8\\u0CCA-\\u0CCD\\u0CD5-\\u0CD6" - "\\u0CE0-\\u0CE3\\u0CE6-\\u0CEF\\u0CF1-\\u0CF2\\u0D02-\\u0D03\\u0D05-\\u0D0C\\u0D0E-\\u0D10" - "\\u0D12-\\u0D3A\\u0D3D-\\u0D43\\u0D46-\\u0D48\\u0D4A-\\u0D4E\\u0D57\\u0D60-\\u0D61" - "\\u0D66-\\u0D6F\\u0D7A-\\u0D7F\\u0D82-\\u0D83\\u0D85-\\u0D8E\\u0D91-\\u0D96\\u0D9A-\\u0DA5" - "\\u0DA7-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0DCA\\u0DCF-\\u0DD4\\u0DD6" - "\\u0DD8-\\u0DDE\\u0DF2\\u0E01-\\u0E32\\u0E34-\\u0E3A\\u0E40-\\u0E4E\\u0E50-\\u0E59" - "\\u0E81-\\u0E82\\u0E84\\u0E87-\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F" - "\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA-\\u0EAB\\u0EAD-\\u0EB2\\u0EB4-\\u0EB9\\u0EBB-\\u0EBD" - "\\u0EC0-\\u0EC4\\u0EC6\\u0EC8-\\u0ECD\\u0ED0-\\u0ED9\\u0EDE-\\u0EDF\\u0F00\\u0F20-\\u0F29" - "\\u0F35\\u0F37\\u0F3E-\\u0F42\\u0F44-\\u0F47\\u0F49-\\u0F4C\\u0F4E-\\u0F51\\u0F53-\\u0F56" - "\\u0F58-\\u0F5B\\u0F5D-\\u0F68\\u0F6A-\\u0F6C\\u0F71-\\u0F72\\u0F74\\u0F7A-\\u0F80" - "\\u0F82-\\u0F84\\u0F86-\\u0F92\\u0F94-\\u0F97\\u0F99-\\u0F9C\\u0F9E-\\u0FA1\\u0FA3-\\u0FA6" - "\\u0FA8-\\u0FAB\\u0FAD-\\u0FB8\\u0FBA-\\u0FBC\\u0FC6\\u1000-\\u1049\\u1050-\\u109D" - "\\u10C7\\u10CD\\u10D0-\\u10F0\\u10F7-\\u10FA\\u10FD-\\u10FF\\u1200-\\u1248\\u124A-\\u124D" - "\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0" - "\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310" - "\\u1312-\\u1315\\u1318-\\u135A\\u135D-\\u135F\\u1380-\\u138F\\u1780-\\u17A2\\u17A5-\\u17A7" - "\\u17A9-\\u17B3\\u17B6-\\u17CA\\u17D2\\u17D7\\u17DC\\u17E0-\\u17E9\\u1E00-\\u1E99" - "\\u1E9E\\u1EA0-\\u1EF9\\u1F00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D" - "\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F70\\u1F72\\u1F74\\u1F76\\u1F78" - "\\u1F7A\\u1F7C\\u1F80-\\u1FB4\\u1FB6-\\u1FBA\\u1FBC\\u1FC2-\\u1FC4\\u1FC6-\\u1FC8" - "\\u1FCA\\u1FCC\\u1FD0-\\u1FD2\\u1FD6-\\u1FDA\\u1FE0-\\u1FE2\\u1FE4-\\u1FEA\\u1FEC" - "\\u1FF2-\\u1FF4\\u1FF6-\\u1FF8\\u1FFA\\u1FFC\\u2D27\\u2D2D\\u2D80-\\u2D96\\u2DA0-\\u2DA6" - "\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6" - "\\u2DD8-\\u2DDE\\u3005-\\u3007\\u3041-\\u3096\\u3099-\\u309A\\u309D-\\u309E\\u30A1-\\u30FA" - "\\u30FC-\\u30FE\\u3105-\\u312D\\u31A0-\\u31BA\\u3400-\\u4DB5\\u4E00-\\u9FD5\\uA660-\\uA661" - "\\uA674-\\uA67B\\uA67F\\uA69F\\uA717-\\uA71F\\uA788\\uA78D-\\uA78E\\uA790-\\uA793" - "\\uA7A0-\\uA7AA\\uA7FA\\uA9E7-\\uA9FE\\uAA60-\\uAA76\\uAA7A-\\uAA7F\\uAB01-\\uAB06" - "\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAC00-\\uD7A3\\uFA0E-\\uFA0F" - "\\uFA11\\uFA13-\\uFA14\\uFA1F\\uFA21\\uFA23-\\uFA24\\uFA27-\\uFA29\\U00020000-\\U0002A6D6" - "\\U0002A700-\\U0002B734\\U0002B740-\\U0002B81D\\U0002B820-\\U0002CEA1]"; + "[0-9A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u0131\\u0134-\\u013E\\u0141-\\u014" + "8\\u014A-\\u017E\\u018F\\u01A0\\u01A1\\u01AF\\u01B0\\u01CD-\\u01DC\\u01DE-\\u01E3\\u01E" + "6-\\u01F0\\u01F4\\u01F5\\u01F8-\\u021B\\u021E\\u021F\\u0226-\\u0233\\u0259\\u02BB\\u02B" + "C\\u02EC\\u0300-\\u0304\\u0306-\\u030C\\u030F-\\u0311\\u0313\\u0314\\u031B\\u0323-\\u03" + "28\\u032D\\u032E\\u0330\\u0331\\u0335\\u0338\\u0339\\u0342\\u0345\\u037B-\\u037D\\u0386" + "\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03CE\\u03FC-\\u045F\\u048A-\\u0529\\u05" + "2E\\u052F\\u0531-\\u0556\\u0559\\u0561-\\u0586\\u05B4\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0" + "620-\\u063F\\u0641-\\u0655\\u0660-\\u0669\\u0670-\\u0672\\u0674\\u0679-\\u068D\\u068F-" + "\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE-\\u06FC\\u06FF\\u0750-\\u07B1\\u08A0-\\u08AC\\u08B2" + "\\u08B6-\\u08BD\\u0901-\\u094D\\u094F\\u0950\\u0956\\u0957\\u0960-\\u0963\\u0966-\\u096" + "F\\u0971-\\u0977\\u0979-\\u097F\\u0981-\\u0983\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u0" + "9A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BC-\\u09C4\\u09C7\\u09C8\\u09CB-\\u09CE\\u" + "09D7\\u09E0-\\u09E3\\u09E6-\\u09F1\\u0A01-\\u0A03\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-" + "\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A35\\u0A38\\u0A39\\u0A3C\\u0A3E-\\u0A42\\u0A47\\u0A48\\" + "u0A4B-\\u0A4D\\u0A5C\\u0A66-\\u0A74\\u0A81-\\u0A83\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A9" + "3-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABC-\\u0AC5\\u0AC7-\\u0AC9\\u0" + "ACB-\\u0ACD\\u0AD0\\u0AE0-\\u0AE3\\u0AE6-\\u0AEF\\u0B01-\\u0B03\\u0B05-\\u0B0C\\u0B0F\\" + "u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3C-\\u0B43\\u0B47" + "\\u0B48\\u0B4B-\\u0B4D\\u0B56\\u0B57\\u0B5F-\\u0B61\\u0B66-\\u0B6F\\u0B71\\u0B82\\u0B83" + "\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3" + "\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BBE-\\u0BC2\\u0BC6-\\u0BC8\\u0BCA-\\u0BCD\\u0B" + "D0\\u0BD7\\u0BE6-\\u0BEF\\u0C01-\\u0C03\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u" + "0C2A-\\u0C33\\u0C35-\\u0C39\\u0C3D-\\u0C44\\u0C46-\\u0C48\\u0C4A-\\u0C4D\\u0C55\\u0C56" + "\\u0C60\\u0C61\\u0C66-\\u0C6F\\u0C80\\u0C82\\u0C83\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92" + "-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBC-\\u0CC4\\u0CC6-\\u0CC8\\u0CCA-\\u0CCD\\u0" + "CD5\\u0CD6\\u0CE0-\\u0CE3\\u0CE6-\\u0CEF\\u0CF1\\u0CF2\\u0D02\\u0D03\\u0D05-\\u0D0C\\u0" + "D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D-\\u0D43\\u0D46-\\u0D48\\u0D4A-\\u0D4E\\u0D54-\\u0D57" + "\\u0D60\\u0D61\\u0D66-\\u0D6F\\u0D7A-\\u0D7F\\u0D82\\u0D83\\u0D85-\\u0D8E\\u0D91-\\u0D9" + "6\\u0D9A-\\u0DA5\\u0DA7-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0DCA\\u0DCF-\\u0" + "DD4\\u0DD6\\u0DD8-\\u0DDE\\u0DF2\\u0E01-\\u0E32\\u0E34-\\u0E3A\\u0E40-\\u0E4E\\u0E50-\\" + "u0E59\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u" + "0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB2\\u0EB4-\\u0EB9\\u0EBB-\\u0EBD\\" + "u0EC0-\\u0EC4\\u0EC6\\u0EC8-\\u0ECD\\u0ED0-\\u0ED9\\u0EDE\\u0EDF\\u0F00\\u0F20-\\u0F29" + "\\u0F35\\u0F37\\u0F3E-\\u0F42\\u0F44-\\u0F47\\u0F49-\\u0F4C\\u0F4E-\\u0F51\\u0F53-\\u0F" + "56\\u0F58-\\u0F5B\\u0F5D-\\u0F68\\u0F6A-\\u0F6C\\u0F71\\u0F72\\u0F74\\u0F7A-\\u0F80\\u0" + "F82-\\u0F84\\u0F86-\\u0F92\\u0F94-\\u0F97\\u0F99-\\u0F9C\\u0F9E-\\u0FA1\\u0FA3-\\u0FA6" + "\\u0FA8-\\u0FAB\\u0FAD-\\u0FB8\\u0FBA-\\u0FBC\\u0FC6\\u1000-\\u1049\\u1050-\\u109D\\u10" + "C7\\u10CD\\u10D0-\\u10F0\\u10F7-\\u10FA\\u10FD-\\u10FF\\u1200-\\u1248\\u124A-\\u124D\\u" + "1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2" + "-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1" + "315\\u1318-\\u135A\\u135D-\\u135F\\u1380-\\u138F\\u1780-\\u17A2\\u17A5-\\u17A7\\u17A9-" + "\\u17B3\\u17B6-\\u17CA\\u17D2\\u17D7\\u17DC\\u17E0-\\u17E9\\u1C80-\\u1C88\\u1E00-\\u1E9" + "9\\u1E9E\\u1EA0-\\u1EF9\\u1F00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1" + "F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F70\\u1F72\\u1F74\\u1F76\\u1F78\\u1F7A\\u1F" + "7C\\u1F80-\\u1FB4\\u1FB6-\\u1FBA\\u1FBC\\u1FC2-\\u1FC4\\u1FC6-\\u1FC8\\u1FCA\\u1FCC\\u1" + "FD0-\\u1FD2\\u1FD6-\\u1FDA\\u1FE0-\\u1FE2\\u1FE4-\\u1FEA\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-" + "\\u1FF8\\u1FFA\\u1FFC\\u2D27\\u2D2D\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0" + "-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u3" + "005-\\u3007\\u3041-\\u3096\\u3099\\u309A\\u309D\\u309E\\u30A1-\\u30FA\\u30FC-\\u30FE\\u" + "3105-\\u312D\\u31A0-\\u31BA\\u3400-\\u4DB5\\u4E00-\\u9FD5\\uA660\\uA661\\uA674-\\uA67B" + "\\uA67F\\uA69F\\uA717-\\uA71F\\uA788\\uA78D\\uA78E\\uA790-\\uA793\\uA7A0-\\uA7AA\\uA7AE" + "\\uA7FA\\uA9E7-\\uA9FE\\uAA60-\\uAA76\\uAA7A-\\uAA7F\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB" + "11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAC00-\\uD7A3\\uFA0E\\uFA0F\\uFA11\\uFA13\\uF" + "A14\\uFA1F\\uFA21\\uFA23\\uFA24\\uFA27-\\uFA29\\U00020000-\\U0002A6D6\\U0002A700-\\U0" + "002B734\\U0002B740-\\U0002B81D\\U0002B820-\\U0002CEA1]"; gRecommendedSet = new UnicodeSet(UnicodeString(recommendedPat, -1, US_INV), status); gRecommendedSet->freeze(); @@ -135,11 +129,6 @@ static void U_CALLCONV initializeStatics(UErrorCode &status) { ucln_i18n_registerCleanup(UCLN_I18N_SPOOF, uspoof_cleanup); } -static void U_CALLCONV initializeDefaultData(UErrorCode &status) { - gDefaultSpoofData = SpoofData::getDefault(status); - ucln_i18n_registerCleanup(UCLN_I18N_SPOOF, uspoof_cleanup); -} - U_CFUNC void uspoof_internalInitStatics(UErrorCode *status) { umtx_initOnce(gSpoofInitStaticsOnce, &initializeStatics, *status); } @@ -147,14 +136,10 @@ U_CFUNC void uspoof_internalInitStatics(UErrorCode *status) { U_CAPI USpoofChecker * U_EXPORT2 uspoof_open(UErrorCode *status) { umtx_initOnce(gSpoofInitStaticsOnce, &initializeStatics, *status); - umtx_initOnce(gSpoofInitDefaultOnce, &initializeDefaultData, *status); if (U_FAILURE(*status)) { return NULL; } - SpoofImpl *si = new SpoofImpl(gDefaultSpoofData, *status); - if (si) { - gDefaultSpoofData->addReference(); - } + SpoofImpl *si = new SpoofImpl(*status); if (U_SUCCESS(*status) && si == NULL) { *status = U_MEMORY_ALLOCATION_ERROR; } @@ -162,7 +147,7 @@ uspoof_open(UErrorCode *status) { delete si; si = NULL; } - return reinterpret_cast<USpoofChecker *>(si); + return si->asUSpoofChecker(); } @@ -188,9 +173,9 @@ uspoof_openFromSerialized(const void *data, int32_t length, int32_t *pActualLeng } if (pActualLength != NULL) { - *pActualLength = sd->fRawData->fLength; + *pActualLength = sd->size(); } - return reinterpret_cast<USpoofChecker *>(si); + return si->asUSpoofChecker(); } @@ -205,7 +190,7 @@ uspoof_clone(const USpoofChecker *sc, UErrorCode *status) { delete result; result = NULL; } - return reinterpret_cast<USpoofChecker *>(result); + return result->asUSpoofChecker(); } @@ -250,6 +235,7 @@ uspoof_setRestrictionLevel(USpoofChecker *sc, URestrictionLevel restrictionLevel SpoofImpl *This = SpoofImpl::validateThis(sc, status); if (This != NULL) { This->fRestrictionLevel = restrictionLevel; + This->fChecks |= USPOOF_RESTRICTION_LEVEL; } } @@ -333,6 +319,22 @@ uspoof_check(const USpoofChecker *sc, int32_t *position, UErrorCode *status) { + // Backwards compatibility: + if (position != NULL) { + *position = 0; + } + + // Delegate to uspoof_check2 + return uspoof_check2(sc, id, length, NULL, status); +} + + +U_CAPI int32_t U_EXPORT2 +uspoof_check2(const USpoofChecker *sc, + const UChar* id, int32_t length, + USpoofCheckResult* checkResult, + UErrorCode *status) { + const SpoofImpl *This = SpoofImpl::validateThis(sc, *status); if (This == NULL) { return 0; @@ -342,7 +344,7 @@ uspoof_check(const USpoofChecker *sc, return 0; } UnicodeString idStr((length == -1), id, length); // Aliasing constructor. - int32_t result = uspoof_checkUnicodeString(sc, idStr, position, status); + int32_t result = uspoof_check2UnicodeString(sc, idStr, checkResult, status); return result; } @@ -353,11 +355,27 @@ uspoof_checkUTF8(const USpoofChecker *sc, int32_t *position, UErrorCode *status) { + // Backwards compatibility: + if (position != NULL) { + *position = 0; + } + + // Delegate to uspoof_check2 + return uspoof_check2UTF8(sc, id, length, NULL, status); +} + + +U_CAPI int32_t U_EXPORT2 +uspoof_check2UTF8(const USpoofChecker *sc, + const char *id, int32_t length, + USpoofCheckResult* checkResult, + UErrorCode *status) { + if (U_FAILURE(*status)) { return 0; } UnicodeString idStr = UnicodeString::fromUTF8(StringPiece(id, length>=0 ? length : uprv_strlen(id))); - int32_t result = uspoof_checkUnicodeString(sc, idStr, position, status); + int32_t result = uspoof_check2UnicodeString(sc, idStr, checkResult, status); return result; } @@ -419,125 +437,95 @@ uspoof_areConfusableUnicodeString(const USpoofChecker *sc, // If no tests relavant to this function have been specified, return an error. // TODO: is this really the right thing to do? It's probably an error on the caller's part, // but logically we would just return 0 (no error). - if ((This->fChecks & (USPOOF_SINGLE_SCRIPT_CONFUSABLE | USPOOF_MIXED_SCRIPT_CONFUSABLE | - USPOOF_WHOLE_SCRIPT_CONFUSABLE)) == 0) { + if ((This->fChecks & USPOOF_CONFUSABLE) == 0) { *status = U_INVALID_STATE_ERROR; return 0; } - int32_t flagsForSkeleton = This->fChecks & USPOOF_ANY_CASE; - int32_t result = 0; - IdentifierInfo *identifierInfo = This->getIdentifierInfo(*status); - if (U_FAILURE(*status)) { + // Compute the skeletons and check for confusability. + UnicodeString id1Skeleton; + uspoof_getSkeletonUnicodeString(sc, 0 /* deprecated */, id1, id1Skeleton, status); + UnicodeString id2Skeleton; + uspoof_getSkeletonUnicodeString(sc, 0 /* deprecated */, id2, id2Skeleton, status); + if (U_FAILURE(*status)) { return 0; } + if (id1Skeleton != id2Skeleton) { return 0; } - identifierInfo->setIdentifier(id1, *status); - int32_t id1ScriptCount = identifierInfo->getScriptCount(); - int32_t id1FirstScript = identifierInfo->getScripts()->nextSetBit(0); - identifierInfo->setIdentifier(id2, *status); - int32_t id2ScriptCount = identifierInfo->getScriptCount(); - int32_t id2FirstScript = identifierInfo->getScripts()->nextSetBit(0); - This->releaseIdentifierInfo(identifierInfo); - identifierInfo = NULL; - - if (This->fChecks & USPOOF_SINGLE_SCRIPT_CONFUSABLE) { - UnicodeString id1Skeleton; - UnicodeString id2Skeleton; - if (id1ScriptCount <= 1 && id2ScriptCount <= 1 && id1FirstScript == id2FirstScript) { - flagsForSkeleton |= USPOOF_SINGLE_SCRIPT_CONFUSABLE; - uspoof_getSkeletonUnicodeString(sc, flagsForSkeleton, id1, id1Skeleton, status); - uspoof_getSkeletonUnicodeString(sc, flagsForSkeleton, id2, id2Skeleton, status); - if (id1Skeleton == id2Skeleton) { - result |= USPOOF_SINGLE_SCRIPT_CONFUSABLE; - } + + // If we get here, the strings are confusable. Now we just need to set the flags for the appropriate classes + // of confusables according to UTS 39 section 4. + // Start by computing the resolved script sets of id1 and id2. + ScriptSet id1RSS; + This->getResolvedScriptSet(id1, id1RSS, *status); + ScriptSet id2RSS; + This->getResolvedScriptSet(id2, id2RSS, *status); + + // Turn on all applicable flags + int32_t result = 0; + if (id1RSS.intersects(id2RSS)) { + result |= USPOOF_SINGLE_SCRIPT_CONFUSABLE; + } else { + result |= USPOOF_MIXED_SCRIPT_CONFUSABLE; + if (!id1RSS.isEmpty() && !id2RSS.isEmpty()) { + result |= USPOOF_WHOLE_SCRIPT_CONFUSABLE; } } - if (result & USPOOF_SINGLE_SCRIPT_CONFUSABLE) { - // If the two inputs are single script confusable they cannot also be - // mixed or whole script confusable, according to the UAX39 definitions. - // So we can skip those tests. - return result; + // Turn off flags that the user doesn't want + if ((This->fChecks & USPOOF_SINGLE_SCRIPT_CONFUSABLE) == 0) { + result &= ~USPOOF_SINGLE_SCRIPT_CONFUSABLE; } - - // Two identifiers are whole script confusable if each is of a single script - // and they are mixed script confusable. - UBool possiblyWholeScriptConfusables = - id1ScriptCount <= 1 && id2ScriptCount <= 1 && (This->fChecks & USPOOF_WHOLE_SCRIPT_CONFUSABLE); - - // - // Mixed Script Check - // - if ((This->fChecks & USPOOF_MIXED_SCRIPT_CONFUSABLE) || possiblyWholeScriptConfusables ) { - // For getSkeleton(), resetting the USPOOF_SINGLE_SCRIPT_CONFUSABLE flag will get us - // the mixed script table skeleton, which is what we want. - // The Any Case / Lower Case bit in the skelton flags was set at the top of the function. - UnicodeString id1Skeleton; - UnicodeString id2Skeleton; - flagsForSkeleton &= ~USPOOF_SINGLE_SCRIPT_CONFUSABLE; - uspoof_getSkeletonUnicodeString(sc, flagsForSkeleton, id1, id1Skeleton, status); - uspoof_getSkeletonUnicodeString(sc, flagsForSkeleton, id2, id2Skeleton, status); - if (id1Skeleton == id2Skeleton) { - result |= USPOOF_MIXED_SCRIPT_CONFUSABLE; - if (possiblyWholeScriptConfusables) { - result |= USPOOF_WHOLE_SCRIPT_CONFUSABLE; - } - } + if ((This->fChecks & USPOOF_MIXED_SCRIPT_CONFUSABLE) == 0) { + result &= ~USPOOF_MIXED_SCRIPT_CONFUSABLE; + } + if ((This->fChecks & USPOOF_WHOLE_SCRIPT_CONFUSABLE) == 0) { + result &= ~USPOOF_WHOLE_SCRIPT_CONFUSABLE; } return result; } - - U_CAPI int32_t U_EXPORT2 uspoof_checkUnicodeString(const USpoofChecker *sc, const icu::UnicodeString &id, int32_t *position, UErrorCode *status) { - const SpoofImpl *This = SpoofImpl::validateThis(sc, *status); - if (This == NULL) { - return 0; - } - int32_t result = 0; - IdentifierInfo *identifierInfo = NULL; - if ((This->fChecks) & (USPOOF_RESTRICTION_LEVEL | USPOOF_MIXED_NUMBERS)) { - identifierInfo = This->getIdentifierInfo(*status); - if (U_FAILURE(*status)) { - goto cleanupAndReturn; - } - identifierInfo->setIdentifier(id, *status); - identifierInfo->setIdentifierProfile(*This->fAllowedCharsSet); + // Backwards compatibility: + if (position != NULL) { + *position = 0; } + // Delegate to uspoof_check2 + return uspoof_check2UnicodeString(sc, id, NULL, status); +} + +int32_t checkImpl(const SpoofImpl* This, const UnicodeString& id, CheckResult* checkResult, UErrorCode* status) { + U_ASSERT(This != NULL); + U_ASSERT(checkResult != NULL); + checkResult->clear(); + int32_t result = 0; - if ((This->fChecks) & USPOOF_RESTRICTION_LEVEL) { - URestrictionLevel idRestrictionLevel = identifierInfo->getRestrictionLevel(*status); + if (0 != (This->fChecks & USPOOF_RESTRICTION_LEVEL)) { + URestrictionLevel idRestrictionLevel = This->getRestrictionLevel(id, *status); if (idRestrictionLevel > This->fRestrictionLevel) { result |= USPOOF_RESTRICTION_LEVEL; } - if (This->fChecks & USPOOF_AUX_INFO) { - result |= idRestrictionLevel; - } + checkResult->fRestrictionLevel = idRestrictionLevel; } - if ((This->fChecks) & USPOOF_MIXED_NUMBERS) { - const UnicodeSet *numerics = identifierInfo->getNumerics(); - if (numerics->size() > 1) { + if (0 != (This->fChecks & USPOOF_MIXED_NUMBERS)) { + UnicodeSet numerics; + This->getNumerics(id, numerics, *status); + if (numerics.size() > 1) { result |= USPOOF_MIXED_NUMBERS; } - - // TODO: ICU4J returns the UnicodeSet of the numerics found in the identifier. - // We have no easy way to do the same in C. - // if (checkResult != null) { - // checkResult.numerics = numerics; - // } + checkResult->fNumerics = numerics; // UnicodeSet::operator= } - if (This->fChecks & (USPOOF_CHAR_LIMIT)) { + if (0 != (This->fChecks & USPOOF_CHAR_LIMIT)) { int32_t i; UChar32 c; int32_t length = id.length(); @@ -551,103 +539,74 @@ uspoof_checkUnicodeString(const USpoofChecker *sc, } } - if (This->fChecks & - (USPOOF_WHOLE_SCRIPT_CONFUSABLE | USPOOF_MIXED_SCRIPT_CONFUSABLE | USPOOF_INVISIBLE)) { - // These are the checks that need to be done on NFD input + if (0 != (This->fChecks & USPOOF_INVISIBLE)) { + // This check needs to be done on NFD input UnicodeString nfdText; gNfdNormalizer->normalize(id, nfdText, *status); int32_t nfdLength = nfdText.length(); - if (This->fChecks & USPOOF_INVISIBLE) { - - // scan for more than one occurence of the same non-spacing mark - // in a sequence of non-spacing marks. - int32_t i; - UChar32 c; - UChar32 firstNonspacingMark = 0; - UBool haveMultipleMarks = FALSE; - UnicodeSet marksSeenSoFar; // Set of combining marks in a single combining sequence. - - for (i=0; i<nfdLength ;) { - c = nfdText.char32At(i); - i += U16_LENGTH(c); - if (u_charType(c) != U_NON_SPACING_MARK) { - firstNonspacingMark = 0; - if (haveMultipleMarks) { - marksSeenSoFar.clear(); - haveMultipleMarks = FALSE; - } - continue; - } - if (firstNonspacingMark == 0) { - firstNonspacingMark = c; - continue; - } - if (!haveMultipleMarks) { - marksSeenSoFar.add(firstNonspacingMark); - haveMultipleMarks = TRUE; - } - if (marksSeenSoFar.contains(c)) { - // report the error, and stop scanning. - // No need to find more than the first failure. - result |= USPOOF_INVISIBLE; - break; - } - marksSeenSoFar.add(c); - } - } - + // scan for more than one occurence of the same non-spacing mark + // in a sequence of non-spacing marks. + int32_t i; + UChar32 c; + UChar32 firstNonspacingMark = 0; + UBool haveMultipleMarks = FALSE; + UnicodeSet marksSeenSoFar; // Set of combining marks in a single combining sequence. - if (This->fChecks & (USPOOF_WHOLE_SCRIPT_CONFUSABLE | USPOOF_MIXED_SCRIPT_CONFUSABLE)) { - // The basic test is the same for both whole and mixed script confusables. - // Compute the set of scripts that every input character has a confusable in. - // For this computation an input character is always considered to be - // confusable with itself in its own script. - // - // If the number of such scripts is two or more, and the input consisted of - // characters all from a single script, we have a whole script confusable. - // (The two scripts will be the original script and the one that is confusable) - // - // If the number of such scripts >= one, and the original input contained characters from - // more than one script, we have a mixed script confusable. (We can transform - // some of the characters, and end up with a visually similar string all in - // one script.) - - if (identifierInfo == NULL) { - identifierInfo = This->getIdentifierInfo(*status); - if (U_FAILURE(*status)) { - goto cleanupAndReturn; + for (i=0; i<nfdLength ;) { + c = nfdText.char32At(i); + i += U16_LENGTH(c); + if (u_charType(c) != U_NON_SPACING_MARK) { + firstNonspacingMark = 0; + if (haveMultipleMarks) { + marksSeenSoFar.clear(); + haveMultipleMarks = FALSE; } - identifierInfo->setIdentifier(id, *status); + continue; } - - int32_t scriptCount = identifierInfo->getScriptCount(); - - ScriptSet scripts; - This->wholeScriptCheck(nfdText, &scripts, *status); - int32_t confusableScriptCount = scripts.countMembers(); - //printf("confusableScriptCount = %d\n", confusableScriptCount); - - if ((This->fChecks & USPOOF_WHOLE_SCRIPT_CONFUSABLE) && - confusableScriptCount >= 2 && - scriptCount == 1) { - result |= USPOOF_WHOLE_SCRIPT_CONFUSABLE; + if (firstNonspacingMark == 0) { + firstNonspacingMark = c; + continue; } - - if ((This->fChecks & USPOOF_MIXED_SCRIPT_CONFUSABLE) && - confusableScriptCount >= 1 && - scriptCount > 1) { - result |= USPOOF_MIXED_SCRIPT_CONFUSABLE; + if (!haveMultipleMarks) { + marksSeenSoFar.add(firstNonspacingMark); + haveMultipleMarks = TRUE; } + if (marksSeenSoFar.contains(c)) { + // report the error, and stop scanning. + // No need to find more than the first failure. + result |= USPOOF_INVISIBLE; + break; + } + marksSeenSoFar.add(c); } } -cleanupAndReturn: - This->releaseIdentifierInfo(identifierInfo); - if (position != NULL) { - *position = 0; + checkResult->fChecks = result; + return checkResult->toCombinedBitmask(This->fChecks); +} + +U_CAPI int32_t U_EXPORT2 +uspoof_check2UnicodeString(const USpoofChecker *sc, + const icu::UnicodeString &id, + USpoofCheckResult* checkResult, + UErrorCode *status) { + const SpoofImpl *This = SpoofImpl::validateThis(sc, *status); + if (This == NULL) { + return FALSE; + } + + if (checkResult != NULL) { + CheckResult* ThisCheckResult = CheckResult::validateThis(checkResult, *status); + if (ThisCheckResult == NULL) { + return FALSE; + } + return checkImpl(This, id, ThisCheckResult, status); + } else { + // Stack-allocate the checkResult since this method doesn't return it + CheckResult stackCheckResult; + return checkImpl(This, id, &stackCheckResult, status); } - return result; } @@ -678,7 +637,7 @@ uspoof_getSkeleton(const USpoofChecker *sc, U_I18N_API UnicodeString & U_EXPORT2 uspoof_getSkeletonUnicodeString(const USpoofChecker *sc, - uint32_t type, + uint32_t /*type*/, const UnicodeString &id, UnicodeString &dest, UErrorCode *status) { @@ -687,21 +646,9 @@ uspoof_getSkeletonUnicodeString(const USpoofChecker *sc, return dest; } - int32_t tableMask = 0; - switch (type) { - case 0: - tableMask = USPOOF_ML_TABLE_FLAG; - break; - case USPOOF_SINGLE_SCRIPT_CONFUSABLE: - tableMask = USPOOF_SL_TABLE_FLAG; - break; - case USPOOF_ANY_CASE: - tableMask = USPOOF_MA_TABLE_FLAG; - break; - case USPOOF_SINGLE_SCRIPT_CONFUSABLE | USPOOF_ANY_CASE: - tableMask = USPOOF_SA_TABLE_FLAG; - break; - default: + // Check that at least one of the CONFUSABLE flags is turned on. If not, + // return an error. + if ((This->fChecks & USPOOF_CONFUSABLE) == 0) { *status = U_ILLEGAL_ARGUMENT_ERROR; return dest; } @@ -717,7 +664,7 @@ uspoof_getSkeletonUnicodeString(const USpoofChecker *sc, for (inputIndex=0; inputIndex < normalizedLen; ) { UChar32 c = nfdId.char32At(inputIndex); inputIndex += U16_LENGTH(c); - This->confusableLookup(c, tableMask, skelStr); + This->fSpoofData->confusableLookup(c, skelStr); } gNfdNormalizer->normalize(skelStr, dest, *status); @@ -761,13 +708,8 @@ uspoof_serialize(USpoofChecker *sc,void *buf, int32_t capacity, UErrorCode *stat U_ASSERT(U_FAILURE(*status)); return 0; } - int32_t dataSize = This->fSpoofData->fRawData->fLength; - if (capacity < dataSize) { - *status = U_BUFFER_OVERFLOW_ERROR; - return dataSize; - } - uprv_memcpy(buf, This->fSpoofData->fRawData, dataSize); - return dataSize; + + return This->fSpoofData->serialize(buf, capacity, *status); } U_CAPI const USet * U_EXPORT2 @@ -794,6 +736,48 @@ uspoof_getRecommendedUnicodeSet(UErrorCode *status) { return gRecommendedSet; } +//------------------ +// CheckResult APIs +//------------------ + +U_CAPI USpoofCheckResult* U_EXPORT2 +uspoof_openCheckResult(UErrorCode *status) { + CheckResult* checkResult = new CheckResult(); + if (checkResult == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + return NULL; + } + return checkResult->asUSpoofCheckResult(); +} + +U_CAPI void U_EXPORT2 +uspoof_closeCheckResult(USpoofCheckResult* checkResult) { + UErrorCode status = U_ZERO_ERROR; + CheckResult* This = CheckResult::validateThis(checkResult, status); + delete This; +} + +U_CAPI int32_t U_EXPORT2 +uspoof_getCheckResultChecks(const USpoofCheckResult *checkResult, UErrorCode *status) { + const CheckResult* This = CheckResult::validateThis(checkResult, *status); + if (U_FAILURE(*status)) { return 0; } + return This->fChecks; +} + +U_CAPI URestrictionLevel U_EXPORT2 +uspoof_getCheckResultRestrictionLevel(const USpoofCheckResult *checkResult, UErrorCode *status) { + const CheckResult* This = CheckResult::validateThis(checkResult, *status); + if (U_FAILURE(*status)) { return USPOOF_UNRESTRICTIVE; } + return This->fRestrictionLevel; +} + +U_CAPI const USet* U_EXPORT2 +uspoof_getCheckResultNumerics(const USpoofCheckResult *checkResult, UErrorCode *status) { + const CheckResult* This = CheckResult::validateThis(checkResult, *status); + if (U_FAILURE(*status)) { return NULL; } + return This->fNumerics.toUSet(); +} + #endif // !UCONFIG_NO_NORMALIZATION diff --git a/deps/icu-small/source/i18n/uspoof_build.cpp b/deps/icu-small/source/i18n/uspoof_build.cpp index 0a404faf76..d676fe9977 100644 --- a/deps/icu-small/source/i18n/uspoof_build.cpp +++ b/deps/icu-small/source/i18n/uspoof_build.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* *************************************************************************** * Copyright (C) 2008-2015, International Business Machines Corporation @@ -35,7 +37,6 @@ #include "uassert.h" #include "uarrsort.h" #include "uspoof_conf.h" -#include "uspoof_wsconf.h" #if !UCONFIG_NO_NORMALIZATION @@ -48,7 +49,7 @@ U_CFUNC void uspoof_internalInitStatics(UErrorCode *status); U_CAPI USpoofChecker * U_EXPORT2 uspoof_openFromSource(const char *confusables, int32_t confusablesLen, - const char *confusablesWholeScript, int32_t confusablesWholeScriptLen, + const char* /*confusablesWholeScript*/, int32_t /*confusablesWholeScriptLen*/, int32_t *errorType, UParseError *pe, UErrorCode *status) { uspoof_internalInitStatics(status); if (U_FAILURE(*status)) { @@ -74,7 +75,6 @@ uspoof_openFromSource(const char *confusables, int32_t confusablesLen, // Compile the binary data from the source (text) format. ConfusabledataBuilder::buildConfusableData(This, confusables, confusablesLen, errorType, pe, *status); - buildWSConfusableData(This, confusablesWholeScript, confusablesWholeScriptLen, pe, *status); if (U_FAILURE(*status)) { delete This; diff --git a/deps/icu-small/source/i18n/uspoof_conf.cpp b/deps/icu-small/source/i18n/uspoof_conf.cpp index aba8375e7c..6edd1fa3f3 100644 --- a/deps/icu-small/source/i18n/uspoof_conf.cpp +++ b/deps/icu-small/source/i18n/uspoof_conf.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * @@ -43,11 +45,13 @@ U_NAMESPACE_USE // // The binary structures are described in uspoof_impl.h // -// 1. parse the data, building 4 hash tables, one each for the SL, SA, ML and MA -// tables. Each maps from a UChar32 to a String. +// 1. Parse the data, making a hash table mapping from a UChar32 to a String. // // 2. Sort all of the strings encountered by length, since they will need to // be stored in that order in the final string table. +// TODO: Sorting these strings by length is no longer needed since the removal of +// the string lengths table. This logic can be removed to save processing time +// when building confusables data. // // 3. Build a list of keys (UChar32s) from the four mapping tables. Sort the // list because that will be the ordering of our runtime table. @@ -61,7 +65,7 @@ U_NAMESPACE_USE SPUString::SPUString(UnicodeString *s) { fStr = s; - fStrTableIndex = 0; + fCharOrStrTableIndex = 0; } @@ -143,15 +147,11 @@ SPUString *SPUStringPool::addString(UnicodeString *src, UErrorCode &status) { ConfusabledataBuilder::ConfusabledataBuilder(SpoofImpl *spImpl, UErrorCode &status) : fSpoofImpl(spImpl), fInput(NULL), - fSLTable(NULL), - fSATable(NULL), - fMLTable(NULL), - fMATable(NULL), + fTable(NULL), fKeySet(NULL), fKeyVec(NULL), fValueVec(NULL), fStringTable(NULL), - fStringLengthsTable(NULL), stringPool(NULL), fParseLine(NULL), fParseHexNum(NULL), @@ -160,10 +160,7 @@ ConfusabledataBuilder::ConfusabledataBuilder(SpoofImpl *spImpl, UErrorCode &stat if (U_FAILURE(status)) { return; } - fSLTable = uhash_open(uhash_hashLong, uhash_compareLong, NULL, &status); - fSATable = uhash_open(uhash_hashLong, uhash_compareLong, NULL, &status); - fMLTable = uhash_open(uhash_hashLong, uhash_compareLong, NULL, &status); - fMATable = uhash_open(uhash_hashLong, uhash_compareLong, NULL, &status); + fTable = uhash_open(uhash_hashLong, uhash_compareLong, NULL, &status); fKeySet = new UnicodeSet(); fKeyVec = new UVector(status); fValueVec = new UVector(status); @@ -175,14 +172,10 @@ ConfusabledataBuilder::~ConfusabledataBuilder() { uprv_free(fInput); uregex_close(fParseLine); uregex_close(fParseHexNum); - uhash_close(fSLTable); - uhash_close(fSATable); - uhash_close(fMLTable); - uhash_close(fMATable); + uhash_close(fTable); delete fKeySet; delete fKeyVec; delete fStringTable; - delete fStringLengthsTable; delete fValueVec; delete stringPool; } @@ -228,7 +221,7 @@ void ConfusabledataBuilder::build(const char * confusables, int32_t confusablesL // any line. What was matched is determined by examining which capture groups have a match. // Capture Group 1: the source char // Capture Group 2: the replacement chars - // Capture Group 3-6 the table type, SL, SA, ML, or MA + // Capture Group 3-6 the table type, SL, SA, ML, or MA (deprecated) // Capture Group 7: A blank or comment only line. // Capture Group 8: A syntactically invalid line. Anything that didn't match before. // Example Line from the confusables.txt source file: @@ -294,41 +287,12 @@ void ConfusabledataBuilder::build(const char * confusables, int32_t confusablesL // This a little like a Java intern() - any duplicates will be eliminated. SPUString *smapString = stringPool->addString(mapString, status); - // Add the UChar32 -> string mapping to the appropriate table. - UHashtable *table = uregex_start(fParseLine, 3, &status) >= 0 ? fSLTable : - uregex_start(fParseLine, 4, &status) >= 0 ? fSATable : - uregex_start(fParseLine, 5, &status) >= 0 ? fMLTable : - uregex_start(fParseLine, 6, &status) >= 0 ? fMATable : - NULL; - if (U_SUCCESS(status) && table == NULL) { - status = U_PARSE_ERROR; - } - if (U_FAILURE(status)) { - return; - } - + // Add the UChar32 -> string mapping to the table. // For Unicode 8, the SL, SA and ML tables have been discontinued. // All input data from confusables.txt is tagged MA. - // ICU spoof check functions should ignore the specified table and always - // use this MA Data. - // For now, implement by populating the MA data into all four tables, and - // keep the multiple table implementation in place, in case it comes back - // at some time in the future. - // There is no run time size penalty to keeping the four table implementation - - // the data is shared when it's the same betweeen tables. - if (table != fMATable) { - status = U_PARSE_ERROR; - return; - }; - // uhash_iput(table, keyChar, smapString, &status); - uhash_iput(fSLTable, keyChar, smapString, &status); - uhash_iput(fSATable, keyChar, smapString, &status); - uhash_iput(fMLTable, keyChar, smapString, &status); - uhash_iput(fMATable, keyChar, smapString, &status); + uhash_iput(fTable, keyChar, smapString, &status); + if (U_FAILURE(status)) { return; } fKeySet->add(keyChar); - if (U_FAILURE(status)) { - return; - } } // Input data is now all parsed and collected. @@ -341,43 +305,24 @@ void ConfusabledataBuilder::build(const char * confusables, int32_t confusablesL // Build up the string array, and record the index of each string therein // in the (build time only) string pool. // Strings of length one are not entered into the strings array. - // At the same time, build up the string lengths table, which records the - // position in the string table of the first string of each length >= 4. // (Strings in the table are sorted by length) stringPool->sort(status); fStringTable = new UnicodeString(); - fStringLengthsTable = new UVector(status); - int32_t previousStringLength = 0; - int32_t previousStringIndex = 0; int32_t poolSize = stringPool->size(); int32_t i; for (i=0; i<poolSize; i++) { SPUString *s = stringPool->getByIndex(i); int32_t strLen = s->fStr->length(); int32_t strIndex = fStringTable->length(); - U_ASSERT(strLen >= previousStringLength); if (strLen == 1) { // strings of length one do not get an entry in the string table. // Keep the single string character itself here, which is the same // convention that is used in the final run-time string table index. - s->fStrTableIndex = s->fStr->charAt(0); + s->fCharOrStrTableIndex = s->fStr->charAt(0); } else { - if ((strLen > previousStringLength) && (previousStringLength >= 4)) { - fStringLengthsTable->addElement(previousStringIndex, status); - fStringLengthsTable->addElement(previousStringLength, status); - } - s->fStrTableIndex = strIndex; + s->fCharOrStrTableIndex = strIndex; fStringTable->append(*(s->fStr)); } - previousStringLength = strLen; - previousStringIndex = strIndex; - } - // Make the final entry to the string lengths table. - // (it holds an entry for the _last_ string of each length, so adding the - // final one doesn't happen in the main loop because no longer string was encountered.) - if (previousStringLength >= 4) { - fStringLengthsTable->addElement(previousStringIndex, status); - fStringLengthsTable->addElement(previousStringLength, status); } // Construct the compile-time Key and Value tables @@ -396,10 +341,22 @@ void ConfusabledataBuilder::build(const char * confusables, int32_t confusablesL // code points requires a nested loop. for (UChar32 keyChar=fKeySet->getRangeStart(range); keyChar <= fKeySet->getRangeEnd(range); keyChar++) { - addKeyEntry(keyChar, fSLTable, USPOOF_SL_TABLE_FLAG, status); - addKeyEntry(keyChar, fSATable, USPOOF_SA_TABLE_FLAG, status); - addKeyEntry(keyChar, fMLTable, USPOOF_ML_TABLE_FLAG, status); - addKeyEntry(keyChar, fMATable, USPOOF_MA_TABLE_FLAG, status); + SPUString *targetMapping = static_cast<SPUString *>(uhash_iget(fTable, keyChar)); + U_ASSERT(targetMapping != NULL); + + // Set an error code if trying to consume a long string. Otherwise, + // codePointAndLengthToKey will abort on a U_ASSERT. + if (targetMapping->fStr->length() > 256) { + status = U_ILLEGAL_ARGUMENT_ERROR; + return; + } + + int32_t key = ConfusableDataUtils::codePointAndLengthToKey(keyChar, + targetMapping->fStr->length()); + int32_t value = targetMapping->fCharOrStrTableIndex; + + fKeyVec->addElement(key, status); + fValueVec->addElement(value, status); } } @@ -435,14 +392,14 @@ void ConfusabledataBuilder::outputData(UErrorCode &status) { return; } int i; - int32_t previousKey = 0; + UChar32 previousCodePoint = 0; for (i=0; i<numKeys; i++) { int32_t key = fKeyVec->elementAti(i); - (void)previousKey; // Suppress unused variable warning on gcc. - U_ASSERT((key & 0x00ffffff) >= (previousKey & 0x00ffffff)); - U_ASSERT((key & 0xff000000) != 0); + UChar32 codePoint = ConfusableDataUtils::keyToCodePoint(key); + // strictly greater because there can be only one entry per code point + U_ASSERT(codePoint > previousCodePoint); keys[i] = key; - previousKey = key; + previousCodePoint = codePoint; } SpoofDataHeader *rawData = fSpoofImpl->fSpoofData->fRawData; rawData->fCFUKeys = (int32_t)((char *)keys - (char *)rawData); @@ -484,143 +441,6 @@ void ConfusabledataBuilder::outputData(UErrorCode &status) { rawData->fCFUStringTable = (int32_t)((char *)strings - (char *)rawData); rawData->fCFUStringTableLen = stringsLength; fSpoofImpl->fSpoofData->fCFUStrings = strings; - - // The String Lengths Table - // While copying into the runtime array do some sanity checks on the values - // Each complete entry contains two fields, an index and an offset. - // Lengths should increase with each entry. - // Offsets should be less than the size of the string table. - int32_t lengthTableLength = fStringLengthsTable->size(); - uint16_t *stringLengths = - static_cast<uint16_t *>(fSpoofImpl->fSpoofData->reserveSpace(lengthTableLength*sizeof(uint16_t), status)); - if (U_FAILURE(status)) { - return; - } - int32_t destIndex = 0; - uint32_t previousLength = 0; - for (i=0; i<lengthTableLength; i+=2) { - uint32_t offset = static_cast<uint32_t>(fStringLengthsTable->elementAti(i)); - uint32_t length = static_cast<uint32_t>(fStringLengthsTable->elementAti(i+1)); - U_ASSERT(offset < stringsLength); - U_ASSERT(length < 40); - (void)previousLength; // Suppress unused variable warning on gcc. - U_ASSERT(length > previousLength); - stringLengths[destIndex++] = static_cast<uint16_t>(offset); - stringLengths[destIndex++] = static_cast<uint16_t>(length); - previousLength = length; - } - rawData = fSpoofImpl->fSpoofData->fRawData; - rawData->fCFUStringLengths = (int32_t)((char *)stringLengths - (char *)rawData); - // Note: StringLengthsSize in the raw data is the number of complete entries, - // each consisting of a pair of 16 bit values, hence the divide by 2. - rawData->fCFUStringLengthsSize = lengthTableLength / 2; - fSpoofImpl->fSpoofData->fCFUStringLengths = - reinterpret_cast<SpoofStringLengthsElement *>(stringLengths); -} - - - -// addKeyEntry Construction of the confusable Key and Mapping Values tables. -// This is an intermediate point in the building process. -// We already have the mappings in the hash tables fSLTable, etc. -// This function builds corresponding run-time style table entries into -// fKeyVec and fValueVec - -void ConfusabledataBuilder::addKeyEntry( - UChar32 keyChar, // The key character - UHashtable *table, // The table, one of SATable, MATable, etc. - int32_t tableFlag, // One of USPOOF_SA_TABLE_FLAG, etc. - UErrorCode &status) { - - SPUString *targetMapping = static_cast<SPUString *>(uhash_iget(table, keyChar)); - if (targetMapping == NULL) { - // No mapping for this key character. - // (This function is called for all four tables for each key char that - // is seen anywhere, so this no entry cases are very much expected.) - return; - } - - // Check whether there is already an entry with the correct mapping. - // If so, simply set the flag in the keyTable saying that the existing entry - // applies to the table that we're doing now. - - UBool keyHasMultipleValues = FALSE; - int32_t i; - for (i=fKeyVec->size()-1; i>=0 ; i--) { - int32_t key = fKeyVec->elementAti(i); - if ((key & 0x0ffffff) != keyChar) { - // We have now checked all existing key entries for this key char (if any) - // without finding one with the same mapping. - break; - } - UnicodeString mapping = getMapping(i); - if (mapping == *(targetMapping->fStr)) { - // The run time entry we are currently testing has the correct mapping. - // Set the flag in it indicating that it applies to the new table also. - key |= tableFlag; - fKeyVec->setElementAt(key, i); - return; - } - keyHasMultipleValues = TRUE; - } - - // Need to add a new entry to the binary data being built for this mapping. - // Includes adding entries to both the key table and the parallel values table. - - int32_t newKey = keyChar | tableFlag; - if (keyHasMultipleValues) { - newKey |= USPOOF_KEY_MULTIPLE_VALUES; - } - int32_t adjustedMappingLength = targetMapping->fStr->length() - 1; - if (adjustedMappingLength>3) { - adjustedMappingLength = 3; - } - newKey |= adjustedMappingLength << USPOOF_KEY_LENGTH_SHIFT; - - int32_t newData = targetMapping->fStrTableIndex; - - fKeyVec->addElement(newKey, status); - fValueVec->addElement(newData, status); - - // If the preceding key entry is for the same key character (but with a different mapping) - // set the multiple-values flag on it. - if (keyHasMultipleValues) { - int32_t previousKeyIndex = fKeyVec->size() - 2; - int32_t previousKey = fKeyVec->elementAti(previousKeyIndex); - previousKey |= USPOOF_KEY_MULTIPLE_VALUES; - fKeyVec->setElementAt(previousKey, previousKeyIndex); - } -} - - - -UnicodeString ConfusabledataBuilder::getMapping(int32_t index) { - int32_t key = fKeyVec->elementAti(index); - int32_t value = fValueVec->elementAti(index); - int32_t length = USPOOF_KEY_LENGTH_FIELD(key); - int32_t lastIndexWithLen; - switch (length) { - case 0: - return UnicodeString(static_cast<UChar>(value)); - case 1: - case 2: - return UnicodeString(*fStringTable, value, length+1); - case 3: - length = 0; - int32_t i; - for (i=0; i<fStringLengthsTable->size(); i+=2) { - lastIndexWithLen = fStringLengthsTable->elementAti(i); - if (value <= lastIndexWithLen) { - length = fStringLengthsTable->elementAti(i+1); - break; - } - } - U_ASSERT(length>=3); - return UnicodeString(*fStringTable, value, length); - default: - U_ASSERT(FALSE); - } - return UnicodeString(); } #endif diff --git a/deps/icu-small/source/i18n/uspoof_conf.h b/deps/icu-small/source/i18n/uspoof_conf.h index 2157142be6..72cd028104 100644 --- a/deps/icu-small/source/i18n/uspoof_conf.h +++ b/deps/icu-small/source/i18n/uspoof_conf.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * @@ -36,9 +38,9 @@ U_NAMESPACE_BEGIN struct SPUString : public UMemory { UnicodeString *fStr; // The actual string. - int32_t fStrTableIndex; // Index into the final runtime data for this string. - // (or, for length 1, the single string char itself, - // there being no string table entry for it.) + int32_t fCharOrStrTableIndex; // Index into the final runtime data for this + // string (or, for length 1, the single string char + // itself, there being no string table entry for it.) SPUString(UnicodeString *s); ~SPUString(); }; @@ -86,10 +88,7 @@ class ConfusabledataBuilder : public UMemory { private: SpoofImpl *fSpoofImpl; UChar *fInput; - UHashtable *fSLTable; - UHashtable *fSATable; - UHashtable *fMLTable; - UHashtable *fMATable; + UHashtable *fTable; UnicodeSet *fKeySet; // A set of all keys (UChar32s) that go into the four mapping tables. // The binary data is first assembled into the following four collections, then @@ -97,7 +96,6 @@ class ConfusabledataBuilder : public UMemory { UVector *fKeyVec; UVector *fValueVec; UnicodeString *fStringTable; - UVector *fStringLengthsTable; SPUStringPool *stringPool; URegularExpression *fParseLine; diff --git a/deps/icu-small/source/i18n/uspoof_impl.cpp b/deps/icu-small/source/i18n/uspoof_impl.cpp index 111a1489ff..fba742c3ff 100644 --- a/deps/icu-small/source/i18n/uspoof_impl.cpp +++ b/deps/icu-small/source/i18n/uspoof_impl.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2008-2016, International Business Machines @@ -13,11 +15,11 @@ #include "utrie2.h" #include "cmemory.h" #include "cstring.h" -#include "identifier_info.h" #include "scriptset.h" #include "umutex.h" #include "udataswp.h" #include "uassert.h" +#include "ucln_in.h" #include "uspoof_impl.h" #if !UCONFIG_NO_NORMALIZATION @@ -27,41 +29,53 @@ U_NAMESPACE_BEGIN UOBJECT_DEFINE_RTTI_IMPLEMENTATION(SpoofImpl) -SpoofImpl::SpoofImpl(SpoofData *data, UErrorCode &status) : - fMagic(0), fChecks(USPOOF_ALL_CHECKS), fSpoofData(data), fAllowedCharsSet(NULL) , - fAllowedLocales(NULL), fCachedIdentifierInfo(NULL) { - if (U_FAILURE(status)) { - return; - } +SpoofImpl::SpoofImpl(SpoofData *data, UErrorCode& status) { + construct(status); + fSpoofData = data; +} + +SpoofImpl::SpoofImpl(UErrorCode& status) { + construct(status); + + // TODO: Call this method where it is actually needed, instead of in the + // constructor, to allow for lazy data loading. See #12696. + fSpoofData = SpoofData::getDefault(status); +} + +SpoofImpl::SpoofImpl() { + UErrorCode status = U_ZERO_ERROR; + construct(status); + + // TODO: Call this method where it is actually needed, instead of in the + // constructor, to allow for lazy data loading. See #12696. + fSpoofData = SpoofData::getDefault(status); +} + +void SpoofImpl::construct(UErrorCode& status) { + fMagic = USPOOF_MAGIC; + fChecks = USPOOF_ALL_CHECKS; + fSpoofData = NULL; + fAllowedCharsSet = NULL; + fAllowedLocales = NULL; fRestrictionLevel = USPOOF_HIGHLY_RESTRICTIVE; + if (U_FAILURE(status)) { return; } + UnicodeSet *allowedCharsSet = new UnicodeSet(0, 0x10ffff); - allowedCharsSet->freeze(); fAllowedCharsSet = allowedCharsSet; fAllowedLocales = uprv_strdup(""); if (fAllowedCharsSet == NULL || fAllowedLocales == NULL) { status = U_MEMORY_ALLOCATION_ERROR; return; } - fMagic = USPOOF_MAGIC; -} - - -SpoofImpl::SpoofImpl() : - fMagic(USPOOF_MAGIC), fChecks(USPOOF_ALL_CHECKS), fSpoofData(NULL), fAllowedCharsSet(NULL) , - fAllowedLocales(NULL), fCachedIdentifierInfo(NULL) { - UnicodeSet *allowedCharsSet = new UnicodeSet(0, 0x10ffff); allowedCharsSet->freeze(); - fAllowedCharsSet = allowedCharsSet; - fAllowedLocales = uprv_strdup(""); - fRestrictionLevel = USPOOF_HIGHLY_RESTRICTIVE; } // Copy Constructor, used by the user level clone() function. SpoofImpl::SpoofImpl(const SpoofImpl &src, UErrorCode &status) : fMagic(0), fChecks(USPOOF_ALL_CHECKS), fSpoofData(NULL), fAllowedCharsSet(NULL) , - fAllowedLocales(NULL), fCachedIdentifierInfo(NULL) { + fAllowedLocales(NULL) { if (U_FAILURE(status)) { return; } @@ -71,10 +85,10 @@ SpoofImpl::SpoofImpl(const SpoofImpl &src, UErrorCode &status) : fSpoofData = src.fSpoofData->addReference(); } fAllowedCharsSet = static_cast<const UnicodeSet *>(src.fAllowedCharsSet->clone()); - if (fAllowedCharsSet == NULL) { + fAllowedLocales = uprv_strdup(src.fAllowedLocales); + if (fAllowedCharsSet == NULL || fAllowedLocales == NULL) { status = U_MEMORY_ALLOCATION_ERROR; } - fAllowedLocales = uprv_strdup(src.fAllowedLocales); fRestrictionLevel = src.fRestrictionLevel; } @@ -86,7 +100,11 @@ SpoofImpl::~SpoofImpl() { } delete fAllowedCharsSet; uprv_free((void *)fAllowedLocales); - delete fCachedIdentifierInfo; +} + +// Cast this instance as a USpoofChecker for the C API. +USpoofChecker *SpoofImpl::asUSpoofChecker() { + return reinterpret_cast<USpoofChecker*>(this); } // @@ -102,12 +120,11 @@ const SpoofImpl *SpoofImpl::validateThis(const USpoofChecker *sc, UErrorCode &st return NULL; } SpoofImpl *This = (SpoofImpl *)sc; - if (This->fMagic != USPOOF_MAGIC || - This->fSpoofData == NULL) { + if (This->fMagic != USPOOF_MAGIC) { status = U_INVALID_FORMAT_ERROR; return NULL; } - if (!SpoofData::validateDataVersion(This->fSpoofData->fRawData, status)) { + if (This->fSpoofData != NULL && !This->fSpoofData->validateDataVersion(status)) { return NULL; } return This; @@ -119,148 +136,6 @@ SpoofImpl *SpoofImpl::validateThis(USpoofChecker *sc, UErrorCode &status) { } - -//-------------------------------------------------------------------------------------- -// -// confusableLookup() This is the heart of the confusable skeleton generation -// implementation. -// -// Given a source character, produce the corresponding -// replacement character(s), appending them to the dest string. -// -//--------------------------------------------------------------------------------------- -int32_t SpoofImpl::confusableLookup(UChar32 inChar, int32_t tableMask, UnicodeString &dest) const { - - // Binary search the spoof data key table for the inChar - int32_t *low = fSpoofData->fCFUKeys; - int32_t *mid = NULL; - int32_t *limit = low + fSpoofData->fRawData->fCFUKeysSize; - UChar32 midc; - do { - int32_t delta = ((int32_t)(limit-low))/2; - mid = low + delta; - midc = *mid & 0x1fffff; - if (inChar == midc) { - goto foundChar; - } else if (inChar < midc) { - limit = mid; - } else { - low = mid; - } - } while (low < limit-1); - mid = low; - midc = *mid & 0x1fffff; - if (inChar != midc) { - // Char not found. It maps to itself. - int i = 0; - dest.append(inChar); - return i; - } - foundChar: - int32_t keyFlags = *mid & 0xff000000; - if ((keyFlags & tableMask) == 0) { - // We found the right key char, but the entry doesn't pertain to the - // table we need. See if there is an adjacent key that does - if (keyFlags & USPOOF_KEY_MULTIPLE_VALUES) { - int32_t *altMid; - for (altMid = mid-1; (*altMid&0x00ffffff) == inChar; altMid--) { - keyFlags = *altMid & 0xff000000; - if (keyFlags & tableMask) { - mid = altMid; - goto foundKey; - } - } - for (altMid = mid+1; (*altMid&0x00ffffff) == inChar; altMid++) { - keyFlags = *altMid & 0xff000000; - if (keyFlags & tableMask) { - mid = altMid; - goto foundKey; - } - } - } - // No key entry for this char & table. - // The input char maps to itself. - int i = 0; - dest.append(inChar); - return i; - } - - foundKey: - int32_t stringLen = USPOOF_KEY_LENGTH_FIELD(keyFlags) + 1; - int32_t keyTableIndex = (int32_t)(mid - fSpoofData->fCFUKeys); - - // Value is either a UChar (for strings of length 1) or - // an index into the string table (for longer strings) - uint16_t value = fSpoofData->fCFUValues[keyTableIndex]; - if (stringLen == 1) { - dest.append((UChar)value); - return 1; - } - - // String length of 4 from the above lookup is used for all strings of length >= 4. - // For these, get the real length from the string lengths table, - // which maps string table indexes to lengths. - // All strings of the same length are stored contiguously in the string table. - // 'value' from the lookup above is the starting index for the desired string. - - int32_t ix; - if (stringLen == 4) { - int32_t stringLengthsLimit = fSpoofData->fRawData->fCFUStringLengthsSize; - for (ix = 0; ix < stringLengthsLimit; ix++) { - if (fSpoofData->fCFUStringLengths[ix].fLastString >= value) { - stringLen = fSpoofData->fCFUStringLengths[ix].fStrLength; - break; - } - } - U_ASSERT(ix < stringLengthsLimit); - } - - U_ASSERT(value + stringLen <= fSpoofData->fRawData->fCFUStringTableLen); - UChar *src = &fSpoofData->fCFUStrings[value]; - dest.append(src, stringLen); - return stringLen; -} - - -//--------------------------------------------------------------------------------------- -// -// wholeScriptCheck() -// -// Input text is already normalized to NFD -// Return the set of scripts, each of which can represent something that is -// confusable with the input text. The script of the input text -// is included; input consisting of characters from a single script will -// always produce a result consisting of a set containing that script. -// -//--------------------------------------------------------------------------------------- -void SpoofImpl::wholeScriptCheck( - const UnicodeString &text, ScriptSet *result, UErrorCode &status) const { - - UTrie2 *table = - (fChecks & USPOOF_ANY_CASE) ? fSpoofData->fAnyCaseTrie : fSpoofData->fLowerCaseTrie; - result->setAll(); - int32_t length = text.length(); - for (int32_t inputIdx=0; inputIdx < length;) { - UChar32 c = text.char32At(inputIdx); - inputIdx += U16_LENGTH(c); - uint32_t index = utrie2_get32(table, c); - if (index == 0) { - // No confusables in another script for this char. - // TODO: we should change the data to have sets with just the single script - // bit for the script of this char. Gets rid of this special case. - // Until then, grab the script from the char and intersect it with the set. - UScriptCode cpScript = uscript_getScript(c, &status); - U_ASSERT(cpScript > USCRIPT_INHERITED); - result->intersect(cpScript, status); - } else if (index == 1) { - // Script == Common or Inherited. Nothing to do. - } else { - result->intersect(fSpoofData->fScriptSets[index]); - } - } -} - - void SpoofImpl::setAllowedLocales(const char *localesList, UErrorCode &status) { UnicodeSet allowedChars; UnicodeSet *tmpSet = NULL; @@ -372,6 +247,137 @@ void SpoofImpl::addScriptChars(const char *locale, UnicodeSet *allowedChars, UEr } } +// Computes the augmented script set for a code point, according to UTS 39 section 5.1. +void SpoofImpl::getAugmentedScriptSet(UChar32 codePoint, ScriptSet& result, UErrorCode& status) { + result.resetAll(); + result.setScriptExtensions(codePoint, status); + if (U_FAILURE(status)) { return; } + + // Section 5.1 step 1 + if (result.test(USCRIPT_HAN, status)) { + result.set(USCRIPT_HAN_WITH_BOPOMOFO, status); + result.set(USCRIPT_JAPANESE, status); + result.set(USCRIPT_KOREAN, status); + } + if (result.test(USCRIPT_HIRAGANA, status)) { + result.set(USCRIPT_JAPANESE, status); + } + if (result.test(USCRIPT_KATAKANA, status)) { + result.set(USCRIPT_JAPANESE, status); + } + if (result.test(USCRIPT_HANGUL, status)) { + result.set(USCRIPT_KOREAN, status); + } + if (result.test(USCRIPT_BOPOMOFO, status)) { + result.set(USCRIPT_HAN_WITH_BOPOMOFO, status); + } + + // Section 5.1 step 2 + if (result.test(USCRIPT_COMMON, status) || result.test(USCRIPT_INHERITED, status)) { + result.setAll(); + } +} + +// Computes the resolved script set for a string, according to UTS 39 section 5.1. +void SpoofImpl::getResolvedScriptSet(const UnicodeString& input, ScriptSet& result, UErrorCode& status) const { + getResolvedScriptSetWithout(input, USCRIPT_CODE_LIMIT, result, status); +} + +// Computes the resolved script set for a string, omitting characters having the specified script. +// If USCRIPT_CODE_LIMIT is passed as the second argument, all characters are included. +void SpoofImpl::getResolvedScriptSetWithout(const UnicodeString& input, UScriptCode script, ScriptSet& result, UErrorCode& status) const { + result.setAll(); + + ScriptSet temp; + UChar32 codePoint; + for (int32_t i = 0; i < input.length(); i += U16_LENGTH(codePoint)) { + codePoint = input.char32At(i); + + // Compute the augmented script set for the character + getAugmentedScriptSet(codePoint, temp, status); + if (U_FAILURE(status)) { return; } + + // Intersect the augmented script set with the resolved script set, but only if the character doesn't + // have the script specified in the function call + if (script == USCRIPT_CODE_LIMIT || !temp.test(script, status)) { + result.intersect(temp); + } + } +} + +// Computes the set of numerics for a string, according to UTS 39 section 5.3. +void SpoofImpl::getNumerics(const UnicodeString& input, UnicodeSet& result, UErrorCode& /*status*/) const { + result.clear(); + + UChar32 codePoint; + for (int32_t i = 0; i < input.length(); i += U16_LENGTH(codePoint)) { + codePoint = input.char32At(i); + + // Store a representative character for each kind of decimal digit + if (u_charType(codePoint) == U_DECIMAL_DIGIT_NUMBER) { + // Store the zero character as a representative for comparison. + // Unicode guarantees it is codePoint - value + result.add(codePoint - (UChar32)u_getNumericValue(codePoint)); + } + } +} + +// Computes the restriction level of a string, according to UTS 39 section 5.2. +URestrictionLevel SpoofImpl::getRestrictionLevel(const UnicodeString& input, UErrorCode& status) const { + // Section 5.2 step 1: + if (!fAllowedCharsSet->containsAll(input)) { + return USPOOF_UNRESTRICTIVE; + } + + // Section 5.2 step 2 + // Java use a static UnicodeSet for this test. In C++, avoid the static variable + // and just do a simple for loop. + UBool allASCII = TRUE; + for (int32_t i=0, length=input.length(); i<length; i++) { + if (input.charAt(i) > 0x7f) { + allASCII = FALSE; + break; + } + } + if (allASCII) { + return USPOOF_ASCII; + } + + // Section 5.2 steps 3: + ScriptSet resolvedScriptSet; + getResolvedScriptSet(input, resolvedScriptSet, status); + if (U_FAILURE(status)) { return USPOOF_UNRESTRICTIVE; } + + // Section 5.2 step 4: + if (!resolvedScriptSet.isEmpty()) { + return USPOOF_SINGLE_SCRIPT_RESTRICTIVE; + } + + // Section 5.2 step 5: + ScriptSet resolvedNoLatn; + getResolvedScriptSetWithout(input, USCRIPT_LATIN, resolvedNoLatn, status); + if (U_FAILURE(status)) { return USPOOF_UNRESTRICTIVE; } + + // Section 5.2 step 6: + if (resolvedNoLatn.test(USCRIPT_HAN_WITH_BOPOMOFO, status) + || resolvedNoLatn.test(USCRIPT_JAPANESE, status) + || resolvedNoLatn.test(USCRIPT_KOREAN, status)) { + return USPOOF_HIGHLY_RESTRICTIVE; + } + + // Section 5.2 step 7: + if (!resolvedNoLatn.isEmpty() + && !resolvedNoLatn.test(USCRIPT_CYRILLIC, status) + && !resolvedNoLatn.test(USCRIPT_GREEK, status) + && !resolvedNoLatn.test(USCRIPT_CHEROKEE, status)) { + return USPOOF_MODERATELY_RESTRICTIVE; + } + + // Section 5.2 step 8: + return USPOOF_MINIMALLY_RESTRICTIVE; +} + + // Convert a text format hex number. Utility function used by builder code. Static. // Input: UChar *string text. Output: a UChar32 @@ -404,55 +410,60 @@ UChar32 SpoofImpl::ScanHex(const UChar *s, int32_t start, int32_t limit, UErrorC return (UChar32)val; } -// IdentifierInfo Cache. IdentifierInfo objects are somewhat expensive to create. -// Maintain a one-element cache, which is sufficient to avoid repeatedly -// creating new ones unless we get multi-thread concurrency in spoof -// check operations, which should be statistically uncommon. -// These functions are used in place of new & delete of an IdentifierInfo. -// They will recycle the IdentifierInfo when possible. -// They are logically const, and used within const functions that must be thread safe. -IdentifierInfo *SpoofImpl::getIdentifierInfo(UErrorCode &status) const { - IdentifierInfo *returnIdInfo = NULL; - if (U_FAILURE(status)) { - return returnIdInfo; - } - SpoofImpl *nonConstThis = const_cast<SpoofImpl *>(this); - { - Mutex m; - returnIdInfo = nonConstThis->fCachedIdentifierInfo; - nonConstThis->fCachedIdentifierInfo = NULL; - } - if (returnIdInfo == NULL) { - returnIdInfo = new IdentifierInfo(status); - if (U_SUCCESS(status) && returnIdInfo == NULL) { - status = U_MEMORY_ALLOCATION_ERROR; - } - if (U_FAILURE(status) && returnIdInfo != NULL) { - delete returnIdInfo; - returnIdInfo = NULL; - } - } - return returnIdInfo; +//----------------------------------------- +// +// class CheckResult Implementation +// +//----------------------------------------- + +CheckResult::CheckResult() : fMagic(USPOOF_CHECK_MAGIC) { + clear(); } +USpoofCheckResult* CheckResult::asUSpoofCheckResult() { + return reinterpret_cast<USpoofCheckResult*>(this); +} -void SpoofImpl::releaseIdentifierInfo(IdentifierInfo *idInfo) const { - if (idInfo != NULL) { - SpoofImpl *nonConstThis = const_cast<SpoofImpl *>(this); - { - Mutex m; - if (nonConstThis->fCachedIdentifierInfo == NULL) { - nonConstThis->fCachedIdentifierInfo = idInfo; - idInfo = NULL; - } - } - delete idInfo; +// +// Incoming parameter check on Status and the CheckResult object +// received from the C API. +// +const CheckResult* CheckResult::validateThis(const USpoofCheckResult *ptr, UErrorCode &status) { + if (U_FAILURE(status)) { return NULL; } + if (ptr == NULL) { + status = U_ILLEGAL_ARGUMENT_ERROR; + return NULL; } + CheckResult *This = (CheckResult*) ptr; + if (This->fMagic != USPOOF_CHECK_MAGIC) { + status = U_INVALID_FORMAT_ERROR; + return NULL; + } + return This; +} + +CheckResult* CheckResult::validateThis(USpoofCheckResult *ptr, UErrorCode &status) { + return const_cast<CheckResult *> + (CheckResult::validateThis(const_cast<const USpoofCheckResult*>(ptr), status)); } +void CheckResult::clear() { + fChecks = 0; + fNumerics.clear(); + fRestrictionLevel = USPOOF_UNDEFINED_RESTRICTIVE; +} +int32_t CheckResult::toCombinedBitmask(int32_t enabledChecks) { + if ((enabledChecks & USPOOF_AUX_INFO) != 0 && fRestrictionLevel != USPOOF_UNDEFINED_RESTRICTIVE) { + return fChecks | fRestrictionLevel; + } else { + return fChecks; + } +} +CheckResult::~CheckResult() { +} //---------------------------------------------------------------------------------------------- // @@ -461,12 +472,14 @@ void SpoofImpl::releaseIdentifierInfo(IdentifierInfo *idInfo) const { //---------------------------------------------------------------------------------------------- -UBool SpoofData::validateDataVersion(const SpoofDataHeader *rawData, UErrorCode &status) { +UBool SpoofData::validateDataVersion(UErrorCode &status) const { if (U_FAILURE(status) || - rawData == NULL || - rawData->fMagic != USPOOF_MAGIC || - rawData->fFormatVersion[0] > 1 || - rawData->fFormatVersion[1] > 0) { + fRawData == NULL || + fRawData->fMagic != USPOOF_MAGIC || + fRawData->fFormatVersion[0] != USPOOF_CONFUSABLE_DATA_FORMAT_VERSION || + fRawData->fFormatVersion[1] != 0 || + fRawData->fFormatVersion[2] != 0 || + fRawData->fFormatVersion[3] != 0) { status = U_INVALID_FORMAT_ERROR; return FALSE; } @@ -485,7 +498,7 @@ spoofDataIsAcceptable(void *context, pInfo->dataFormat[1] == 0x66 && pInfo->dataFormat[2] == 0x75 && pInfo->dataFormat[3] == 0x20 && - pInfo->formatVersion[0] == 1 + pInfo->formatVersion[0] == USPOOF_CONFUSABLE_DATA_FORMAT_VERSION ) { UVersionInfo *version = static_cast<UVersionInfo *>(context); if(version != NULL) { @@ -497,32 +510,61 @@ spoofDataIsAcceptable(void *context, } } +// Methods for the loading of the default confusables data file. The confusable +// data is loaded only when it is needed. +// +// SpoofData::getDefault() - Return the default confusables data, and call the +// initOnce() if it is not available. Adds a reference +// to the SpoofData that the caller is responsible for +// decrementing when they are done with the data. // -// SpoofData::getDefault() - return a wrapper around the spoof data that is -// baked into the default ICU data. +// uspoof_loadDefaultData - Called once, from initOnce(). The resulting SpoofData +// is shared by all spoof checkers using the default data. // -// Called once, from the initOnce() function in uspoof_impl.cpp; the resulting -// SpoofData is shared by all spoof checkers using the default data. +// uspoof_cleanupDefaultData - Called during cleanup. // -SpoofData *SpoofData::getDefault(UErrorCode &status) { + +static UInitOnce gSpoofInitDefaultOnce = U_INITONCE_INITIALIZER; +static SpoofData* gDefaultSpoofData; + +static UBool U_CALLCONV +uspoof_cleanupDefaultData(void) { + if (gDefaultSpoofData) { + // Will delete, assuming all user-level spoof checkers were closed. + gDefaultSpoofData->removeReference(); + gDefaultSpoofData = NULL; + gSpoofInitDefaultOnce.reset(); + } + return TRUE; +} + +static void U_CALLCONV uspoof_loadDefaultData(UErrorCode& status) { UDataMemory *udm = udata_openChoice(NULL, "cfu", "confusables", spoofDataIsAcceptable, NULL, // context, would receive dataVersion if supplied. &status); + if (U_FAILURE(status)) { return; } + gDefaultSpoofData = new SpoofData(udm, status); if (U_FAILURE(status)) { - return NULL; - } - SpoofData *This = new SpoofData(udm, status); - if (U_FAILURE(status)) { - delete This; - return NULL; + delete gDefaultSpoofData; + return; } - if (This == NULL) { + if (gDefaultSpoofData == NULL) { status = U_MEMORY_ALLOCATION_ERROR; + return; } - return This; + ucln_i18n_registerCleanup(UCLN_I18N_SPOOFDATA, uspoof_cleanupDefaultData); +} + +SpoofData* SpoofData::getDefault(UErrorCode& status) { + umtx_initOnce(gSpoofInitDefaultOnce, &uspoof_loadDefaultData, status); + if (U_FAILURE(status)) { return NULL; } + gDefaultSpoofData->addReference(); + return gDefaultSpoofData; } + + SpoofData::SpoofData(UDataMemory *udm, UErrorCode &status) { reset(); @@ -533,7 +575,7 @@ SpoofData::SpoofData(UDataMemory *udm, UErrorCode &status) // fRawData is non-const because it may be constructed by the data builder. fRawData = reinterpret_cast<SpoofDataHeader *>( const_cast<void *>(udata_getMemory(udm))); - validateDataVersion(fRawData, status); + validateDataVersion(status); initPtrs(status); } @@ -554,7 +596,7 @@ SpoofData::SpoofData(const void *data, int32_t length, UErrorCode &status) status = U_INVALID_FORMAT_ERROR; return; } - validateDataVersion(fRawData, status); + validateDataVersion(status); initPtrs(status); } @@ -582,7 +624,7 @@ SpoofData::SpoofData(UErrorCode &status) { uprv_memset(fRawData, 0, initialSize); fRawData->fMagic = USPOOF_MAGIC; - fRawData->fFormatVersion[0] = 1; + fRawData->fFormatVersion[0] = USPOOF_CONFUSABLE_DATA_FORMAT_VERSION; fRawData->fFormatVersion[1] = 0; fRawData->fFormatVersion[2] = 0; fRawData->fFormatVersion[3] = 0; @@ -600,11 +642,7 @@ void SpoofData::reset() { fRefCount = 1; fCFUKeys = NULL; fCFUValues = NULL; - fCFUStringLengths = NULL; fCFUStrings = NULL; - fAnyCaseTrie = NULL; - fLowerCaseTrie = NULL; - fScriptSets = NULL; } @@ -626,7 +664,6 @@ void SpoofData::reset() { void SpoofData::initPtrs(UErrorCode &status) { fCFUKeys = NULL; fCFUValues = NULL; - fCFUStringLengths = NULL; fCFUStrings = NULL; if (U_FAILURE(status)) { return; @@ -637,33 +674,13 @@ void SpoofData::initPtrs(UErrorCode &status) { if (fRawData->fCFUStringIndex != 0) { fCFUValues = (uint16_t *)((char *)fRawData + fRawData->fCFUStringIndex); } - if (fRawData->fCFUStringLengths != 0) { - fCFUStringLengths = (SpoofStringLengthsElement *)((char *)fRawData + fRawData->fCFUStringLengths); - } if (fRawData->fCFUStringTable != 0) { fCFUStrings = (UChar *)((char *)fRawData + fRawData->fCFUStringTable); } - - if (fAnyCaseTrie == NULL && fRawData->fAnyCaseTrie != 0) { - fAnyCaseTrie = utrie2_openFromSerialized(UTRIE2_16_VALUE_BITS, - (char *)fRawData + fRawData->fAnyCaseTrie, fRawData->fAnyCaseTrieLength, NULL, &status); - } - if (fLowerCaseTrie == NULL && fRawData->fLowerCaseTrie != 0) { - fLowerCaseTrie = utrie2_openFromSerialized(UTRIE2_16_VALUE_BITS, - (char *)fRawData + fRawData->fLowerCaseTrie, fRawData->fLowerCaseTrieLength, NULL, &status); - } - - if (fRawData->fScriptSets != 0) { - fScriptSets = (ScriptSet *)((char *)fRawData + fRawData->fScriptSets); - } } SpoofData::~SpoofData() { - utrie2_close(fAnyCaseTrie); - fAnyCaseTrie = NULL; - utrie2_close(fLowerCaseTrie); - fLowerCaseTrie = NULL; if (fDataOwned) { uprv_free(fRawData); } @@ -708,6 +725,78 @@ void *SpoofData::reserveSpace(int32_t numBytes, UErrorCode &status) { return (char *)fRawData + returnOffset; } +int32_t SpoofData::serialize(void *buf, int32_t capacity, UErrorCode &status) const { + int32_t dataSize = fRawData->fLength; + if (capacity < dataSize) { + status = U_BUFFER_OVERFLOW_ERROR; + return dataSize; + } + uprv_memcpy(buf, fRawData, dataSize); + return dataSize; +} + +int32_t SpoofData::size() const { + return fRawData->fLength; +} + +//------------------------------- +// +// Front-end APIs for SpoofData +// +//------------------------------- + +int32_t SpoofData::confusableLookup(UChar32 inChar, UnicodeString &dest) const { + // Perform a binary search. + // [lo, hi), i.e lo is inclusive, hi is exclusive. + // The result after the loop will be in lo. + int32_t lo = 0; + int32_t hi = length(); + do { + int32_t mid = (lo + hi) / 2; + if (codePointAt(mid) > inChar) { + hi = mid; + } else if (codePointAt(mid) < inChar) { + lo = mid; + } else { + // Found result. Break early. + lo = mid; + break; + } + } while (hi - lo > 1); + + // Did we find an entry? If not, the char maps to itself. + if (codePointAt(lo) != inChar) { + dest.append(inChar); + return 1; + } + + // Add the element to the string builder and return. + return appendValueTo(lo, dest); +} + +int32_t SpoofData::length() const { + return fRawData->fCFUKeysSize; +} + +UChar32 SpoofData::codePointAt(int32_t index) const { + return ConfusableDataUtils::keyToCodePoint(fCFUKeys[index]); +} + +int32_t SpoofData::appendValueTo(int32_t index, UnicodeString& dest) const { + int32_t stringLength = ConfusableDataUtils::keyToLength(fCFUKeys[index]); + + // Value is either a char (for strings of length 1) or + // an index into the string table (for longer strings) + uint16_t value = fCFUValues[index]; + if (stringLength == 1) { + dest.append((UChar)value); + } else { + dest.append(fCFUStrings + value, stringLength); + } + + return stringLength; +} + U_NAMESPACE_END @@ -739,7 +828,10 @@ uspoof_swap(const UDataSwapper *ds, const void *inData, int32_t length, void *ou pInfo->dataFormat[1]==0x66 && pInfo->dataFormat[2]==0x75 && pInfo->dataFormat[3]==0x20 && - pInfo->formatVersion[0]==1 )) { + pInfo->formatVersion[0]==USPOOF_CONFUSABLE_DATA_FORMAT_VERSION && + pInfo->formatVersion[1]==0 && + pInfo->formatVersion[2]==0 && + pInfo->formatVersion[3]==0 )) { udata_printError(ds, "uspoof_swap(): data format %02x.%02x.%02x.%02x " "(format version %02x %02x %02x %02x) is not recognized\n", pInfo->dataFormat[0], pInfo->dataFormat[1], @@ -828,26 +920,6 @@ uspoof_swap(const UDataSwapper *ds, const void *inData, int32_t length, void *ou sectionLength = ds->readUInt32(spoofDH->fCFUStringTableLen) * 2; ds->swapArray16(ds, inBytes+sectionStart, sectionLength, outBytes+sectionStart, status); - // String Lengths Section - sectionStart = ds->readUInt32(spoofDH->fCFUStringLengths); - sectionLength = ds->readUInt32(spoofDH->fCFUStringLengthsSize) * 4; - ds->swapArray16(ds, inBytes+sectionStart, sectionLength, outBytes+sectionStart, status); - - // Any Case Trie - sectionStart = ds->readUInt32(spoofDH->fAnyCaseTrie); - sectionLength = ds->readUInt32(spoofDH->fAnyCaseTrieLength); - utrie2_swap(ds, inBytes+sectionStart, sectionLength, outBytes+sectionStart, status); - - // Lower Case Trie - sectionStart = ds->readUInt32(spoofDH->fLowerCaseTrie); - sectionLength = ds->readUInt32(spoofDH->fLowerCaseTrieLength); - utrie2_swap(ds, inBytes+sectionStart, sectionLength, outBytes+sectionStart, status); - - // Script Sets. The data is an array of int32_t - sectionStart = ds->readUInt32(spoofDH->fScriptSets); - sectionLength = ds->readUInt32(spoofDH->fScriptSetsLength) * sizeof(ScriptSet); - ds->swapArray32(ds, inBytes+sectionStart, sectionLength, outBytes+sectionStart, status); - // And, last, swap the header itself. // int32_t fMagic // swap this // uint8_t fFormatVersion[4] // Do not swap this, just copy diff --git a/deps/icu-small/source/i18n/uspoof_impl.h b/deps/icu-small/source/i18n/uspoof_impl.h index 44f6b5c943..62480e39e8 100644 --- a/deps/icu-small/source/i18n/uspoof_impl.h +++ b/deps/icu-small/source/i18n/uspoof_impl.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* *************************************************************************** * Copyright (C) 2008-2013, International Business Machines Corporation @@ -13,6 +15,7 @@ #ifndef USPOOFIM_H #define USPOOFIM_H +#include "uassert.h" #include "unicode/utypes.h" #include "unicode/uspoof.h" #include "unicode/uscript.h" @@ -37,11 +40,13 @@ U_NAMESPACE_BEGIN // Magic number for sanity checking spoof data. #define USPOOF_MAGIC 0x3845fdef -class IdentifierInfo; +// Magic number for sanity checking spoof checkers. +#define USPOOF_CHECK_MAGIC 0x2734ecde + class ScriptSet; class SpoofData; struct SpoofDataHeader; -struct SpoofStringLengthsElement; +class ConfusableDataUtils; /** * Class SpoofImpl corresponds directly to the plain C API opaque type @@ -49,25 +54,20 @@ struct SpoofStringLengthsElement; */ class SpoofImpl : public UObject { public: - SpoofImpl(SpoofData *data, UErrorCode &status); - SpoofImpl(); - virtual ~SpoofImpl(); + SpoofImpl(SpoofData *data, UErrorCode& status); + SpoofImpl(UErrorCode& status); + SpoofImpl(); + void construct(UErrorCode& status); + virtual ~SpoofImpl(); /** Copy constructor, used by the user level uspoof_clone() function. */ SpoofImpl(const SpoofImpl &src, UErrorCode &status); + USpoofChecker *asUSpoofChecker(); static SpoofImpl *validateThis(USpoofChecker *sc, UErrorCode &status); static const SpoofImpl *validateThis(const USpoofChecker *sc, UErrorCode &status); - /** Get the confusable skeleton transform for a single code point. - * The result is a string with a length between 1 and 18. - * @param tableMask bit flag specifying which confusable table to use. - * One of USPOOF_SL_TABLE_FLAG, USPOOF_MA_TABLE_FLAG, etc. - * @return The length in UTF-16 code units of the substition string. - */ - int32_t confusableLookup(UChar32 inChar, int32_t tableMask, UnicodeString &destBuf) const; - /** Set and Get AllowedLocales, implementations of the corresponding API */ void setAllowedLocales(const char *localesList, UErrorCode &status); const char * getAllowedLocales(UErrorCode &status); @@ -76,26 +76,19 @@ public: // the specified locale. Part of the implementation of setAllowedLocales. void addScriptChars(const char *locale, UnicodeSet *allowedChars, UErrorCode &status); + // Functions implementing the features of UTS 39 section 5. + static void getAugmentedScriptSet(UChar32 codePoint, ScriptSet& result, UErrorCode& status); + void getResolvedScriptSet(const UnicodeString& input, ScriptSet& result, UErrorCode& status) const; + void getResolvedScriptSetWithout(const UnicodeString& input, UScriptCode script, ScriptSet& result, UErrorCode& status) const; + void getNumerics(const UnicodeString& input, UnicodeSet& result, UErrorCode& status) const; + URestrictionLevel getRestrictionLevel(const UnicodeString& input, UErrorCode& status) const; /** parse a hex number. Untility used by the builders. */ static UChar32 ScanHex(const UChar *s, int32_t start, int32_t limit, UErrorCode &status); - // Implementation for Whole Script tests. - // Return the test bit flag to be ORed into the eventual user return value - // if a Spoof opportunity is detected. - void wholeScriptCheck( - const UnicodeString &text, ScriptSet *result, UErrorCode &status) const; - static UClassID U_EXPORT2 getStaticClassID(void); virtual UClassID getDynamicClassID(void) const; - // IdentifierInfo Cache. IdentifierInfo objects are somewhat expensive to create. - // Maintain a one-element cache, which is sufficient to avoid repeatedly - // creating new ones unless we get multi-thread concurrency in spoof - // check operations, which should be statistically uncommon. - IdentifierInfo *getIdentifierInfo(UErrorCode &status) const; - void releaseIdentifierInfo(IdentifierInfo *idInfo) const; - // // Data Members // @@ -110,14 +103,36 @@ public: const char *fAllowedLocales; // The list of allowed locales. URestrictionLevel fRestrictionLevel; // The maximum restriction level for an acceptable identifier. - - IdentifierInfo *fCachedIdentifierInfo; // Do not use directly. See getIdentifierInfo().:w }; +/** + * Class CheckResult corresponds directly to the plain C API opaque type + * USpoofCheckResult. One can be cast to the other. + */ +class CheckResult : public UObject { +public: + CheckResult(); + virtual ~CheckResult(); + + USpoofCheckResult *asUSpoofCheckResult(); + static CheckResult *validateThis(USpoofCheckResult *ptr, UErrorCode &status); + static const CheckResult *validateThis(const USpoofCheckResult *ptr, UErrorCode &status); + + void clear(); + + // Used to convert this CheckResult to the older int32_t return value API + int32_t toCombinedBitmask(int32_t expectedChecks); + + // Data Members + int32_t fMagic; // Internal sanity check. + int32_t fChecks; // Bit vector of checks that were failed. + UnicodeSet fNumerics; // Set of numerics found in the string. + URestrictionLevel fRestrictionLevel; // The restriction level of the string. +}; // -// Confusable Mappings Data Structures +// Confusable Mappings Data Structures, version 2.0 // // For the confusable data, we are essentially implementing a map, // key: a code point @@ -125,14 +140,7 @@ public: // // The keys are stored as a sorted array of 32 bit ints. // bits 0-23 a code point value -// bits 24-31 flags -// 24: 1 if entry applies to SL table -// 25: 1 if entry applies to SA table -// 26: 1 if entry applies to ML table -// 27: 1 if entry applies to MA table -// 28: 1 if there are multiple entries for this code point. -// 29-30: length of value string, in UChars. -// values are (1, 2, 3, other) +// bits 24-31 length of value string, in UChars (between 1 and 256 UChars). // The key table is sorted in ascending code point order. (not on the // 32 bit int value, the flag bits do not participate in the sorting.) // @@ -146,39 +154,37 @@ public: // The strings table contains all of the value strings (those of length two or greater) // concatentated together into one long UChar (UTF-16) array. // -// The array is arranged by length of the strings - all strings of the same length -// are stored together. The sections are ordered by length of the strings - -// all two char strings first, followed by all of the three Char strings, etc. -// // There is no nul character or other mark between adjacent strings. // -// String Lengths table -// The length of strings from 1 to 3 is flagged in the key table. -// For strings of length 4 or longer, the string length table provides a -// mapping between an index into the string table and the corresponding length. -// Strings of these lengths are rare, so lookup time is not an issue. -// Each entry consists of -// uint16_t index of the _last_ string with this length -// uint16_t the length +//---------------------------------------------------------------------------- // +// Changes from format version 1 to format version 2: +// 1) Removal of the whole-script confusable data tables. +// 2) Removal of the SL/SA/ML/MA and multi-table flags in the key bitmask. +// 3) Expansion of string length value in the key bitmask from 2 bits to 8 bits. +// 4) Removal of the string lengths table since 8 bits is sufficient for the +// lengths of all entries in confusables.txt. -// Flag bits in the Key entries -#define USPOOF_SL_TABLE_FLAG (1<<24) -#define USPOOF_SA_TABLE_FLAG (1<<25) -#define USPOOF_ML_TABLE_FLAG (1<<26) -#define USPOOF_MA_TABLE_FLAG (1<<27) -#define USPOOF_KEY_MULTIPLE_VALUES (1<<28) -#define USPOOF_KEY_LENGTH_SHIFT 29 -#define USPOOF_KEY_LENGTH_FIELD(x) (((x)>>29) & 3) -struct SpoofStringLengthsElement { - uint16_t fLastString; // index in string table of last string with this length - uint16_t fStrLength; // Length of strings +// Internal functions for manipulating confusable data table keys +#define USPOOF_CONFUSABLE_DATA_FORMAT_VERSION 2 // version for ICU 58 +class ConfusableDataUtils { +public: + inline static UChar32 keyToCodePoint(int32_t key) { + return key & 0x00ffffff; + } + inline static int32_t keyToLength(int32_t key) { + return ((key & 0xff000000) >> 24) + 1; + } + inline static int32_t codePointAndLengthToKey(UChar32 codePoint, int32_t length) { + U_ASSERT((codePoint & 0x00ffffff) == codePoint); + U_ASSERT(length <= 256); + return codePoint | ((length - 1) << 24); + } }; - //------------------------------------------------------------------------------------- // // SpoofData @@ -195,7 +201,9 @@ struct SpoofStringLengthsElement { //--------------------------------------------------------------------------------------- class SpoofData: public UMemory { public: - static SpoofData *getDefault(UErrorCode &status); // Load standard ICU spoof data. + static SpoofData* getDefault(UErrorCode &status); // Get standard ICU spoof data. + static void releaseDefault(); // Cleanup reference to default spoof data. + SpoofData(UErrorCode &status); // Create new spoof data wrapper. // Only used when building new data from rules. @@ -210,7 +218,8 @@ class SpoofData: public UMemory { // Check raw Spoof Data Version compatibility. // Return TRUE it looks good. - static UBool validateDataVersion(const SpoofDataHeader *rawData, UErrorCode &status); + UBool validateDataVersion(UErrorCode &status) const; + ~SpoofData(); // Destructor not normally used. // Use removeReference() instead. // Reference Counting functions. @@ -220,6 +229,35 @@ class SpoofData: public UMemory { SpoofData *addReference(); void removeReference(); + // Reset all fields to an initial state. + // Called from the top of all constructors. + void reset(); + + // Copy this instance's raw data buffer to the specified address. + int32_t serialize(void *buf, int32_t capacity, UErrorCode &status) const; + + // Get the total number of bytes of data backed by this SpoofData. + // Not to be confused with length, which returns the number of confusable entries. + int32_t size() const; + + // Get the confusable skeleton transform for a single code point. + // The result is a string with a length between 1 and 18 as of Unicode 9. + // This is the main public endpoint for this class. + // @return The length in UTF-16 code units of the substition string. + int32_t confusableLookup(UChar32 inChar, UnicodeString &dest) const; + + // Get the number of confusable entries in this SpoofData. + int32_t length() const; + + // Get the code point (key) at the specified index. + UChar32 codePointAt(int32_t index) const; + + // Get the confusable skeleton (value) at the specified index. + // Append it to the specified UnicodeString&. + // @return The length in UTF-16 code units of the skeleton string. + int32_t appendValueTo(int32_t index, UnicodeString& dest) const; + + private: // Reserve space in the raw data. For use by builder when putting together a // new set of data. Init the new storage to zero, to prevent inconsistent // results if it is not all otherwise set by the requester. @@ -230,10 +268,6 @@ class SpoofData: public UMemory { // initialize the pointers from this object to the raw data. void initPtrs(UErrorCode &status); - // Reset all fields to an initial state. - // Called from the top of all constructors. - void reset(); - SpoofDataHeader *fRawData; // Ptr to the raw memory-mapped data UBool fDataOwned; // True if the raw data is owned, and needs // to be deleted when refcount goes to zero. @@ -247,15 +281,10 @@ class SpoofData: public UMemory { // Confusable data int32_t *fCFUKeys; uint16_t *fCFUValues; - SpoofStringLengthsElement *fCFUStringLengths; UChar *fCFUStrings; - // Whole Script Confusable Data - UTrie2 *fAnyCaseTrie; - UTrie2 *fLowerCaseTrie; - ScriptSet *fScriptSets; - }; - + friend class ConfusabledataBuilder; +}; //--------------------------------------------------------------------------------------- // @@ -284,47 +313,11 @@ struct SpoofDataHeader { int32_t fCFUStringTable; // byte offset of String table int32_t fCFUStringTableLen; // length of string table (in 16 bit UChars) - int32_t fCFUStringLengths; // byte offset to String Lengths table - int32_t fCFUStringLengthsSize; // number of entries in lengths table. (2 x 16 bits each) - - - // The following sections are for data from confusablesWholeScript.txt - - int32_t fAnyCaseTrie; // byte offset to the serialized Any Case Trie - int32_t fAnyCaseTrieLength; // Length (bytes) of the serialized Any Case Trie - - int32_t fLowerCaseTrie; // byte offset to the serialized Lower Case Trie - int32_t fLowerCaseTrieLength; // Length (bytes) of the serialized Lower Case Trie - - int32_t fScriptSets; // byte offset to array of ScriptSets - int32_t fScriptSetsLength; // Number of ScriptSets (24 bytes each) - - // The following sections are for data from xidmodifications.txt - int32_t unused[15]; // Padding, Room for Expansion +}; - }; - - - - -// -// Structure for the Whole Script Confusable Data -// See Unicode UAX-39, Unicode Security Mechanisms, for a description of the -// Whole Script confusable data -// -// The data provides mappings from code points to a set of scripts -// that contain characters that might be confused with the code point. -// There are two mappings, one for lower case only, and one for characters -// of any case. -// -// The actual data consists of a utrie2 to map from a code point to an offset, -// and an array of UScriptSets (essentially bit maps) that is indexed -// by the offsets obtained from the Trie. -// -// U_NAMESPACE_END diff --git a/deps/icu-small/source/i18n/uspoof_wsconf.cpp b/deps/icu-small/source/i18n/uspoof_wsconf.cpp deleted file mode 100644 index ad73ed690c..0000000000 --- a/deps/icu-small/source/i18n/uspoof_wsconf.cpp +++ /dev/null @@ -1,435 +0,0 @@ -/* -****************************************************************************** -* -* Copyright (C) 2008-2013, International Business Machines -* Corporation and others. All Rights Reserved. -* -****************************************************************************** -* file name: uspoof_wsconf.cpp -* encoding: US-ASCII -* tab size: 8 (not used) -* indentation:4 -* -* created on: 2009Jan05 (refactoring earlier files) -* created by: Andy Heninger -* -* Internal functions for compililing Whole Script confusable source data -* into its binary (runtime) form. The binary data format is described -* in uspoof_impl.h -*/ - -#include "unicode/utypes.h" -#include "unicode/uspoof.h" - -#if !UCONFIG_NO_NORMALIZATION - -#if !UCONFIG_NO_REGULAR_EXPRESSIONS - -#include "unicode/unorm.h" -#include "unicode/uregex.h" -#include "unicode/ustring.h" -#include "cmemory.h" -#include "scriptset.h" -#include "uspoof_impl.h" -#include "uhash.h" -#include "uvector.h" -#include "uassert.h" -#include "uspoof_wsconf.h" - -U_NAMESPACE_USE - - -// Regular expression for parsing a line from the Unicode file confusablesWholeScript.txt -// Example Lines: -// 006F ; Latn; Deva; A # (o) LATIN SMALL LETTER O -// 0048..0049 ; Latn; Grek; A # [2] (H..I) LATIN CAPITAL LETTER H..LATIN CAPITAL LETTER I -// | | | | -// | | | |---- Which table, Any Case or Lower Case (A or L) -// | | |----------Target script. We need this. -// | |----------------Src script. Should match the script of the source -// | code points. Beyond checking that, we don't keep it. -// |--------------------------------Source code points or range. -// -// The expression will match _all_ lines, including erroneous lines. -// The result of the parse is returned via the contents of the (match) groups. -static const char *parseExp = - "(?m)" // Multi-line mode - "^([ \\t]*(?:#.*?)?)$" // A blank or comment line. Matches Group 1. - "|^(?:" // OR - "\\s*([0-9A-F]{4,})(?:..([0-9A-F]{4,}))?\\s*;" // Code point range. Groups 2 and 3. - "\\s*([A-Za-z]+)\\s*;" // The source script. Group 4. - "\\s*([A-Za-z]+)\\s*;" // The target script. Group 5. - "\\s*(?:(A)|(L))" // The table A or L. Group 6 or 7 - "[ \\t]*(?:#.*?)?" // Trailing commment - ")$|" // OR - "^(.*?)$"; // An error line. Group 8. - // Any line not matching the preceding - // parts of the expression.will match - // this, and thus be flagged as an error - - -// Extract a regular expression match group into a char * string. -// The group must contain only invariant characters. -// Used for script names -// -static void extractGroup( - URegularExpression *e, int32_t group, char *destBuf, int32_t destCapacity, UErrorCode &status) { - - UChar ubuf[50]; - ubuf[0] = 0; - destBuf[0] = 0; - int32_t len = uregex_group(e, group, ubuf, 50, &status); - if (U_FAILURE(status) || len == -1 || len >= destCapacity) { - return; - } - UnicodeString s(FALSE, ubuf, len); // Aliasing constructor - s.extract(0, len, destBuf, destCapacity, US_INV); -} - - - -U_NAMESPACE_BEGIN - -// Build the Whole Script Confusable data -// -// TODO: Reorganize. Either get rid of the WSConfusableDataBuilder class, -// because everything is local to this one build function anyhow, -// OR -// break this function into more reasonably sized pieces, with -// state in WSConfusableDataBuilder. -// -void buildWSConfusableData(SpoofImpl *spImpl, const char * confusablesWS, - int32_t confusablesWSLen, UParseError *pe, UErrorCode &status) -{ - if (U_FAILURE(status)) { - return; - } - URegularExpression *parseRegexp = NULL; - int32_t inputLen = 0; - UChar *input = NULL; - int32_t lineNum = 0; - - UVector *scriptSets = NULL; - uint32_t rtScriptSetsCount = 2; - - UTrie2 *anyCaseTrie = NULL; - UTrie2 *lowerCaseTrie = NULL; - - anyCaseTrie = utrie2_open(0, 0, &status); - lowerCaseTrie = utrie2_open(0, 0, &status); - - UnicodeString pattern(parseExp, -1, US_INV); - - // The scriptSets vector provides a mapping from TRIE values to the set of scripts. - // - // Reserved TRIE values: - // 0: Code point has no whole script confusables. - // 1: Code point is of script Common or Inherited. - // These code points do not participate in whole script confusable detection. - // (This is logically equivalent to saying that they contain confusables in - // all scripts) - // - // Because Trie values are indexes into the ScriptSets vector, pre-fill - // vector positions 0 and 1 to avoid conflicts with the reserved values. - - scriptSets = new UVector(status); - if (scriptSets == NULL) { - status = U_MEMORY_ALLOCATION_ERROR; - goto cleanup; - } - scriptSets->addElement((void *)NULL, status); - scriptSets->addElement((void *)NULL, status); - - // Convert the user input data from UTF-8 to UChar (UTF-16) - u_strFromUTF8(NULL, 0, &inputLen, confusablesWS, confusablesWSLen, &status); - if (status != U_BUFFER_OVERFLOW_ERROR) { - goto cleanup; - } - status = U_ZERO_ERROR; - input = static_cast<UChar *>(uprv_malloc((inputLen+1) * sizeof(UChar))); - if (input == NULL) { - status = U_MEMORY_ALLOCATION_ERROR; - goto cleanup; - } - u_strFromUTF8(input, inputLen+1, NULL, confusablesWS, confusablesWSLen, &status); - - parseRegexp = uregex_open(pattern.getBuffer(), pattern.length(), 0, NULL, &status); - - // Zap any Byte Order Mark at the start of input. Changing it to a space is benign - // given the syntax of the input. - if (*input == 0xfeff) { - *input = 0x20; - } - - // Parse the input, one line per iteration of this loop. - uregex_setText(parseRegexp, input, inputLen, &status); - while (uregex_findNext(parseRegexp, &status)) { - lineNum++; - if (uregex_start(parseRegexp, 1, &status) >= 0) { - // this was a blank or comment line. - continue; - } - if (uregex_start(parseRegexp, 8, &status) >= 0) { - // input file syntax error. - status = U_PARSE_ERROR; - goto cleanup; - } - if (U_FAILURE(status)) { - goto cleanup; - } - - // Pick up the start and optional range end code points from the parsed line. - UChar32 startCodePoint = SpoofImpl::ScanHex( - input, uregex_start(parseRegexp, 2, &status), uregex_end(parseRegexp, 2, &status), status); - UChar32 endCodePoint = startCodePoint; - if (uregex_start(parseRegexp, 3, &status) >=0) { - endCodePoint = SpoofImpl::ScanHex( - input, uregex_start(parseRegexp, 3, &status), uregex_end(parseRegexp, 3, &status), status); - } - - // Extract the two script names from the source line. We need these in an 8 bit - // default encoding (will be EBCDIC on IBM mainframes) in order to pass them on - // to the ICU u_getPropertyValueEnum() function. Ugh. - char srcScriptName[20]; - char targScriptName[20]; - extractGroup(parseRegexp, 4, srcScriptName, sizeof(srcScriptName), status); - extractGroup(parseRegexp, 5, targScriptName, sizeof(targScriptName), status); - UScriptCode srcScript = - static_cast<UScriptCode>(u_getPropertyValueEnum(UCHAR_SCRIPT, srcScriptName)); - UScriptCode targScript = - static_cast<UScriptCode>(u_getPropertyValueEnum(UCHAR_SCRIPT, targScriptName)); - if (U_FAILURE(status)) { - goto cleanup; - } - if (srcScript == USCRIPT_INVALID_CODE || targScript == USCRIPT_INVALID_CODE) { - status = U_INVALID_FORMAT_ERROR; - goto cleanup; - } - - // select the table - (A) any case or (L) lower case only - UTrie2 *table = anyCaseTrie; - if (uregex_start(parseRegexp, 7, &status) >= 0) { - table = lowerCaseTrie; - } - - // Build the set of scripts containing confusable characters for - // the code point(s) specified in this input line. - // Sanity check that the script of the source code point is the same - // as the source script indicated in the input file. Failure of this check is - // an error in the input file. - // Include the source script in the set (needed for Mixed Script Confusable detection). - // - UChar32 cp; - for (cp=startCodePoint; cp<=endCodePoint; cp++) { - int32_t setIndex = utrie2_get32(table, cp); - BuilderScriptSet *bsset = NULL; - if (setIndex > 0) { - U_ASSERT(setIndex < scriptSets->size()); - bsset = static_cast<BuilderScriptSet *>(scriptSets->elementAt(setIndex)); - } else { - bsset = new BuilderScriptSet(); - if (bsset == NULL) { - status = U_MEMORY_ALLOCATION_ERROR; - goto cleanup; - } - bsset->codePoint = cp; - bsset->trie = table; - bsset->sset = new ScriptSet(); - setIndex = scriptSets->size(); - bsset->index = setIndex; - bsset->rindex = 0; - if (bsset->sset == NULL) { - status = U_MEMORY_ALLOCATION_ERROR; - goto cleanup; - } - scriptSets->addElement(bsset, status); - utrie2_set32(table, cp, setIndex, &status); - } - bsset->sset->set(targScript, status); - bsset->sset->set(srcScript, status); - - if (U_FAILURE(status)) { - goto cleanup; - } - UScriptCode cpScript = uscript_getScript(cp, &status); - if (cpScript != srcScript) { - status = U_INVALID_FORMAT_ERROR; - goto cleanup; - } - } - } - - // Eliminate duplicate script sets. At this point we have a separate - // script set for every code point that had data in the input file. - // - // We eliminate underlying ScriptSet objects, not the BuildScriptSets that wrap them - // - // printf("Number of scriptSets: %d\n", scriptSets->size()); - { - int32_t duplicateCount = 0; - rtScriptSetsCount = 2; - for (int32_t outeri=2; outeri<scriptSets->size(); outeri++) { - BuilderScriptSet *outerSet = static_cast<BuilderScriptSet *>(scriptSets->elementAt(outeri)); - if (outerSet->index != static_cast<uint32_t>(outeri)) { - // This set was already identified as a duplicate. - // It will not be allocated a position in the runtime array of ScriptSets. - continue; - } - outerSet->rindex = rtScriptSetsCount++; - for (int32_t inneri=outeri+1; inneri<scriptSets->size(); inneri++) { - BuilderScriptSet *innerSet = static_cast<BuilderScriptSet *>(scriptSets->elementAt(inneri)); - if (*(outerSet->sset) == *(innerSet->sset) && outerSet->sset != innerSet->sset) { - delete innerSet->sset; - innerSet->scriptSetOwned = FALSE; - innerSet->sset = outerSet->sset; - innerSet->index = outeri; - innerSet->rindex = outerSet->rindex; - duplicateCount++; - } - // But this doesn't get all. We need to fix the TRIE. - } - } - // printf("Number of distinct script sets: %d\n", rtScriptSetsCount); - } - - - - // Update the Trie values to be reflect the run time script indexes (after duplicate merging). - // (Trie Values 0 and 1 are reserved, and the corresponding slots in scriptSets - // are unused, which is why the loop index starts at 2.) - { - for (int32_t i=2; i<scriptSets->size(); i++) { - BuilderScriptSet *bSet = static_cast<BuilderScriptSet *>(scriptSets->elementAt(i)); - if (bSet->rindex != (uint32_t)i) { - utrie2_set32(bSet->trie, bSet->codePoint, bSet->rindex, &status); - } - } - } - - // For code points with script==Common or script==Inherited, - // Set the reserved value of 1 into both Tries. These characters do not participate - // in Whole Script Confusable detection; this reserved value is the means - // by which they are detected. - { - UnicodeSet ignoreSet; - ignoreSet.applyIntPropertyValue(UCHAR_SCRIPT, USCRIPT_COMMON, status); - UnicodeSet inheritedSet; - inheritedSet.applyIntPropertyValue(UCHAR_SCRIPT, USCRIPT_INHERITED, status); - ignoreSet.addAll(inheritedSet); - for (int32_t rn=0; rn<ignoreSet.getRangeCount(); rn++) { - UChar32 rangeStart = ignoreSet.getRangeStart(rn); - UChar32 rangeEnd = ignoreSet.getRangeEnd(rn); - utrie2_setRange32(anyCaseTrie, rangeStart, rangeEnd, 1, TRUE, &status); - utrie2_setRange32(lowerCaseTrie, rangeStart, rangeEnd, 1, TRUE, &status); - } - } - - // Serialize the data to the Spoof Detector - { - utrie2_freeze(anyCaseTrie, UTRIE2_16_VALUE_BITS, &status); - int32_t size = utrie2_serialize(anyCaseTrie, NULL, 0, &status); - // printf("Any case Trie size: %d\n", size); - if (status != U_BUFFER_OVERFLOW_ERROR) { - goto cleanup; - } - status = U_ZERO_ERROR; - spImpl->fSpoofData->fRawData->fAnyCaseTrie = spImpl->fSpoofData->fMemLimit; - spImpl->fSpoofData->fRawData->fAnyCaseTrieLength = size; - spImpl->fSpoofData->fAnyCaseTrie = anyCaseTrie; - void *where = spImpl->fSpoofData->reserveSpace(size, status); - utrie2_serialize(anyCaseTrie, where, size, &status); - - utrie2_freeze(lowerCaseTrie, UTRIE2_16_VALUE_BITS, &status); - size = utrie2_serialize(lowerCaseTrie, NULL, 0, &status); - // printf("Lower case Trie size: %d\n", size); - if (status != U_BUFFER_OVERFLOW_ERROR) { - goto cleanup; - } - status = U_ZERO_ERROR; - spImpl->fSpoofData->fRawData->fLowerCaseTrie = spImpl->fSpoofData->fMemLimit; - spImpl->fSpoofData->fRawData->fLowerCaseTrieLength = size; - spImpl->fSpoofData->fLowerCaseTrie = lowerCaseTrie; - where = spImpl->fSpoofData->reserveSpace(size, status); - utrie2_serialize(lowerCaseTrie, where, size, &status); - - spImpl->fSpoofData->fRawData->fScriptSets = spImpl->fSpoofData->fMemLimit; - spImpl->fSpoofData->fRawData->fScriptSetsLength = rtScriptSetsCount; - ScriptSet *rtScriptSets = static_cast<ScriptSet *> - (spImpl->fSpoofData->reserveSpace(rtScriptSetsCount * sizeof(ScriptSet), status)); - uint32_t rindex = 2; - for (int32_t i=2; i<scriptSets->size(); i++) { - BuilderScriptSet *bSet = static_cast<BuilderScriptSet *>(scriptSets->elementAt(i)); - if (bSet->rindex < rindex) { - // We have already copied this script set to the serialized data. - continue; - } - U_ASSERT(rindex == bSet->rindex); - rtScriptSets[rindex] = *bSet->sset; // Assignment of a ScriptSet just copies the bits. - rindex++; - } - } - - // Open new utrie2s from the serialized data. We don't want to keep the ones - // we just built because we would then have two copies of the data, one internal to - // the utries that we have already constructed, and one in the serialized data area. - // An alternative would be to not pre-serialize the Trie data, but that makes the - // spoof detector data different, depending on how the detector was constructed. - // It's simpler to keep the data always the same. - - spImpl->fSpoofData->fAnyCaseTrie = utrie2_openFromSerialized( - UTRIE2_16_VALUE_BITS, - (const char *)spImpl->fSpoofData->fRawData + spImpl->fSpoofData->fRawData->fAnyCaseTrie, - spImpl->fSpoofData->fRawData->fAnyCaseTrieLength, - NULL, - &status); - - spImpl->fSpoofData->fLowerCaseTrie = utrie2_openFromSerialized( - UTRIE2_16_VALUE_BITS, - (const char *)spImpl->fSpoofData->fRawData + spImpl->fSpoofData->fRawData->fLowerCaseTrie, - spImpl->fSpoofData->fRawData->fAnyCaseTrieLength, - NULL, - &status); - - - -cleanup: - if (U_FAILURE(status)) { - pe->line = lineNum; - } - uregex_close(parseRegexp); - uprv_free(input); - - int32_t i; - if (scriptSets != NULL) { - for (i=0; i<scriptSets->size(); i++) { - BuilderScriptSet *bsset = static_cast<BuilderScriptSet *>(scriptSets->elementAt(i)); - delete bsset; - } - delete scriptSets; - } - utrie2_close(anyCaseTrie); - utrie2_close(lowerCaseTrie); - return; -} - -U_NAMESPACE_END - - - -BuilderScriptSet::BuilderScriptSet() { - codePoint = -1; - trie = NULL; - sset = NULL; - index = 0; - rindex = 0; - scriptSetOwned = TRUE; -} - -BuilderScriptSet::~BuilderScriptSet() { - if (scriptSetOwned) { - delete sset; - } -} - -#endif -#endif // !UCONFIG_NO_REGULAR_EXPRESSIONS diff --git a/deps/icu-small/source/i18n/uspoof_wsconf.h b/deps/icu-small/source/i18n/uspoof_wsconf.h deleted file mode 100644 index 5c0e6111a7..0000000000 --- a/deps/icu-small/source/i18n/uspoof_wsconf.h +++ /dev/null @@ -1,70 +0,0 @@ -/* -****************************************************************************** -* -* Copyright (C) 2008-2012, International Business Machines -* Corporation and others. All Rights Reserved. -* -****************************************************************************** -* file name: uspoof_buildwsconf.h -* encoding: US-ASCII -* tab size: 8 (not used) -* indentation:4 -* -* created on: 2009Jan19 -* created by: Andy Heninger -* -* Internal classes and functions -* for compiling whole script confusable data into its binary (runtime) form. -*/ - -#ifndef __USPOOF_BUILDWSCONF_H__ -#define __USPOOF_BUILDWSCONF_H__ - -#include "unicode/utypes.h" - -#if !UCONFIG_NO_NORMALIZATION - -#if !UCONFIG_NO_REGULAR_EXPRESSIONS - -#include "uspoof_impl.h" -#include "utrie2.h" - - -U_NAMESPACE_BEGIN - -// -// class BuilderScriptSet. Represents the set of scripts (Script Codes) -// containing characters that are confusable with one specific -// code point. -// - -class BuilderScriptSet: public UMemory { - public: - UChar32 codePoint; // The source code point. - UTrie2 *trie; // Any-case or Lower-case Trie. - // These Trie tables are the final result of the - // build. This flag indicates which of the two - // this set of data is for. - ScriptSet *sset; // The set of scripts itself. - - // Vectors of all B - uint32_t index; // Index of this set in the Build Time vector - // of script sets. - uint32_t rindex; // Index of this set in the final (runtime) - // array of sets. - UBool scriptSetOwned; // True if this BuilderScriptSet owns (should delete) - // its underlying sset. - - BuilderScriptSet(); - ~BuilderScriptSet(); -}; - - -void buildWSConfusableData(SpoofImpl *spImpl, const char * confusablesWS, - int32_t confusablesWSLen, UParseError *pe, UErrorCode &status); - -U_NAMESPACE_END - -#endif // !UCONFIG_NO_REGULAR_EXPRESSIONS -#endif // !UCONFIG_NO_NORMALIZATION -#endif diff --git a/deps/icu-small/source/i18n/usrchimp.h b/deps/icu-small/source/i18n/usrchimp.h index 898e38a20f..e6693d16b7 100644 --- a/deps/icu-small/source/i18n/usrchimp.h +++ b/deps/icu-small/source/i18n/usrchimp.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (C) 2001-2015 IBM and others. All rights reserved. diff --git a/deps/icu-small/source/i18n/utf16collationiterator.cpp b/deps/icu-small/source/i18n/utf16collationiterator.cpp index 559ea91ea8..733729fae7 100644 --- a/deps/icu-small/source/i18n/utf16collationiterator.cpp +++ b/deps/icu-small/source/i18n/utf16collationiterator.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2010-2014, International Business Machines diff --git a/deps/icu-small/source/i18n/utf16collationiterator.h b/deps/icu-small/source/i18n/utf16collationiterator.h index 16de2078ed..505ab810d3 100644 --- a/deps/icu-small/source/i18n/utf16collationiterator.h +++ b/deps/icu-small/source/i18n/utf16collationiterator.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2010-2014, International Business Machines diff --git a/deps/icu-small/source/i18n/utf8collationiterator.cpp b/deps/icu-small/source/i18n/utf8collationiterator.cpp index ddb753f6ae..0a0205e7b3 100644 --- a/deps/icu-small/source/i18n/utf8collationiterator.cpp +++ b/deps/icu-small/source/i18n/utf8collationiterator.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2012-2014, International Business Machines diff --git a/deps/icu-small/source/i18n/utf8collationiterator.h b/deps/icu-small/source/i18n/utf8collationiterator.h index bb0fc1179d..8deb5ea395 100644 --- a/deps/icu-small/source/i18n/utf8collationiterator.h +++ b/deps/icu-small/source/i18n/utf8collationiterator.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2012-2016, International Business Machines diff --git a/deps/icu-small/source/i18n/utmscale.c b/deps/icu-small/source/i18n/utmscale.c index 94fb7525fd..6868b9db22 100644 --- a/deps/icu-small/source/i18n/utmscale.c +++ b/deps/icu-small/source/i18n/utmscale.c @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2004-2012, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/utrans.cpp b/deps/icu-small/source/i18n/utrans.cpp index 91d9f1c8e6..aed817ce26 100644 --- a/deps/icu-small/source/i18n/utrans.cpp +++ b/deps/icu-small/source/i18n/utrans.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 1997-2009,2014 International Business Machines diff --git a/deps/icu-small/source/i18n/valueformatter.cpp b/deps/icu-small/source/i18n/valueformatter.cpp index d7870d1041..45b08f60b6 100644 --- a/deps/icu-small/source/i18n/valueformatter.cpp +++ b/deps/icu-small/source/i18n/valueformatter.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2015, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/valueformatter.h b/deps/icu-small/source/i18n/valueformatter.h index 42ccd21207..da2dd1b337 100644 --- a/deps/icu-small/source/i18n/valueformatter.h +++ b/deps/icu-small/source/i18n/valueformatter.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2015, International Business Machines Corporation and * diff --git a/deps/icu-small/source/i18n/visibledigits.cpp b/deps/icu-small/source/i18n/visibledigits.cpp index a6cbd0fdce..1fea3504df 100644 --- a/deps/icu-small/source/i18n/visibledigits.cpp +++ b/deps/icu-small/source/i18n/visibledigits.cpp @@ -1,5 +1,7 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* - * Copyright (C) 2015, International Business Machines + * Copyright (C) 2016, International Business Machines * Corporation and others. All Rights Reserved. * * file name: visibledigits.cpp @@ -84,8 +86,11 @@ double VisibleDigits::computeAbsDoubleValue() const { } // stack allocate a decNumber to hold MAX_DBL_DIGITS+3 significant digits - char rawNumber[sizeof(decNumber) + MAX_DBL_DIGITS+3]; - decNumber *numberPtr = (decNumber *) rawNumber; + struct { + decNumber decNum; + char digits[MAX_DBL_DIGITS+3]; + } decNumberWithStorage; + decNumber *numberPtr = &decNumberWithStorage.decNum; int32_t mostSig = fInterval.getMostSignificantExclusive(); int32_t mostSigNonZero = fExponent + fDigits.length(); @@ -109,15 +114,8 @@ double VisibleDigits::computeAbsDoubleValue() const { char str[MAX_DBL_DIGITS+18]; uprv_decNumberToString(numberPtr, str); U_ASSERT(uprv_strlen(str) < MAX_DBL_DIGITS+18); - char decimalSeparator = DigitList::getStrtodDecimalSeparator(); - if (decimalSeparator != '.') { - char *decimalPt = strchr(str, '.'); - if (decimalPt != NULL) { - *decimalPt = decimalSeparator; - } - } char *unused = NULL; - return uprv_strtod(str, &unused); + return DigitList::decimalStrToDouble(str, &unused); } void VisibleDigits::getFixedDecimal( @@ -165,7 +163,8 @@ void VisibleDigits::getFixedDecimal( // f (decimal digits) // skip over any leading 0's in fraction digits. int32_t idx = -1; - for (; idx >= -v && getDigitByExponent(idx) == 0; --idx); + for (; idx >= -v && getDigitByExponent(idx) == 0; --idx) + ; // Only process up to first 18 non zero fraction digits for decimalDigits // since that is all we can fit into an int64. diff --git a/deps/icu-small/source/i18n/visibledigits.h b/deps/icu-small/source/i18n/visibledigits.h index 9390aadc6b..cd18239a56 100644 --- a/deps/icu-small/source/i18n/visibledigits.h +++ b/deps/icu-small/source/i18n/visibledigits.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2015, International Business Machines * Corporation and others. All Rights Reserved. diff --git a/deps/icu-small/source/i18n/vtzone.cpp b/deps/icu-small/source/i18n/vtzone.cpp index 0585ea75ae..ba5f3bc0d7 100644 --- a/deps/icu-small/source/i18n/vtzone.cpp +++ b/deps/icu-small/source/i18n/vtzone.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2007-2016, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/vzone.cpp b/deps/icu-small/source/i18n/vzone.cpp index cd75802a17..7ee95e4ede 100644 --- a/deps/icu-small/source/i18n/vzone.cpp +++ b/deps/icu-small/source/i18n/vzone.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2009-2011, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/vzone.h b/deps/icu-small/source/i18n/vzone.h index f89a5619a6..22a41b4e37 100644 --- a/deps/icu-small/source/i18n/vzone.h +++ b/deps/icu-small/source/i18n/vzone.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2009-2016, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/windtfmt.cpp b/deps/icu-small/source/i18n/windtfmt.cpp index 8625ea7e3e..20ce338bb4 100644 --- a/deps/icu-small/source/i18n/windtfmt.cpp +++ b/deps/icu-small/source/i18n/windtfmt.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** * Copyright (C) 2005-2016, International Business Machines @@ -230,8 +232,8 @@ static const DWORD dfFlags[] = {DATE_LONGDATE, DATE_LONGDATE, DATE_SHORTDATE, DA void Win32DateFormat::formatDate(const SYSTEMTIME *st, UnicodeString &appendTo) const { int result; - UChar stackBuffer[STACK_BUFFER_SIZE]; - UChar *buffer = stackBuffer; + wchar_t stackBuffer[STACK_BUFFER_SIZE]; + wchar_t *buffer = stackBuffer; result = GetDateFormatW(fLCID, dfFlags[fDateStyle - kDateOffset], st, NULL, buffer, STACK_BUFFER_SIZE); @@ -239,12 +241,12 @@ void Win32DateFormat::formatDate(const SYSTEMTIME *st, UnicodeString &appendTo) if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { int newLength = GetDateFormatW(fLCID, dfFlags[fDateStyle - kDateOffset], st, NULL, NULL, 0); - buffer = NEW_ARRAY(UChar, newLength); + buffer = NEW_ARRAY(wchar_t, newLength); GetDateFormatW(fLCID, dfFlags[fDateStyle - kDateOffset], st, NULL, buffer, newLength); } } - appendTo.append(buffer, (int32_t) wcslen(buffer)); + appendTo.append((const UChar *)buffer, (int32_t) wcslen(buffer)); if (buffer != stackBuffer) { DELETE_ARRAY(buffer); @@ -256,8 +258,8 @@ static const DWORD tfFlags[] = {0, 0, 0, TIME_NOSECONDS}; void Win32DateFormat::formatTime(const SYSTEMTIME *st, UnicodeString &appendTo) const { int result; - UChar stackBuffer[STACK_BUFFER_SIZE]; - UChar *buffer = stackBuffer; + wchar_t stackBuffer[STACK_BUFFER_SIZE]; + wchar_t *buffer = stackBuffer; result = GetTimeFormatW(fLCID, tfFlags[fTimeStyle], st, NULL, buffer, STACK_BUFFER_SIZE); @@ -265,12 +267,12 @@ void Win32DateFormat::formatTime(const SYSTEMTIME *st, UnicodeString &appendTo) if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { int newLength = GetTimeFormatW(fLCID, tfFlags[fTimeStyle], st, NULL, NULL, 0); - buffer = NEW_ARRAY(UChar, newLength); + buffer = NEW_ARRAY(wchar_t, newLength); GetDateFormatW(fLCID, tfFlags[fTimeStyle], st, NULL, buffer, newLength); } } - appendTo.append(buffer, (int32_t) wcslen(buffer)); + appendTo.append((const UChar *)buffer, (int32_t) wcslen(buffer)); if (buffer != stackBuffer) { DELETE_ARRAY(buffer); diff --git a/deps/icu-small/source/i18n/windtfmt.h b/deps/icu-small/source/i18n/windtfmt.h index a286ced2e3..a822194370 100644 --- a/deps/icu-small/source/i18n/windtfmt.h +++ b/deps/icu-small/source/i18n/windtfmt.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** * Copyright (C) 2005-2015, International Business Machines diff --git a/deps/icu-small/source/i18n/winnmfmt.cpp b/deps/icu-small/source/i18n/winnmfmt.cpp index 23610732a2..d7e98723bb 100644 --- a/deps/icu-small/source/i18n/winnmfmt.cpp +++ b/deps/icu-small/source/i18n/winnmfmt.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** * Copyright (C) 2005-2016, International Business Machines @@ -86,10 +88,10 @@ static void getNumberFormat(NUMBERFMTW *fmt, int32_t lcid) GetLocaleInfoA(lcid, LOCALE_SGROUPING, buf, 10); fmt->Grouping = getGrouping(buf); - fmt->lpDecimalSep = NEW_ARRAY(UChar, 6); + fmt->lpDecimalSep = NEW_ARRAY(wchar_t, 6); GetLocaleInfoW(lcid, LOCALE_SDECIMAL, fmt->lpDecimalSep, 6); - fmt->lpThousandSep = NEW_ARRAY(UChar, 6); + fmt->lpThousandSep = NEW_ARRAY(wchar_t, 6); GetLocaleInfoW(lcid, LOCALE_STHOUSAND, fmt->lpThousandSep, 6); GetLocaleInfoW(lcid, LOCALE_RETURN_NUMBER|LOCALE_INEGNUMBER, (LPWSTR) &fmt->NegativeOrder, sizeof(UINT)); @@ -113,16 +115,16 @@ static void getCurrencyFormat(CURRENCYFMTW *fmt, int32_t lcid) GetLocaleInfoA(lcid, LOCALE_SMONGROUPING, buf, sizeof(buf)); fmt->Grouping = getGrouping(buf); - fmt->lpDecimalSep = NEW_ARRAY(UChar, 6); + fmt->lpDecimalSep = NEW_ARRAY(wchar_t, 6); GetLocaleInfoW(lcid, LOCALE_SMONDECIMALSEP, fmt->lpDecimalSep, 6); - fmt->lpThousandSep = NEW_ARRAY(UChar, 6); + fmt->lpThousandSep = NEW_ARRAY(wchar_t, 6); GetLocaleInfoW(lcid, LOCALE_SMONTHOUSANDSEP, fmt->lpThousandSep, 6); GetLocaleInfoW(lcid, LOCALE_RETURN_NUMBER|LOCALE_INEGCURR, (LPWSTR) &fmt->NegativeOrder, sizeof(UINT)); GetLocaleInfoW(lcid, LOCALE_RETURN_NUMBER|LOCALE_ICURRENCY, (LPWSTR) &fmt->PositiveOrder, sizeof(UINT)); - fmt->lpCurrencySymbol = NEW_ARRAY(UChar, 8); + fmt->lpCurrencySymbol = NEW_ARRAY(wchar_t, 8); GetLocaleInfoW(lcid, LOCALE_SCURRENCY, (LPWSTR) fmt->lpCurrencySymbol, 8); } @@ -290,8 +292,8 @@ UnicodeString &Win32NumberFormat::format(int32_t numDigits, UnicodeString &appen } } - UChar stackBuffer[STACK_BUFFER_SIZE]; - UChar *buffer = stackBuffer; + wchar_t stackBuffer[STACK_BUFFER_SIZE]; + wchar_t *buffer = stackBuffer; FormatInfo formatInfo; formatInfo = *fFormatInfo; @@ -314,7 +316,7 @@ UnicodeString &Win32NumberFormat::format(int32_t numDigits, UnicodeString &appen if (lastError == ERROR_INSUFFICIENT_BUFFER) { int newLength = GetCurrencyFormatW(fLCID, 0, nBuffer, &formatInfo.currency, NULL, 0); - buffer = NEW_ARRAY(UChar, newLength); + buffer = NEW_ARRAY(wchar_t, newLength); buffer[0] = 0x0000; GetCurrencyFormatW(fLCID, 0, nBuffer, &formatInfo.currency, buffer, newLength); } @@ -334,14 +336,14 @@ UnicodeString &Win32NumberFormat::format(int32_t numDigits, UnicodeString &appen if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { int newLength = GetNumberFormatW(fLCID, 0, nBuffer, &formatInfo.number, NULL, 0); - buffer = NEW_ARRAY(UChar, newLength); + buffer = NEW_ARRAY(wchar_t, newLength); buffer[0] = 0x0000; GetNumberFormatW(fLCID, 0, nBuffer, &formatInfo.number, buffer, newLength); } } } - appendTo.append(buffer, (int32_t) wcslen(buffer)); + appendTo.append((UChar *)buffer, (int32_t) wcslen(buffer)); if (buffer != stackBuffer) { DELETE_ARRAY(buffer); diff --git a/deps/icu-small/source/i18n/winnmfmt.h b/deps/icu-small/source/i18n/winnmfmt.h index a0b34dfc9f..3b0df915e1 100644 --- a/deps/icu-small/source/i18n/winnmfmt.h +++ b/deps/icu-small/source/i18n/winnmfmt.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** * Copyright (C) 2005-2015, International Business Machines diff --git a/deps/icu-small/source/i18n/wintzimpl.cpp b/deps/icu-small/source/i18n/wintzimpl.cpp index 921ecf78d2..4c042d5421 100644 --- a/deps/icu-small/source/i18n/wintzimpl.cpp +++ b/deps/icu-small/source/i18n/wintzimpl.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** * Copyright (C) 2009-2013, International Business Machines diff --git a/deps/icu-small/source/i18n/wintzimpl.h b/deps/icu-small/source/i18n/wintzimpl.h index 3ba4174a06..8149fc1417 100644 --- a/deps/icu-small/source/i18n/wintzimpl.h +++ b/deps/icu-small/source/i18n/wintzimpl.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** * Copyright (C) 2008-2011, International Business Machines diff --git a/deps/icu-small/source/i18n/zonemeta.cpp b/deps/icu-small/source/i18n/zonemeta.cpp index e2c75e5577..fdf333c371 100644 --- a/deps/icu-small/source/i18n/zonemeta.cpp +++ b/deps/icu-small/source/i18n/zonemeta.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2007-2014, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/zonemeta.h b/deps/icu-small/source/i18n/zonemeta.h index ac65e82acb..84be5553ea 100644 --- a/deps/icu-small/source/i18n/zonemeta.h +++ b/deps/icu-small/source/i18n/zonemeta.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2007-2013, International Business Machines Corporation and * diff --git a/deps/icu-small/source/i18n/zrule.cpp b/deps/icu-small/source/i18n/zrule.cpp index a7573e5fb5..ad64ab6e16 100644 --- a/deps/icu-small/source/i18n/zrule.cpp +++ b/deps/icu-small/source/i18n/zrule.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2009-2011, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/zrule.h b/deps/icu-small/source/i18n/zrule.h index cfc2b71542..b9827bf520 100644 --- a/deps/icu-small/source/i18n/zrule.h +++ b/deps/icu-small/source/i18n/zrule.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2009-2016, International Business Machines Corporation and diff --git a/deps/icu-small/source/i18n/ztrans.cpp b/deps/icu-small/source/i18n/ztrans.cpp index e33e8511bc..956b563a2a 100644 --- a/deps/icu-small/source/i18n/ztrans.cpp +++ b/deps/icu-small/source/i18n/ztrans.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2009-2010, International Business Machines Corporation and * diff --git a/deps/icu-small/source/i18n/ztrans.h b/deps/icu-small/source/i18n/ztrans.h index 6697dcd5eb..0101dc06e3 100644 --- a/deps/icu-small/source/i18n/ztrans.h +++ b/deps/icu-small/source/i18n/ztrans.h @@ -1,3 +1,5 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * Copyright (C) 2009-2016, International Business Machines Corporation and |